当前位置: 首页 > 面试题库 >

Yuv(NV21)图像转换为位图

段宏毅
2023-03-14
问题内容

我正在尝试从相机预览中捕获图像并在其上进行一些绘制。问题是,我只有大约3-4
fps的绘图,并且一半的帧处理时间是从摄像机预览接收和解码NV21图像并将其转换为 位图
。我有一个执行此任务的代码,是在另一个堆栈问题上找到的。它似乎并不快,但我不知道如何优化它。在Samsung Note
3(图像尺寸1920x1080)上大约需要100-150毫秒。我怎样才能使其更快地工作?

代码:

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毫秒。在三星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);


 类似资料:
  • 有没有人知道如何正确旋转NV21图像字节[]保留其颜色信息正确。

  • 问题内容: 我想将位图打印到移动蓝牙打印机(Bixolon SPP-R200)-SDK不提供直接方法来打印内存图像。所以我想到了这样转换一个位图: 到单色位图。我正在使用Canvas在给定的位图上方绘制黑色文本,效果很好。但是,当我将上述位图转换为ByteArray时,打印机似乎无法处理这些字节。我怀疑我需要一个每个像素一位的数组(一个像素将是白色= 1或黑色= 0)。 似乎没有方便的开箱即用的方

  • 有人知道怎么做吗?显然有一个Windows命令用于这种事情... 谢谢

  • 我想把openCV Mat文件转换成GDI+位图图像。我找不到任何关于如何做到这一点的信息?

  • 我试图将YUV_420_888图像转换为位图,来自camera2预览。但是输出图像的颜色不正确。 请让我知道如果有人能发现转换的问题:

  • 问题内容: 用户选择后,我想在 base64中 获取图像(提交表单之前) 就像是 : 我了解了文件API和其他内容,我想要一个简单的跨浏览器解决方案(显然不包括IE6 / IE7) 任何帮助表示感谢。 问题答案: function readFile() { ( PS: 一个base64编码的图像(字符串)为原始图像数据大小的4/3)