locked
GDI+ or .NET bug - 8bpp PNG loaded as 32bpp RRS feed

  • Pergunta

  • There is a bug in GDI (or .NET).

    Steps to Reproduce:

    1. Create a 8bpp Bitmap

    Bitmap bmp = new Bitmap(200, 200, PixelFormat.Format8bppIndexed);

    2. Save it to a file

    bmp.Save("pngFile.png", ImageFormat.Png);

    3. Load it as a new bitmap

    Bitmap bmpFromPNG = new Bitmap(filenamePNG);

    The PixelFormat will be 32bpp! It should be 8bpp!!! If you do the same with a BMP the format will be the correct (8bpp).

    Solutions that I found:

    1. Change the bmp palette (at least from rang 16 to 40)

     ColorPalette pal;
     pal = bmp.Palette;
     for (int i = 16; i < 40; i++)
     {
     pal.Entries[i] = Color.FromArgb(i, i, i);
     }
     bmp.Palette = pal;
    

     

    2. Load the bmp using WPF new classes:

     public static Bitmap LoadPNG(string file)
     {
     //using (Bitmap PNG = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
     // PNG.Save("Test.png", ImageFormat.Png);
     PngBitmapDecoder pngDec = new PngBitmapDecoder(new Uri(file),
        BitmapCreateOptions.PreservePixelFormat,
        BitmapCacheOption.OnDemand);
     BmpBitmapEncoder bmpEnc = new BmpBitmapEncoder();
     bmpEnc.Frames.Add(pngDec.Frames[0]);
     Bitmap bmp = null;
     using (MemoryStream stream = new MemoryStream())
     {
     bmpEnc.Save(stream);
     bmp = new Bitmap(stream);
     }
     return bmp;
     }
    


    What do you think about that, is it GDI+ bug?

    Emgucv does have a similar bug, if the palette is not in grayscale, a 8bpp image will be loaded incorrectly.. :(



    segunda-feira, 18 de julho de 2011 14:05

Todas as Respostas

  • Hello FreeCoderr, you can try to use the GDI encoder parameters:

     

          var bmp = new Bitmap(200, 200, PixelFormat.Format8bppIndexed);
          var encoder = ImageCodecInfo.GetImageEncoders().Where(item => item.MimeType == "image/png").First();
          var encoderParams = new EncoderParameters(1);
          encoderParams.Param[0] = new EncoderParameter(Encoder.ColorDepth, 16L);
          bmp.Save(@"Image path...", encoder, encoderParams);
    
    

     

    Hop this helps,

    Miguel.

    • Marcado como Resposta Jackie-Sun segunda-feira, 1 de agosto de 2011 05:09
    • Não Marcado como Resposta FreeCoderr segunda-feira, 1 de agosto de 2011 18:17
    segunda-feira, 18 de julho de 2011 14:47
  • It's probably a feature, since you can't draw to an indexed image.
    segunda-feira, 18 de julho de 2011 16:50
  • Hello FreeCoderr, you can try to use the GDI encoder parameters:

     

     

       var bmp = new Bitmap(200, 200, PixelFormat.Format8bppIndexed);
       var encoder = ImageCodecInfo.GetImageEncoders().Where(item => item.MimeType == "image/png").First();
       var encoderParams = new EncoderParameters(1);
       encoderParams.Param[0] = new EncoderParameter(Encoder.ColorDepth, 16L);
       bmp.Save(@"Image path...", encoder, encoderParams);
    
    

     

     

    Hop this helps,

    Miguel.

    This is to save the image as 8bpp. The image is alredy been saved correctly. As you can see opening with an image editor like Irfanview. The bpp is 8. The problem is to reopen it.

    This code is in VB? Can you reproduce to c#?

    'System.Array' does not contain a definition for 'Where' and no extension method 'Where' accepting a first argument of type 'System.Array' could be found (are you missing a using directive or an assembly reference?) 

    segunda-feira, 1 de agosto de 2011 13:16
  • It's probably a feature, since you can't draw to an indexed image.

    What do you mean?? Open a 8bpp bmp the Bitmap will get PixelFormatp 8bpp, if it is a 8bpp PNG the bitmap gets Format32bppArgb ! It is a feature? Something is wrong for sure
    segunda-feira, 1 de agosto de 2011 13:23
  • It's probably a feature, since you can't draw to an indexed image.

    What do you mean?? Open a 8bpp bmp the Bitmap will get PixelFormatp 8bpp, if it is a 8bpp PNG the bitmap gets Format32bppArgb ! It is a feature? Something is wrong for sure

    What don't you understand?  What do you think is wrong?
    segunda-feira, 1 de agosto de 2011 13:30
  • What???

    Maybe if you read my post and reproduce the error you can realize what is wrong.

     


    1. Save 8bpp Bitmap as bmp and as PNG

    2. Create a new Bitmap from the files. From the bmp it will be 8bpp (CORRECT) from the PNG it will be 32bpp (not correct).

    If you open with an image editor both files are in 8bpp, so save is ok.

    If you edit the palette before save, it will be loaded correctly.

    I think GDI do not handle well the png palette.

    segunda-feira, 1 de agosto de 2011 13:57
  • What???

    Maybe if you read my post and reproduce the error you can realize what is wrong.

     


    1. Save 8bpp Bitmap as bmp and as PNG

    2. Create a new Bitmap from the files. From the bmp it will be 8bpp (CORRECT) from the PNG it will be 32bpp (not correct).

    If you open with an image editor both files are in 8bpp, so save is ok.

    If you edit the palette before save, it will be loaded correctly.

    I think GDI do not handle well the png palette.


    My response was that it was a feature that by default it opens a drawable image.  As you have determined, there are many ways to override the default behavior.  These are ancient classes which have long ago ceased any development.  WYSIWYG.  Use WPF for classes under current development.
    segunda-feira, 1 de agosto de 2011 16:57
  • Hi,

     

    You can submit this issue to Microsoft Connect feedback portal http://connect.microsoft.com to help to improve the old classes, Microsoft engineers will evaluate them seriously, thanks.

     

    If this issue is urgent, please contact support at http://support.microsoft.com.

     

    I hope this can help you.

     

     

    Have a nice day,


    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    terça-feira, 2 de agosto de 2011 02:52
  • 8 years later and still broken. And broken in dotnet Core 3 no less! If the file is 8bpp, it should load as 8bpp.
    segunda-feira, 4 de novembro de 2019 21:45