我知道这听起来微不足道,但我目前陷入困境。
我有各种格式的图像作为输入。 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/