在 Android 中拍摄一张照片,然后使用 ImageAnalyzer 对其进行处理

Capture a picture in Android, and work with it using the ImageAnalyzer

我正在尝试实施一种解决方案,该解决方案能够从 phone 的相机中捕捉图片,然后操作图片(对其进行处理)并快速重复此过程 N 次。

我已经使用 imageCapture.takePicture 方法实现了这一点,但是当尝试对 N 张图片实施相同的过程时,onCaptureSuccess 方法每 ~500 毫秒被调用一次(在坚固的三星设备上) .捕获和保存图片的过程对我来说持续时间太长。我需要它比 500 毫秒更快。

我正在寻找使用 imageAnalyzer class 来实现它,并使用了类似于这样的代码:

private class CameraAnalyzer implements ImageAnalysis.Analyzer {
        
        @Override
        public void analyze(@NonNull ImageProxy image) {

            ByteBuffer bb = image.getPlanes()[0].getBuffer();
            byte[] buf = new byte[bb.remaining()];
            bb.get(buf);
            
            //raw - data container
            raw = buf;
            //runnable - operate the picture
            runnable.run();
            image.close();
        }
    }

但是我收到 buf 的 NULL 并且图片总是空的。 bb.rewind() 也没有帮助。

在被告知图片是 RAW 格式,因此需要将其转换为位图后,我使用以下代码完成了:

            ImageProxy.PlaneProxy[] planes = image.getPlanes();
            ByteBuffer buffer = planes[0].getBuffer();
            int pixelStride = planes[0].getPixelStride();
            int rowStride = planes[0].getRowStride();
            int rowPadding = rowStride - pixelStride * image.getWidth();
            Bitmap bitmap = Bitmap.createBitmap(image.getWidth()+rowPadding/pixelStride,
                    image.getHeight(), Bitmap.Config.ARGB_8888);

            bitmap.copyPixelsFromBuffer(buffer);

但是在执行 copyPixelsFromBuffer 时我遇到了这个问题:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.strujomeri, PID: 24466
    java.lang.RuntimeException: Buffer not large enough for pixels

如何在imageAnalyzer中得到我想要的图片,并且有内容 在 byte[] 格式中用它做什么我想要什么?

默认的 image 格式是 YUV_420_888 并且由于您的缓冲区只有一个平面(亮度 (Y) 平面),缓冲区的像素只有一个 byte尺寸。

copyPixelsFromBuffer 假定 buffer 与位图的颜色 space 相同,因此当您将位图格式设置为 ARGB_8888 时,它正在寻找每个像素 4 个字节,而不是你给它的每个像素 1 个字节。

我没用过这个,但是这个 page 有一个 ImageProxy.toBitmap 示例,可以通过 Jpeg 将 YUV 转换为位图(如果您只想要 Jpeg,可以跳过最后一步)

我还看到另一个 method 不是通过 Jpeg 而是直接将 YUV 的颜色space 更改为位图。

您当然可以更改为唯一的其他颜色 space ImageAnalysis 支持 ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888 这需要更长的时间才能捕获,因为它需要转换并且仍然不是位图的正确格式