从缓冲区数组创建jpeg图像

时间:2018-09-03 08:16:48

标签: c# jpeg

我正在尝试从RGBA缓冲区数组中保存jpeg图像。
我尝试了这段代码

byte[] buffer = new byte[m_FrameProps.ImgSize];
Marshal.Copy(m_BM.BackBuffer, buffer, 0, m_FrameProps.ImgSize); //m_BM is WriteableBitmap
using (MemoryStream imgStream = new MemoryStream(buffer))
{
    using (System.Drawing.Image image = System.Drawing.Image.FromStream(imgStream))
    {
        image.Save(m_WorkingDir + "1", ImageFormat.Jpeg); 
    }
} 

但是我遇到了运行时错误:“ System.Drawing.dll中发生了'System.ArgumentException'类型的未处理异常

其他信息:参数无效。”

我也尝试创建位图,然后使用JpegBitmapEncoder

Bitmap bitmap;
using (var ms = new MemoryStream(buffer))
{
    bitmap = new Bitmap(ms);
} 

但是我遇到了同样的错误。
我想是因为阿尔法。
我该怎么办?我是否需要循环这些值并在不使用alpha的情况下进行复制?

1 个答案:

答案 0 :(得分:1)

不可能仅从像素数据数组构造图像。至少还需要像素格式信息和图像尺寸。这意味着使用流直接从ARGB数组直接创建位图的任何尝试都会失败,Image.FromStream()Bitmap()方法都要求流包含某种头信息来构造图像。

也就是说,假设您似乎知道要保存的图像的尺寸和像素格式,则可以使用以下方法:

public void SaveAsJpeg(int width, int height, byte[] argbData, int sourceStride, string path)
{
    using (Bitmap img = new Bitmap(width, height, PixelFormat.Format32bppPArgb))
    {
        BitmapData data = img.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, img.PixelFormat);
        for (int y = 0; y < height; y++)
        {
            Marshal.Copy(argbData, sourceStride * y, data.Scan0 + data.Stride * y, width * 4);
        }
        img.UnlockBits(data);
        img.Save(path, ImageFormat.Jpeg);
    }
}