Android 使用BitMapRegionCoder加载的图像在模拟器上正常,但在设备上太大

Android 使用BitMapRegionCoder加载的图像在模拟器上正常,但在设备上太大,android,bitmap,bitmapfactory,android-bitmap,bitmapregiondecoder,Android,Bitmap,Bitmapfactory,Android Bitmap,Bitmapregiondecoder,在中,我使用以下代码从a加载26个字母的平铺图像: private static final CharacterIterator ABC = new StringCharacterIterator("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); private static HashMap<Character, Bitmap> sImages = new HashMap<Character, Bitmap>(); BitmapRegio

在中,我使用以下代码从a加载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);
}       

private静态最终字符计数器ABC=
新StringCharacteristator(“ABCDEFGHIJKLMNOPQRSTUVXYZ”);
私有静态哈希映射sImages=
新的HashMap();
BitMapRegionCoder解码器=空;
InputStream is=sContext.getResources()
.openRawResource(R.drawable.big_english);
试试{
解码器=BitMapRegionCoder.newInstance(is,false);
}捕获(IOEX异常){
}       
int h=解码器.getHeight();
rectr r=新的Rect(0,0,h,h);
for(char c=ABC.first();
c!=字符转换器。完成;
c=ABC.next(),r.offset(h,0)){
位图bmp=解码器.decoderence(r,null);
sImages.put(c,bmp);
}       
这在Android emulator中运行良好:

但在真正的Moto G设备上,字母太大(可能是1.5倍?当我打印
sContext.getResources().getDisplayMetrics().density
I出于某种原因获得2.0):

同时正确显示

所有(和)都是PNG图像-那么为什么会有区别呢

为什么会发生这种情况以及如何解决

我是否应该使用
inDensity
或任何其他


或者是因为我的
getResources().openRawResource()
调用-但是使用什么来代替呢?

我对图像也有同样的问题,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宽度、高度

   //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;
                    }

我将在这里分享我自己的解决方案

问题是,我的字母平铺的黄色背景是一个
可绘制的
,前景是一个
位图
(在PNG条纹的
BitMapRegionCoder
帮助下读取)

出于某种奇怪的原因,我仍然不明白——在一些Android设备上,它们的尺寸不同

(1)因此,每次绘制字母平铺时,都要将
位图(带字母的前景)缩放到
可绘制的
(黄色方形背景)的范围内:

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)我只缩放了一次
位图
——就在我用
BitMapRegionCoder
阅读它之后,在我将它存储到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) {
}

不同的屏幕分辨率?是的,但黄色方形瓷砖背面显示正确。这两个(和)都是PNG图像——那么为什么会有区别呢?将R.drawable.big_english放在drawable nodpi folder中,但我不想在更小的Android设备上浪费内存。图像大小为6240 x 240像素。我想在低端设备上使用更小的
res/drawable ldpi/big_english.png
。您是否将所有图像都放在仅可绘制的文件夹中,或者放在所有mdpi、hdpi、xhdpi、xxhdpi文件夹中?
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);
}