无法将YUV420帧转换为位图

时间:2017-06-30 16:12:10

标签: c# image image-processing bitmap

我正在尝试将YUV420帧转换为Bitmap或Image。我正在使用AVBlocks库从C#中的MP4视频中读取这些帧。因此,在使用AVBlocks类创建输入和输出套接字之后,然后我使用YUV420颜色格式和UncompressedVideo流类型从视频中拉出每个帧。我基本上是通过调用Transcoder.Pull(int outputIndex, MediaSample outputData)来执行此操作,然后是MediaBuffer,其中outputData的一部分具有字节数组中的数据。所以我试图将这些字节转换为Bitmap或Image,这样我最终可以在Winforms应用程序中将每个帧显示到PictureBox中。

我尝试过的事情:

我尝试过使用MemoryStream,如下所示,但是我得到一个未处理的ArgumentException,说该参数无效。我也尝试使用ImageConverter()转换为Image,但我得到了相同的异常。然后,我将字节数组从YUV转换为RGB格式,并将更新后的数组作为参数提供给MemoryStream,但再次没有运气。我还尝试将输出插槽的颜色格式从YUV420更改为BGR格式,但是它产生了与上面相同的问题。尝试使用MemoryStream转换为位图的代码:

while (transcoder.Pull(out inputIndex, yuvFrame))
{
    buffer = (MediaBuffer) yuvFrame.Buffer.Clone();
    Bitmap b;

    byte[] temp = new byte[buffer.DataSize];
    Array.Copy(buffer.Start, buffer.DataOffset, temp, 0, buffer.DataSize);
    var ms = new MemoryStream(temp);
    b = new Bitmap(ms);
}

上述异常将在代码的最后一行引发。我不确定它是颜色格式还是流类型,或其他导致问题的因素。如果有人想要查看更多代码(设置输入和输出套接字等),请告诉我。作为参考,我从AVBlocks跟随的示例的链接是this,MediaBuffer类的链接是this

1 个答案:

答案 0 :(得分:1)

undefined构造函数需要中的字节为实际文件,如png,jpeg,bmp或gif。如果我正确地读到这个,你就没有那个;你只有纯RGB三元组数据。这还不够,因为它缺乏有关图像宽度,高度,颜色深度等的所有信息。

您需要从RGB数据中实际构建图像对象。这不是真正微不足道的;这意味着您需要使用正确的尺寸和颜色格式制作新的图像对象,然后访问其后备字节数组,并将数据写入其中。可以找到用于从字节数组中创建图像的实际代码in this answer

请注意,您必须考虑所得到的数据中的实际步幅;图像每行的字节数。每行保存图像,这些行通常填充为4个字节的倍数。如果你不考虑这一点,这显然会弄得很多。

如果您的数据非常紧凑,那么Bitmap(MemoryStream ms)提供给我链接到的stride函数只会是您的图像宽度乘以每像素的字节数(对于24bpp应为3) RGB),但如果没有,你必须将它填充到下一个4的倍数。