在xml中设置ImageView源时,Android会自动使用inJustDecodeBounds吗?
我知道,如果我以编程方式加载图像并将其设置为ImageView中的源,最好的做法是首先使用在xml中设置ImageView源时,Android会自动使用inJustDecodeBounds吗?,android,bitmap,android-bitmap,Android,Bitmap,Android Bitmap,我知道,如果我以编程方式加载图像并将其设置为ImageView中的源,最好的做法是首先使用inJustDecodeBounds计算图像的大小,计算出需要的缩放比例,然后使用该缩放比例进行解码: BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.drawable.m
inJustDecodeBounds
计算图像的大小,计算出需要的缩放比例,然后使用该缩放比例进行解码:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.drawable.my_drawable, options);
float srcHeight = options.outHeight;
float srcWidth = options.outWidth;
int inSampleSize = ...; // compute
options = new BitmapFactory.Options();
options.inSampleSize = inSampleSize;
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_drawable, options);
myImageview.setImageBitmap(myBitmap);
现在,如果我想在xml中设置它,并且我只在/drawables
中提供一个基本的drawable(在/drawables hdpi
中没有其他资产,等等)
我知道Android会对生成的位图进行某种缩放,以确保其适合,但它会像我自己解码位图一样高效地进行缩放吗?还是将整个位图加载到内存中,然后进行缩放
换句话说,当Android由自己的设备重新采样图像时,当我只提供一个基本的
/drawable
时,它是否能有效地这样做?如果你确定你想要的大小,你自己缩放位图将节省内存,因为Android不会这样做,至少不是你期望的方式(请参见底部的编辑和注释)
我认为您还需要做一些其他考虑。当您自己解码位图时,您的目标是一个大小,可能是ImageView
的大小(因此在计算了ImageView
的大小之后)。膨胀xml时,该大小未知。如果解码位图后图像视图的大小发生变化,会发生什么情况?您会重新缩放它吗?在这种情况下,解码更大的位图,然后只缩放图形不是更有效吗
要想知道android是否像你一样缩放位图,一个方法很简单,试着在xml中设置一个可笑的大图像作为src,看看会发生什么(剧透警报,它会爆炸)
public static Drawable createFromResourceStream(Resources res, TypedValue value,
InputStream is, String srcName, BitmapFactory.Options opts) {
if (is == null) {
return null;
}
/* ugh. The decodeStream contract is that we have already allocated
the pad rect, but if the bitmap does not had a ninepatch chunk,
then the pad will be ignored. If we could change this to lazily
alloc/assign the rect, we could avoid the GC churn of making new
Rects only to drop them on the floor.
*/
Rect pad = new Rect();
// Special stuff for compatibility mode: if the target density is not
// the same as the display density, but the resource -is- the same as
// the display density, then don't scale it down to the target density.
// This allows us to load the system's density-correct resources into
// an application in compatibility mode, without scaling those down
// to the compatibility density only to have them scaled back up when
// drawn to the screen.
if (opts == null) opts = new BitmapFactory.Options();
opts.inScreenDensity = Drawable.resolveDensity(res, 0);
Bitmap bm = BitmapFactory.decodeResourceStream(res, value, is, pad, opts);
if (bm != null) {
byte[] np = bm.getNinePatchChunk();
if (np == null || !NinePatch.isNinePatchChunk(np)) {
np = null;
pad = null;
}
final Rect opticalInsets = new Rect();
bm.getOpticalInsets(opticalInsets);
return drawableFromBitmap(res, bm, np, pad, opticalInsets, srcName);
}
return null;
}
另外,在draw(Canvas Canvas)
method ofBitmapDrawable
中,使用以下行完成绘制:
canvas.drawBitmap(bitmap, null, mDstRect, paint);
看起来像是使用了位图
,是目标Rect
进行缩放
编辑
今天我还意外地发现了另一件有趣的事情,我将一幅图像放在可绘制文件夹(未指定密度)中,并使用BitmapFactory.decodeSourceStream(res、value、is、pad、opts)检索了一幅位图
,与上面的一样。我得到的位图比drawable文件夹中的图像大得多,我认为如果密度未指定,它将采用mdpi,甚至会对位图进行上采样以获得更高的目标密度。使用巨大的png进行测试的好主意。谢谢,准备看到它爆炸:)今天我还发现了一些新的东西,我把它放在回答栏里,尝试了一个巨大的图像,然后:砰:。此外,在这个类似的问题中,您所说的未指定密度的图像大小也得到了暗示:。如果你改为使用drawable nodpi
会发生什么?嗯,好问题,根据你告诉android不要缩放图像的方式!我想我不会再使用资产文件夹了
canvas.drawBitmap(bitmap, null, mDstRect, paint);