java - Yuv (NV21) 图像转换为位图

标签 java android bitmap camera yuv

<分区>

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

代码:

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 是唯一可用的格式。我不确定是否可以在这些格式更改中找到解决方案。

提前谢谢你。

最佳答案

感谢 Alex Cohn 帮助我加快转换速度。我实现了您建议的方法(RenderScript 内在函数)。此代码使用 RenderScript 内部函数制作,将 YUV 图像转换为位图的速度大约快 5 倍。以前的代码用了 100-150 毫秒。在 Samsung Note 3 上,这需要 15-30 左右。 如果有人需要做同样的任务,这里是代码:

这些将被使用:

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

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

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

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

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);

关于java - Yuv (NV21) 图像转换为位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35826709/

相关文章:

java - 在 Android 中使用枚举来自定义 View 属性

安卓: Canvas drawBitmap?

c - 在 WIN32 中的 "BUTTON"类窗口上显示位图

java - Spring 无法执行多部分项目的清理

java - 将窗口放置在系统托盘上方

android - genymotion 虚拟设备在 ubuntu 中无法正常工作

android - 将 uuid.h 包含到 Android NDK 项目中

java - 调用 Bitmap.compress 不返回 - 并且没有异常

java - 在Brother QL标签打印机上使用自定义java.awt.print.Paper

Java BasicResponseHandler 异常