Search code examples
c++bitmappnggdi+pixelformat

Saved Gdiplus::Bitmap always has Alpha Channel (RGBA/ARGB)


I have a Gdiplus::Bitmap (in C++) in PixelFormat32bppARGB format and convert it to PixelFormat32bppRGB by using:

        Gdiplus::Bitmap* bitmapRGB = new Gdiplus::Bitmap(bitmap->GetWidth(), bitmap->GetHeight(), PixelFormat32bppRGB);
        Gdiplus::Graphics graphics(bitmapRGB);
        graphics.DrawImage(bitmap, Gdiplus::Point(0, 0));

If I check the format of the RGB-Bitmap it is correct (RGB):

bitmapRGB ->GetPixelFormat() == PixelFormat32bppRGB

If I save the Bitmap and check its format (i.e. with Gimp) there is a fourth channel.

    CLSID pngClsid;
    GetEncoderClsid(L"image/png", &pngClsid);
    bitmapRGB ->Save(path, &pngClsid, NULL);

How do I achieve to get a png with a RGB-Pixelformat?


Solution

  • PixelFormat32bppRGB is still 32-bit. PixelFormat24bppRGB is needed for 24-bit format:

    Gdiplus::Bitmap* bitmapRGB = new Gdiplus::Bitmap(
        bitmap->GetWidth(), bitmap->GetHeight(), PixelFormat24bppRGB);
    

    The new operator is not necessary, use one of the appropriate constructor to make sure there is no memory leak:

    //convert:
    Gdiplus::Bitmap bitmap(L"source.jpg");
    Gdiplus::Bitmap bitmapRGB(bitmap.GetWidth(), bitmap.GetHeight(), PixelFormat24bppRGB);
    
    Gdiplus::Graphics graphics(&bitmapRGB);
    graphics.DrawImage(&bitmap, Gdiplus::Point(0, 0));
    
    CLSID pngClsid;
    GetEncoderClsid(L"image/png", &pngClsid);
    bitmapRGB.Save(L"destination.png", &pngClsid);