Converting Bitmap PixelFormats in C#
Asked Answered
V

3

58

I need to convert a Bitmap from PixelFormat.Format32bppRgb to PixelFormat.Format32bppArgb.

I was hoping to use Bitmap.Clone, but it does not seem to be working.

Bitmap orig = new Bitmap("orig.bmp");
Bitmap clone = orig.Clone(new Rectangle(0,0,orig.Width,orig.Height), PixelFormat.Format24bppArgb);

If I run the above code and then check clone.PixelFormat it is set to PixelFormat.Format32bppRgb. What is going on/how do I convert the format?

Victorie answered 6/1, 2010 at 21:32 Comment(5)
Does this only happen on XP? I found the problem on XP but it seems to work fine on Windows 7. Hans' solution fixed it for me.Hammerhead
That's kind of funny. I have a solution that works fine on XP but breaks, giving this error, on Windows 7...Ary
I can confirm that only XP is affected.Wittol
You should watch out on systems that aren't XP too. I haven't tested this spesific code, but working on the pixel level when comparing two images on Windows 7 I ran into a similar problem that was caused from this bug/feature. Dan7 explained exactly what is happening and a more general approach to fixing it.Refrigerator
This works on all platforms (disclaimer: written by me). Can be downloaded as a NuGet.Rabbitfish
L
107

Sloppy, not uncommon for GDI+. This fixes it:

Bitmap orig = new Bitmap(@"c:\temp\24bpp.bmp");
Bitmap clone = new Bitmap(orig.Width, orig.Height,
    System.Drawing.Imaging.PixelFormat.Format32bppPArgb);

using (Graphics gr = Graphics.FromImage(clone)) {
    gr.DrawImage(orig, new Rectangle(0, 0, clone.Width, clone.Height));
}

// Dispose orig as necessary...
Lunula answered 6/1, 2010 at 21:46 Comment(1)
I had a similar issue to the OP, except I had problems with a 48BppRgb TIFF that was saved as 32BppArgb PNG. GDI+ couldn't convert properly and the resulting image was very dark. This solution allowed me to solve that problem by manually redrawing the image as 32BppRgb, so +1.Infracostal
K
38

For some reason if you create a Bitmap from a file path, i.e. Bitmap bmp = new Bitmap("myimage.jpg");, and call Clone() on it, the returned Bitmap will not be converted.

However if you create another Bitmap from your old Bitmap, Clone() will work as intended.

Try something like this:

using (Bitmap oldBmp = new Bitmap("myimage.jpg"))
using (Bitmap newBmp = new Bitmap(oldBmp))
using (Bitmap targetBmp = newBmp.Clone(new Rectangle(0, 0, newBmp.Width, newBmp.Height), PixelFormat.Format32bppArgb))
{
    // targetBmp is now in the desired format.
}
Know answered 19/11, 2011 at 15:8 Comment(3)
+1 Thanks Dan7 for explaining what the trigger was. I've seen new Bitmap(new Bitmap("image.jpg")) before but didn't know why it worked.Ary
is there an easy way to Clone and convert all the pages of the bitmap ? I've noticed that targtBmp only has the active frame in oldBmp.Caddish
This better than marked "Solution" - it's worked with Indexed PixelFormat 4bpp, 8bppDoorstep
O
8
using (var bmp = new Bitmap(width, height, PixelFormat.Format24bppArgb))
using (var g = Graphics.FromImage(bmp)) {
  g.DrawImage(..);
}

Should work like that. Maybe you want to set some parameters on g to define the interpolation mode for quality etc.

Omnivorous answered 6/1, 2010 at 21:44 Comment(2)
InterpolationMode is for scaling, i don't really think that he wants to scale it. Maybe do something like bmp.SetResolution(old.HorizontalResolution, old.VerticalResolution) and call g.DrawImageUnscaled(old, 0,0). But its just my opinion :)Ribbing
@Elmue - do you have any reference to your statement?MSDN states other..Leg

© 2022 - 2024 — McMap. All rights reserved.