在a simple word game app中,我使用以下代码从PNG-image stripe加载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):
同时正确显示the yellow square tile backround。
所有(big_tile.png和big_english.png以及game_board.png)都是PNG图像 - 为什么差异呢?
为什么会发生这种情况以及如何解决这个问题?
我应该使用inDensity
还是其他任何BitmapFactory.Options?
或者是因为我的getResources().openRawResource()
电话 - 而是使用什么呢?
答案 0 :(得分: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
。 。 等等 希望这可以帮助你一些方法。
这里有一些我的代码(我使用的是imageview而不是位图抱歉):
int width,height;
//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;
}
答案 1 :(得分:0)
我将在这里分享我自己的解决方案。
问题是,我的字母图块的黄色背景是Drawable
,前景是Bitmap
(在PNG条纹的BitmapRegionDecoder
的帮助下阅读)
由于一些奇怪的原因,我仍然不明白 - 他们的尺寸在某些Android设备上有所不同。
(1)因此my easiest workaround已将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)我的more involved workaround已经将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
,然后用ImageMagick(命令为convert square.png -crop 40x40 square_%d.png
)分割PNG条纹。现在my app使用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);
}