我使用的是here给出的Google示例。我以以下方式更改了OnImageAvailableListener
:
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
= reader -> {
Image image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
image.close();
String pictureId = "asdasd";
Bitmap bitmap = createMutableBitmap(bytes);
StorageClass.getInstance().put(pictureId, bitmap);
Intent intent = new Intent(Camera2MainActivity.this, TPCameraPreviewSnapActivity.class);
intent.setType("image/*");
intent.putExtra("pictureId", pictureId);
startActivityForResult(intent, 1123);
};
我要开始的新Intent正在使用PhotoView来显示位图。 StorageClass
提供了一种静态方法,可以在意图之间共享大数据(例如这些位图)。
此外,方法createMutableBitmap
是:
public static Bitmap createMutableBitmap(byte[] data){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
Log.d(TAG, "BT1: " + data.length);
Bitmap mutableBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
Log.d(TAG, "BT2: " + mutableBitmap.getByteCount());
return mutableBitmap;
}
在Huawei P30 Pro上执行此代码后,我得到如下输出:
W/ImageReader_JNI: Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffers
E/ion: ioctl c0044901 failed with code -1: Invalid argument
D/Camera2BasicFragment: BT1: 1019119
W/ServiceManagement: getService: unable to call into hwbinder service for vendor.huawei.hardware.jpegdec@1.0::IJpegDecode/default.
D/HwAppInnerBoostImpl: asyncReportData rs.tp.camera2verifiedbypi,1,1,10,0 interval=2774
D/Camera2BasicFragment: BT2: 159694848
无论我如何更改图像的JPEG质量,都会弹出数字159694848
。 159694848字节为〜160MB。
随后,当尝试将Bitmap
设置为
`PhotoView`, I get an exception:
E/BitmapDrawable: Canvas: trying to use a recycled bitmap
W/System.err: java.lang.RuntimeException: Canvas: trying to draw too large(159694848bytes) bitmap.
这个示例,经过我的更改,可以在我尝试过的所有其他手机上正常运行,但它们运行的是Android 8或更低版本。
那么,此问题的起因是什么,我该如何缓解呢?
答案 0 :(得分:2)
您要捕获的JPEG的分辨率是多少?假设ARGB内部存储,一个160 MB的位图是每个像素4个字节,因此160/4 = 4000万像素。
从https://www.gsmarena.com/huawei_p30_pro-9635.php起,Huawei P30 Pro确实确实具有40 MP主摄像头(在四Bayer模式下使用时),因此这一切都是一致的。
也就是说,Android View组件并不是真的希望通过40百万像素的Bitmap。由于屏幕分辨率仅为1080 x 2340像素= 2.5 MP,因此没有理由在该屏幕上绘制40 MP。
如果只想在屏幕上显示JPEG,则在解码图像时应使用BitmapFactory选项将图像重新缩放到更接近屏幕分辨率的水平。这样也可以节省大量内存。
答案 1 :(得分:0)
位图始终是无懈可击的,它与JPEG压缩无关。 ARGB格式的位图始终是其大小的像素数x 4(alpha,红色,绿色,蓝色每个1字节)。因此,如果您有1000x1000像素的位图,则在加载到内存中时,它的大小始终为4MB。 JPEG压缩仅适用于存储到磁盘的文件,在内存中的图像始终未压缩。
您可以通过在每个通道中使用4位来使用较小的位图,而这会牺牲颜色保真度,或者您可以调整它们的大小。