InteropBitmap集合到单个图像

时间:2014-07-22 13:57:55

标签: c# wpf interopbitmapimage

我正在使用InteropBitmap列表,以便在Image控件中显示一组图像帧,该控件是使用datatemplate自定义的。

我所期待的是在单个图像中导出一组图像,但我得到的是一个错误/部分图像,颜色错误。

以下是我用于在单个图片中转换InteropBitmap集的代码片段:

 var firstInterop = this.InteropBitmapList[0]; // Get info from first frame, all other one are the same format.

  int width = firstInterop .PixelWidth;
            int height = firstInterop.PixelHeight;
            int bpp = firstInterop Format.BitsPerPixel;

            int stride = width * (bpp / 8);
            int count = this.InteropBitmapList.Count;

            byte[] buffer = new byte[stride * height * count];

            for (int i = 0; i < count; i++)
            {
                var wb = this.InteropBitmapList[i];
                wb.CopyPixels(buffer, stride, width * height * i);
            }

最后,我使用缓冲区数组通过GDI +或其他wpf工具来实现我的jpeg图像。不幸的是,这两种方式都没有按照我的预期发挥作用。

我的代码中有什么问题吗?

@@修改 好吧,多亏了克莱门斯的答案,现在我能够获得正确的图像,除了它的颜色(所有颜色都被改变)。 只有当我尝试通过GDI +创建一个Image时,问题才是真的,相反,如果我使用WPF susch的东西,因为JpegBitmapEncoder一切正常。

以下代码段允许我获得正确的图像:

byte[] buffer = MyFunc.GetBuffer();
// ...
    var bitmap = System.Windows.Media.Imaging.BitmapSource.Create(width, height, 300, 300,
       System.Windows.Media.PixelFormats.Rgb24, null, buffer, stride);
            System.IO.FileStream stream = new System.IO.FileStream("example.jpg", System.IO.FileMode.Create);
            JpegBitmapEncoder encoder = new JpegBitmapEncoder();

            encoder.QualityLevel = 100;

            encoder.Frames.Add(BitmapFrame.Create(bitmap));
            encoder.Save(stream);

相反,以下代码返回一个颜色错误的图像(红色变为蓝色等等)

byte[] buffer = MyFunc.GetBuffer(); 
// ...
IntPtr unmanagedPointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(buffer.Length);
System.Runtime.InteropServices.Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length);

System.Drawing.Imaging.PixelFormat format = System.Drawing.Imaging.PixelFormat.Format24bppRgb (the equivalent of WPF format..)

System.Drawing.Image myImg = new System.Drawing.Bitmap(Width, Height, stride, format, unmanagedPointer);

myImg.Save("example.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

当我使用System.Drawing类时,我不知道为什么它不起作用。

1 个答案:

答案 0 :(得分:1)

错误在于计算i图像的缓冲区偏移量。而不是width * height * i,它必须计算为stride * height * i

wb.CopyPixels(buffer, stride, stride * height * i);

为了也支持不是8的整数倍的每像素位值,你应该像这样计算步幅:

int stride = (width * bpp + 7) / 8;