我在磁盘上有1280x1280 JPG,我使用下面的代码来解码图像的一个区域(裁剪两侧)以显示在ImageView中。在剪切图像的顶部和底部时存在类似的问题。为什么BitmapRegionDecoder分配这么多内存?
private Bitmap decodeBitmapRegion(InputStream in, Rect region, Bitmap recycleBitmap) {
LOGD(TAG, "decodeBitmapRegion region=" + region + ", recycleBitmap=" + recycleBitmap);
Bitmap bitmap = null;
BitmapRegionDecoder decoder = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
options.inBitmap = recycleBitmap;
try {
decoder = BitmapRegionDecoder.newInstance(in, false);
bitmap = decoder.decodeRegion(region, options);
} catch (IllegalArgumentException e){
LOGE(TAG, "Failed to recycle bitmap for rect=" + region, e);
} catch (IOException e) {
LOGE(TAG, "Failed to decode into rect=" + region, e);
} finally {
if (decoder != null) decoder.recycle();
}
return bitmap;
}
在一个宏基Iconia A100(4.0.3)的代码完美地工作,并且如果提供,在堆上分配无存储器的区域进行解码到再循环位图。 logcat没有GC或增长堆消息。它也可以在运行4.2.0的Nexus 7上正常运行。
在Motorola Xoom(4.0.4)上,代码生成以下logcat。第一个dalvikvm-heap增长(4738256字节)大概是针对BitmapRegionDecoder的数据,第二个(3603216字节)匹配存储图像所需的内存量(800x1126x4)。还有一个skia错误。
8522 LocationImageLoader D decodeBitmapRegion region=Rect(240, 77 - 1040, 1203), [email protected]
8522 dalvikvm D GC_FOR_ALLOC freed 8213K, 28% free 22782K/31623K, paused 34ms
8522 dalvikvm-heap I Grow heap (frag case) to 26.808MB for 4738256-byte allocation
8522 dalvikvm D GC_CONCURRENT freed 6K, 14% free 27403K/31623K, paused 3ms+7ms
8522 skia D WARNING: One-shot allocator has already allocated (alloc count = 1)
8522 dalvikvm D GC_FOR_ALLOC freed 0K, 14% free 27403K/31623K, paused 33ms
8522 dalvikvm-heap I Grow heap (frag case) to 30.238MB for 3603216-byte allocation
8522 dalvikvm D GC_FOR_ALLOC freed 0K, 3% free 30922K/31623K, paused 41ms
Setting options.inPreferredConfig = Bitmap.Config.RGB_565;似乎否定了Xoom上的第二次分配,就好像位图被正确回收,但仍有为解码器分配的内存。
使用完整图像(1280x1280)和BitmapFactory进行回收的工作方式虽然使用的存储整个图像的内存要比区域要求的要多得多。
我不明白为什么Xoom不能正常工作,但宏碁很好,当他们都运行Android 4.0.x.
它看起来Xoom不会在GPU上执行解码/裁剪/编码 – auval
@uval hardwareAccelerated设置为true,但不幸的是它没有什么区别,尽管您关于未在GPU上执行的操作的理论很有意义 –