c# - 从一种 PixelFormat 转换为另一种 WPF

标签 c# bitmap pixelformat

我知道这听起来微不足道,但我目前陷入困境。

我有各种格式的图像作为输入。 Gray16、Gray8、Indexed8 等。我需要的是将它们转换为 RGB24 格式,到目前为止我已经做到了

public WriteableBitmap ConvertToRgb(WriteableBitmap source)
        {
            <-- create the new bitmap of the same width/height as the source with specific RGB24 format-->
            var newBitmap = new WriteableBitmap(source.PixelWidth, source.PixelHeight, source.DpiX, source.DpiY, PixelFormats.Rgb24, source.Palette);
            
            <-- create my pixel array -->
            byte[] pixels = new byte[
                        source.PixelHeight * source.PixelWidth *
                            source.Format.BitsPerPixel / 8];
            <-- copy my original pixels into the array) --> 
            source.CopyPixels(pixels, source.PixelWidth * source.Format.BitsPerPixel / 8, 0);
            <-- write the pixels into the new image --> 
            newBitmap.WritePixels(
                 new Int32Rect(0, 0, newBitmap.PixelWidth, newBitmap.PixelHeight),
                 pixels,
                 newBitmap.PixelWidth * newBitmap.Format.BitsPerPixel/8,
                 0);

            return newBitmap;
        }

此方法抛出异常“缓冲区大小不足”

我想它必须对我的 WritePixels 参数之一执行某些操作。但我不知道缓冲区的正确大小是多少。我找不到太多文档。任何帮助都会很好。

我用来转换的方法不是确定的,如果您知道更好的转换方法,请告诉我。

最佳答案

首先:RGB 图像的默认格式是(与直觉相反)BGR24 或 ARGB 的 BGRA32。这是因为系统的字节序 ( see here for why this happens )

第二:当你使用这种方法时,你根本不会转换PixelFormat。您只需获取所有像素,将它们转换为字节数组,并将这些字节用于新的像素格式 - 这将对字节进行完全不同的解释。因此,如果您的源图像采用 BGRA 格式并且转换为 RGB24,则第一个源像素的蓝色分量将被解释为第一个目标像素的红色分量,依此类推 - 第一个源 alpha 字节将被解释为第一个第二个像素的红色字节(不完全正确,但更容易理解。正确的映射是 a>b、r>g、g>r、r>b2... 因为颜色如何映射到与它们是如何命名的)。这也是缓冲区大小不匹配的原因 - 因为不同的像素格式需要不同的字节数。

WriteableBitmap 的 CopyPixels 和 WritePixels 完全不知道底层的 PixelFormat 并且完全忽略它。仅当源和目标具有完全相同的 PixelFormat 和调色板,或者您手动重新计算并重新排列缓冲区中的所有字节时,这才有效。

您要查找的内容要容易得多:它的名称为 FormatConvertedBitmap 。这是一个 BitmapSource,特别用于更改图像的 PixelFormat。下面这行应该完成将所有内容转换为正确的 RGBA32 图像的工作(仅对 RGB 使用 Bgr24)。

var rgba32 = new FormatConvertedBitmap(source, PixelFormats.Bgra32, source.Palette,0);

关于c# - 从一种 PixelFormat 转换为另一种 WPF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62592706/

相关文章:

c# - 正确覆盖 [NotNull] 属性

android - 仍然得到 E/JavaBinder:!!!失败的 BINDER 交易 !!!错误甚至图像已压缩

Android高分辨率图像处理

c - SIMD 将 12 位字段解包为 16 位

ffmpeg - FFPROBE - "Unspecified pixel format"

javascript - 有没有办法通过 javascript/jquery 将 Mongo ObjectId 转换为字符串

c# - 删除表行而不是隐藏在 rdlc 报告中

c# - .Net 4.0 和 .NET 4.7.2 标题选择之间 DataGridView 的重大变化

c# - GDI+ 错误仅发生在 Windows XP 上

cocoa - OpenGL像素格式属性(NSOpenGLPixelFormatAttibutes)解释?