2

シンプルな単語ゲーム アプリで、次のコードを使用して、 PNG イメージ ストライプから 26 文字のタイル イメージを読み込みます。

画像ストライプ

private static final CharacterIterator ABC = 
    new StringCharacterIterator("ABCDEFGHIJKLMNOPQRSTUVWXYZ");

private static HashMap<Character, Bitmap> sImages =
    new HashMap<Character, Bitmap>();

BitmapRegionDecoder decoder = null; 

InputStream is = sContext.getResources()
    .openRawResource(R.drawable.big_english);

try {   
        decoder = BitmapRegionDecoder.newInstance(is, false); 
} catch (IOException ex) {
}       

int h = decoder.getHeight();
Rect r = new Rect(0, 0, h, h);

for (char c = ABC.first(); 
        c != CharacterIterator.DONE; 
        c = ABC.next(), r.offset(h, 0)) {

           Bitmap bmp = decoder.decodeRegion(r, null);
           sImages.put(c, bmp);
}       

これは Android エミュレーターでうまく機能します。

エミュレータ

しかし、実際の Moto G デバイスでは、文字が大きすぎます (おそらく 1.5 倍?印刷するsContext.getResources().getDisplayMetrics().densityと、何らかの理由で 2.0 になります):

Moto G デバイス

同時に、黄色の四角いタイルの背景が正しく表示されます。

すべて ( big_tile.pngbig_english.pnggame_board.png ) は PNG 画像です。なぜ違いがあるのでしょうか?

なぜそれが起こるのか、これを修正する方法を教えてください。

inDensityまたは他のBitmapFactory.Optionsを使用する必要がありますか?

それとも私のgetResources().openRawResource()電話のせいですか - しかし、代わりに何を使うべきですか?

4

2 に答える 2

2

画像にも同じ問題があります.Androidデバイスには多くの画面解像度が付属しています。描画可能なフォルダーに大量の画像を入れるか、各画面解像度に画像の幅と高さの一連のルールを与える必要があります

for example:
if screen_resolution = 4 inch
int img_height = 200
int img_width = 200
else if screen_resolution = 5 inch
int img_height = 300
int img_width = 300

. . などなど、これが何らかの方法で役立つことを願っています。

ここに私のコードの一部があります(申し訳ありませんが、ビットマップではなくイメージビューを使用しています):

int の幅、高さ。

   //calculate device screen
    DisplayMetrics metrics=new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    float height=metrics.heightPixels/metrics.xdpi;
    float width=metrics.widthPixels/metrics.ydpi;
    float inchscreen = FloatMath.sqrt(height*height+width*width);


if (inchscreen > 4.1000)
    {
        //set image height for device above 4.1 inch screen
        height = 400;
        width = 400     
    }
else {
        //set image height for device below 4.1 inch screen
        height = 280;
        width = 280
    }

if (imgfile != null) {
                    int imageResource = getResources().getIdentifier(uri, null,
                            getPackageName());
                    Drawable image = getResources().getDrawable(imageResource);
                    imageview.setImageDrawable(image);
                    imageview.getLayoutParams().height = h_display;
                    imageview.getLayoutParams().width = h_display;
                    }
于 2014-11-20T05:47:40.853 に答える
0

ここで私自身の解決策を共有します。

問題は、私の文字タイルの黄色の背景が でDrawable、前景が であるということです( PNG ストライプからBitmapの助けを借りて読んでください)。BitmapRegionDecoder

いくつかの奇妙な理由で、私はまだ理解していません.一部のAndroidデバイスでは寸法が異なります.

(1)したがって、私の最も簡単な回避策は、文字タイルが描画されるたびに(Bitmap文字のある前景)を(黄色の正方形の背景)の境界に合わせることでした:Drawable

private Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);

public void draw(Canvas canvas) {
    canvas.save();
    canvas.translate(left, top);
    mImage.draw(canvas);
    Bitmap bmp = getImages().get(mLetter);
    canvas.drawBitmap(bmp, null, mImage.getBounds(), mPaint);
    canvas.restore();
}

(2)のより複雑な回避策は、一度だけスケーリングすることでしBitmapた-それを読んだ直後BitmapRegionDecoder、HashMapに保存する前に:

private static final CharacterIterator ABC = 
    new StringCharacterIterator("ABCDEFGHIJKLMNOPQRSTUVWXYZ");

private static HashMap<Character, Bitmap> sBitmaps = 
    new HashMap<Character, Bitmap>();

try {
        InputStream is = context.getResources().openRawResource(EN);
        BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false);
        int h = decoder.getHeight();
        Rect r = new Rect(0, 0, h, h);
        for (char c = ABC.first();
             c != CharacterIterator.DONE;
             c = ABC.next(), r.offset(h, 0)) {
                Bitmap unscaled = decoder.decodeRegion(r, null);
                Bitmap scaled = Bitmap.createScaledBitmap(unscaled, (int) (SCALE * width), (int) (SCALE * height), true);
                sBitmaps.put(c, scaled);
        }
} catch (IOException ex) {
}

(3)どちらの方法も機能しましたが、古い Google Nexus One デバイスでは、何らかの理由で前景が表示されませんでした。この時点で、私は神経を失い、使用をやめBitmapRegionDecoder、PNG ストライプを ImageMagick (コマンドはconvert square.png -crop 40x40 square_%d.png) で分割しました。これで、私のアプリDrawableは文字タイルの前景と背景の両方を使用し、SDK レベル 8 以降のすべてのデバイスで動作します。

private static final String SQUARE = "square_";

private static final char[] LETTERS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

private static HashMap<Character, Drawable> sLetters = 
    new HashMap<Character, Drawable>();

for (int i = 0; i < LETTERS.length; i++) {
    char c = LETTERS[i];
    int id = context.getResources().getIdentifier(PREFIX + i, "drawable", context.getPackageName());
    Drawable d = context.getResources().getDrawable(id);
    d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
    sLetters.put(c, d);
} 

エミュレータ

于 2014-11-20T12:44:33.687 に答える