Reputation: 93
I have image, that have System.Drawing.Imaging.PixelFormat.Format1bppIndexed
(view in windows explorer file properties).
But after load the file, seen Format32bppArgb
:
string path = "cat.png";
using (var bitmap = new System.Drawing.Bitmap(path))
{
// bitmap.PixelFormat == Format32bppArgb, but must Format1bppIndexed
}
what could be the problem?
test image 1: https://i.sstatic.net/r2HGH.png
test image 2: https://i.sstatic.net/xUgEy.png
UPD
Try to use constructor
// useIcm:
// true to use color correction for this System.Drawing.Bitmap; otherwise, false.
Bitmap(string filename, bool useIcm);
test image 1 loaded success, but test image 2 have Format32bppArgb
Upvotes: 0
Views: 5090
Reputation: 5629
This is a bug in the .Net framework; it seems to have a problem with the way transparency works on paletted png images.
See, paletted png images are actually fully alpha-capable, on a palette level. The png file has a specific extra chunk (the "tRNS" chunk) that can be added to define the alpha of each palette entry. Somehow, when encountering this, the .Net framework applies this alpha correctly, but then insists on treating the image as 32bppARGB.
This is very strange, because it completely supports alpha on the palette in exactly that way, and can in fact save files like that without any issue.
What is especially odd is that the file you have there doesn't actually have transparency on its palette; the "tRNS" chunk defines all palette entries as 100% opaque. But it seems just having the chunk is enough.
The workaround is to load the png into a byte array, read and cut out the "tRNS" chunk containing the transparency data so the .Net framework retains the indexed format, and, after loading the image from a stream created from the edited byte array, post-process the palette using the read "tRNS" data to apply the alpha.
The full code to do that is posted in this answer:
A: Loading an indexed color image file correctly
By the way, analysis of the png chunks showed that that second image is in fact a one-bit-per-pixel image, with a palette of 256 colours. No idea how you managed that.
Upvotes: 1
Reputation: 18013
It does not really matter what the pixel format of the original image is. It depends on the decoder whether it preserves the original pixel format. If you really want to convert a 2-color image to 1 bpp format, see the ConvertPixelFormat
method in my answer here.
Upvotes: 0
Reputation: 1
When you run the Bitmap
constructor, it parses the image file and loads it into an object. What you're seeing is not the PixelFormat
of the file, but the PixelFormat
of the object. The constructor is converting the format to Format32bppArgb
internally.
Upvotes: 0