c# - 从位图转换为位图源期间蓝色和红色 channel 交换

标签 c# wpf bitmap bitmapsource

我需要将从相机接收到的位图复制到 BitmapSource 中,以便在 WPF 应用程序中显示它。图像以负步幅到达 PixelFormat.Format24bppRgb。我通过以下代码得到了这个工作

//NOTE: image is in PixelFormat.Format24bppRgb
var bitmap = imageBuffer.Bitmap;
Image = new WriteableBitmap(bitmap.Width, bitmap.Height, 96, 96, PixelFormats.Rgb24, null);

var bitmapData = bitmap.LockBits(
    new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
    System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);
var rowSize = bitmapData.Stride < 0 ? -bitmapData.Stride : bitmapData.Stride;
var bitmapPtr = bitmapData.Scan0;
var bitmapLine = new Int32Rect(0, 0, bitmap.Width, 1);

for (int line = 0; line < bitmap.Height; line++)
{
    Image.WritePixels(bitmapLine, bitmapPtr, rowSize, rowSize, 0, line);
    bitmapPtr += bitmapData.Stride;
}
bitmap.UnlockBits(bitmapData);

我遇到的问题是蓝色和红色 channel 似乎交换了。我可以通过将 BitmapSource 创建为 Bgr24 来解决该问题,但由于在应用程序中我还需要在转换之前进行一些图像处理,所以我更喜欢在此之前让事物具有正确的格式。我在转换过程中做错了什么,还是这是 GDI 的一些特性?

请注意,如果我将相机位图直接应用到 WinForms 图片框,图像将正确显示。另外 WriteableBitmap 只是为了代码简洁而重新创建。

最佳答案

如果您收到的图像格式为 RGB,但步长为负,则图像格式为 BGR,因为它是向后读取的。

负步长意味着它是自下而上而不是自上而下的图像,通常 Graphics 的绘制操作会为您处理这些事情,但是 Image 类 WritePixels 不允许指定负步长,因此您必须反转像素格式 (BGR)

关于c# - 从位图转换为位图源期间蓝色和红色 channel 交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36998288/

相关文章:

c# - wpf mvvm递归树

c# - 如何添加 Canvas 边框

android - 加载/显示位图的最快方式;重用位图的最佳方式

WPF - DocumentViewer 不允许向上/向下翻页

c# - 如何在 C# (WPF) 中获取字符串资源?

java - 安卓 Java : bitmap resize define height and width auto

java - 将位图循环到数组中

c# - 使用 Reflection.Emit 实现泛型接口(interface)

c# - 字符串字段长度限制和换行

c# - 按钮控件中的嵌入代码 (<%= %>)