Yuv (NV21) 图像转换为位图 [英] Yuv (NV21) image converting to bitmap

查看:66
本文介绍了Yuv (NV21) 图像转换为位图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从相机预览中捕获图像并在其上绘图.问题是,我只有大约 3-4 fps 的绘图速度,一半的帧处理时间是从相机预览接收和解码 NV21 图像并转换为位图.我有一个代码来完成这个任务,我在另一个堆栈问题中找到了它.好像不快,但是不知道怎么优化.在三星 Note 3,图像尺寸 1920x1080 上大约需要 100-150 毫秒.我怎样才能让它运行得更快?

I am trying to capture images from camera preview and do some drawing on it. The problem is, I have only about 3-4 fps of drawing, and half of the frame processing time is receiving and decoding NV21 image from camera preview and converting to bitmap. I have a code to do this task, which I found on another stack question. It does not seem to be fast, but I do not know how to optimize it. It takes about 100-150 ms on Samsung Note 3, image size 1920x1080. How can I make it work faster?

代码:

public Bitmap curFrameImage(byte[] data, Camera camera)
{
    Camera.Parameters parameters = camera.getParameters();
    int imageFormat = parameters.getPreviewFormat();

    if (imageFormat == ImageFormat.NV21)
    {
        YuvImage img = new YuvImage(data, ImageFormat.NV21, prevSizeW, prevSizeH, null);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        img.compressToJpeg(new android.graphics.Rect(0, 0, img.getWidth(), img.getHeight()), 50, out);
        byte[] imageBytes = out.toByteArray();
        return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
    }
    else
    {
        Log.i(TAG, "Preview image not NV21");
        return null;
    }
}

图像的最终格式必须是位图,因此我可以对其进行处理.我已经尝试将 Camera.Parameters.setPreviewFormat 设置为 RGB_565,但无法将相机参数分配给相机,我也读过 NV21 是唯一可用的格式.我不确定,是否可以在这些格式更改中找到解决方案.

The final format of image has to be bitmap, so I could then do processing on it. I've tried to set Camera.Parameters.setPreviewFormat to RGB_565, but could not assign camera params to camera, I've read also that NV21 is the only available format. I am not sure about that, whether it is possible to find solution in these format changes.

提前致谢.

推荐答案

感谢 Alex Cohn,他帮助我更快地完成此转换.我实现了您建议的方法(RenderScript 内在函数).这段代码由 RenderScript 内在函数编写,将 YUV 图像转换为位图的速度大约快 5 倍.以前的代码需要 100-150 毫秒.在三星 Note 3 上,这需要 15-30 左右.如果有人需要做同样的任务,这里是代码:

Thank you, Alex Cohn, for helping me to do make this conversion faster. I implemented your suggested methods (RenderScript intrinsics). This code, made with RenderScript intrinsics, converts YUV image to bitmap about ~5 times faster. Previous code took 100-150 ms. on Samsung Note 3, this takes 15-30 or so. If someone needs to do the same task, here is the code:

将使用这些:

private RenderScript rs;
private ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;
private Type.Builder yuvType, rgbaType;
private Allocation in, out;

在创建函数中我初始化..:

In on create function I initialize..:

rs = RenderScript.create(this);
yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));

整个 onPreviewFrame 看起来像这样(在这里我接收并转换图像):

And the whole onPreviewFrame looks like this (here I receive and convert the image):

if (yuvType == null)
{
    yuvType = new Type.Builder(rs, Element.U8(rs)).setX(dataLength);
    in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);

    rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(prevSizeW).setY(prevSizeH);
    out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
}

in.copyFrom(data);

yuvToRgbIntrinsic.setInput(in);
yuvToRgbIntrinsic.forEach(out);

Bitmap bmpout = Bitmap.createBitmap(prevSizeW, prevSizeH, Bitmap.Config.ARGB_8888);
out.copyTo(bmpout);

这篇关于Yuv (NV21) 图像转换为位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆