为什么PixelFormat是Format32bppArgb,但图像有Format1bppIndexed

本文关键字:图像 Format1bppIndexed PixelFormat Format32bppArgb 为什么 | 更新日期: 2023-09-27 18:16:41

我有图像,有System.Drawing.Imaging.PixelFormat.Format1bppIndexed(视图在windows资源管理器文件属性)。

但加载文件后,看到Format32bppArgb:

string path = "cat.png";
using (var bitmap = new System.Drawing.Bitmap(path))
{
    // bitmap.PixelFormat == Format32bppArgb, but must Format1bppIndexed 
}

有什么问题吗?

test image 1: https://i.stack.imgur.com/r2HGH.png
测试图像2: https://i.stack.imgur.com/xUgEy.png

乌利希期刊指南
尝试使用构造函数

//   useIcm:
//     true to use color correction for this System.Drawing.Bitmap; otherwise, false.
Bitmap(string filename, bool useIcm);

测试映像1加载成功,但测试映像2有Format32bppArgb

为什么PixelFormat是Format32bppArgb,但图像有Format1bppIndexed

这是。net框架中的一个bug;透明度在调色板PNG图像上的工作方式似乎有问题。

看,调色板png图像实际上完全具有alpha功能,在调色板级别。png文件有一个特定的额外块("tRNS"块),可以添加它来定义每个调色板条目的alpha值。不知何故,当遇到这种情况时,. net框架正确地应用这个alpha,但随后坚持将图像处理为32bppARGB。

这很奇怪,因为它完全支持面板上的alpha, 实际上可以保存这样的文件没有任何问题。

特别奇怪的是,你在那里的文件实际上没有在其调色板上有透明度;"tRNS"块将所有调色板项定义为100%不透明。但似乎只要块就足够了。

解决方法是将png加载到字节数组中,读取并剪切包含透明度数据的"tRNS"块,以便. net框架保留索引格式,并且,在从编辑的字节数组创建的流中加载图像后,使用读取的"tRNS"数据对调色板进行后处理以应用alpha。

完整的代码是张贴在这个答案:

A:正确加载已索引的彩色图像文件

顺便说一下,对png块的分析表明,第二张图像实际上是一个每像素1位的图像,调色板256色。不知道你是怎么做到的

当您运行Bitmap构造函数时,它解析图像文件并将其加载到对象中。您看到的不是文件的PixelFormat,而是对象的PixelFormat。构造函数正在内部将格式转换为Format32bppArgb

原始图像的像素格式并不重要。这取决于解码器是否保留原始像素格式。如果你真的想要将2色图像转换成1bpp格式,请参阅我在这里的回答中的ConvertPixelFormat方法。