我正在使用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类时,我不知道为什么它不起作用。
答案 0 :(得分:1)
错误在于计算i
图像的缓冲区偏移量。而不是width * height * i
,它必须计算为stride * height * i
:
wb.CopyPixels(buffer, stride, stride * height * i);
为了也支持不是8
的整数倍的每像素位值,你应该像这样计算步幅:
int stride = (width * bpp + 7) / 8;