在从位图到位图源的转换过程中交换了蓝色和红色通道
Blue and red channels swapped during conversion from bitmap to 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);
我 运行 遇到的问题是蓝色和红色通道似乎互换了。我可以通过将 BitmapSource 创建为 Bgr24 来解决这个问题,但是因为在应用程序中我还需要做在转换之前进行一些图像处理我希望在此之前以正确的格式处理内容。我在转换中做错了什么或者这是 GDI 的一些特性吗?
请注意,如果我将相机位图直接应用于 WinForms 图片框,图像会正确显示。此外 WriteableBitmap 只是为了代码简洁而重新创建。
如果您收到的图像格式是 RGB 但步幅为负,则图像格式是 BGR,因为它正在向后读取。
Negative stride 表示它是自下而上而不是自上而下的图像,通常 Graphics 的绘制操作会为您处理这些事情,但是 Image class WritePixels 不允许指定负数大步,所以你必须反转像素格式(BGR)
从 System.Drawing.Imaging.PixelFormat.Format24bppRgb 到 System.Windows.Media.PixelFormat 的正确转换是 PixelFormats。 Bgr24。
负步幅与像素格式无关,它仅描述图像的垂直旋转 - 正向自上而下,负向自下而上。如果步幅对像素格式有任何影响,那么下面的代码将存储具有反向步幅且交换蓝色和红色通道的图像。事实并非如此,唯一看到的效果是一张图片垂直旋转。
var wholeImage = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
bitmapData = bitmap.LockBits(wholeImage, ImageLockMode.ReadOnly, bitmap.PixelFormat);
var reverseStride = -bitmapData.Stride;
var reversedStartPtr = bitmapData.Scan0 + bitmapData.Stride * (bitmapData.Height - 1);
var reverseStrideBitmap = new Bitmap(bitmapData.Width, bitmapData.Height,
reverseStride, bitmapData.PixelFormat, reversedStartPtr);
bitmap.Save("original.png");
reverseStrideBitmap.Save("reversedStride.png");
我需要将从相机接收到的位图复制到 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);
我 运行 遇到的问题是蓝色和红色通道似乎互换了。我可以通过将 BitmapSource 创建为 Bgr24 来解决这个问题,但是因为在应用程序中我还需要做在转换之前进行一些图像处理我希望在此之前以正确的格式处理内容。我在转换中做错了什么或者这是 GDI 的一些特性吗?
请注意,如果我将相机位图直接应用于 WinForms 图片框,图像会正确显示。此外 WriteableBitmap 只是为了代码简洁而重新创建。
如果您收到的图像格式是 RGB 但步幅为负,则图像格式是 BGR,因为它正在向后读取。
Negative stride 表示它是自下而上而不是自上而下的图像,通常 Graphics 的绘制操作会为您处理这些事情,但是 Image class WritePixels 不允许指定负数大步,所以你必须反转像素格式(BGR)
从 System.Drawing.Imaging.PixelFormat.Format24bppRgb 到 System.Windows.Media.PixelFormat 的正确转换是 PixelFormats。 Bgr24。
负步幅与像素格式无关,它仅描述图像的垂直旋转 - 正向自上而下,负向自下而上。如果步幅对像素格式有任何影响,那么下面的代码将存储具有反向步幅且交换蓝色和红色通道的图像。事实并非如此,唯一看到的效果是一张图片垂直旋转。
var wholeImage = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
bitmapData = bitmap.LockBits(wholeImage, ImageLockMode.ReadOnly, bitmap.PixelFormat);
var reverseStride = -bitmapData.Stride;
var reversedStartPtr = bitmapData.Scan0 + bitmapData.Stride * (bitmapData.Height - 1);
var reverseStrideBitmap = new Bitmap(bitmapData.Width, bitmapData.Height,
reverseStride, bitmapData.PixelFormat, reversedStartPtr);
bitmap.Save("original.png");
reverseStrideBitmap.Save("reversedStride.png");