从相机预览中解码Android位图

3

我正在尝试从相机预览中获取位图图像,然后进行一些处理和绘制一些覆盖层,完成人脸检测。

经过调查,我发现onPreviewFrame接收的字节数组不能直接解码为位图,需要使用YuvImage将其转换为正确的像素格式,这正是我所做的事情:

@Override
public void onPreviewFrame(byte[] data, Camera camera)
{
    YuvImage temp = new YuvImage(data, camera.getParameters().getPreviewFormat(), camera.getParameters().getPictureSize().width, camera.getParameters().getPictureSize().height, null);

    ByteArrayOutputStream os = new ByteArrayOutputStream();
    temp.compressToJpeg(new Rect(0, 0, temp.getWidth(), temp.getHeight()), 80, os);

    Bitmap preview = BitmapFactory.decodeByteArray(os.toByteArray(), 0, os.toByteArray().length);

    /* DO SOMETHING WITH THE preview */

}

问题在于,“预览”对象不是null,但显然不是一个有效的位图。在调试器中,我可以看到mWidth和mHeight都设置为-1,这似乎是错误的。我做错了什么?

如果你正在绘制叠加层并进行像人脸检测这样的重型操作,那么你需要使用NDK来提高速度。看一下GLSurfaceView以及如何与回调一起使用。你不会想要一个jpeg格式的图片 - 最好在本地字节数组上进行操作。 - Andrew G
@AndrewG,当使用GLSurfaceView时,如何将图像帧作为“位图”获取? - Sam
3个回答

1
在API 8或更高版本上,您可以使用以下代码将图像快速压缩为JPEG格式。
public void onPreviewFrame(byte[] data, Camera arg1) {
    FileOutputStream outStream = null;
    try {
        YuvImage yuvimage = new YuvImage(data,ImageFormat.NV21,arg1.getParameters().getPreviewSize().width,arg1.getParameters().getPreviewSize().height,null);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        yuvimage.compressToJpeg(new Rect(0,0,arg1.getParameters().getPreviewSize().width,arg1.getParameters().getPreviewSize().height), 80, baos);

        outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));  
        outStream.write(baos.toByteArray());
        outStream.close();

        Log.d(TAG, "onPreviewFrame - wrote bytes: " + data.length);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
    }
    Preview.this.invalidate();
}

来自 https://code.google.com/p/android/issues/detail?id=823#c37


0

你正在使用getPictureSize而不是getPreviewSize :)


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接