winforms System.Drawing.Bitmap的. net7中的像素格式在24位RGB中混合了R和B值

vojdkbi0  于 2023-03-19  发布在  其他
关注(0)|答案(1)|浏览(146)

所以我使用了System.Drawing位图实现,看起来像是在将格式设置为PixelFormat.Format24bppRgb时,它实际上将其解释为24Bgr而不是RGB

latestImage = new Bitmap(bitmap.Width, bitmap.Height, bitmap.Stride, PixelFormat.Format24bppRgb, bitmap.Scan0);
for (int x = 0; x < _latestImage.Width; x++)
{
    for (int y = 0; y < _latestImage.Height; y++)
    {
        var c = _latestImage.GetPixel(x, y);
        byte r = Marshal.ReadByte((bitmap.Scan0 + (x * 3) + 0) + (y * bitmap.Stride));
        byte g = Marshal.ReadByte((bitmap.Scan0 + (x * 3) + 1) + (y * bitmap.Stride));
        byte b = Marshal.ReadByte((bitmap.Scan0 + (x * 3) + 2) + (y * bitmap.Stride));
        _latestImage.SetPixel(x, y, System.Drawing.Color.FromArgb(r, g, b));
    }
}
_latestImage.Save(temp3, ImageFormat.Jpeg);

对比

_latestImage = new Bitmap(bitmap.Width, bitmap.Height, bitmap.Stride, PixelFormat.Format24bppRgb, bitmap.Scan0);
_latestImage.Save(temp3, ImageFormat.Jpeg);

在第一个例子中,我在所有的东西上循环,手动设置颜色,它工作正常,但永远需要。在第二个例子中,红色和蓝色在图像中交换。
是我疯了还是.net实现错了?
我尝试过不同的格式,但其余的更糟糕。一直在寻找另一个库来处理我的位图数据,但还没有找到解决方案。

qxgroojn

qxgroojn1#

在第一个例子中,我循环了所有的东西,并手动设置颜色,它的工作很好,但需要永远
当然可以,你调用的GetPixelSetPixel都非常慢,你可以访问Scan0中的原始数据,直接通过Span<byte>写入即可。
有趣的是,你甚至没有使用GetPixel的结果,你只是为了好玩而调用它?
是我疯了还是.net实现错了?
当然,你是这样的,因为你没有考虑你编程的环境,特别是你的机器的字节序(它可能与其他人运行你的代码的字节序相同,也可能不同)。
同样需要注意的是,你的WPF标签和你正在编写的GDI+代码是截然相反的。你的代码是完全在CPU上运行的古老代码。像WPF这样的现代框架在GPU上进行图像处理、存储和显示。

相关问题