CameraX设置RGBA_8888格式时触发maxImages(4)超限错误如何解决?
问题根因
- 多余关闭了从ImageProxy获取的底层
Image对象:ImageProxy.close()方法会自动释放其持有的内部Image资源,提前手动调用img.close()会破坏ImageProxy的资源回收逻辑,导致部分帧资源没有被正确释放,累计到ImageReader的最大缓存数4之后就抛出异常。 - 拷贝像素前没有重置ByteBuffer的游标位置:Plane获取的Buffer默认position可能不在起始位置,直接拷贝会失败,隐式触发的异常也可能导致后续close逻辑没有执行完全。
修复代码
直接修改analyze方法的逻辑即可:
@Override @ExperimentalGetImage public void analyze(@NonNull ImageProxy imageProxy) { try { Image img = imageProxy.getImage(); if (img == null) return; Image.Plane[] planes = img.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); // 重置buffer游标到起始位置 buffer.rewind(); int pixelStride = planes[0].getPixelStride(); int rowStride = planes[0].getRowStride(); int rowPadding = rowStride - pixelStride * img.getWidth(); int width = img.getWidth(); int height = img.getHeight(); Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); // 裁剪掉多余的padding区域,得到和原始图像尺寸一致的Bitmap bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height); // 此处可添加你的TFLite推理逻辑 } finally { // 只需要关闭ImageProxy,不需要单独关闭内部Image imageProxy.close(); } }
额外优化建议
- 将close逻辑放到finally块里,避免中间处理逻辑抛出异常时,ImageProxy没有被关闭导致资源泄漏
- 裁剪掉Bitmap的padding区域,否则传入TFLite模型会因为尺寸不匹配出现推理错误
- Bitmap使用完之后及时调用
bitmap.recycle()回收内存,避免出现OOM问题
内容的提问来源于stack exchange,提问作者MickaelD
相关产品推荐
相关产品推荐

