1

I can load a hbitmap into a hdc like this:

        Gdiplus::Color Color{ 255, 255, 255 };
        hBitmap = NULL;
        Gdiplus::Bitmap* bitmap = Gdiplus::Bitmap::FromFile(L"home.png", false);
        if (bitmap)
        {
            bitmap->GetHBITMAP(Color, &hBitmap);
            delete bitmap;
        }

        BITMAP bm;
        GetObject(hBitmap, sizeof(bm), &bm);
        HDC hDCMem = CreateCompatibleDC(NULL);
        HBITMAP hBitmapOld = (HBITMAP)SelectObject(hDCMem, hBitmap);

How could I do the reverse, getting back a bitmap loaded into a specific hdc?

I would need first, retrieve the hbitmap and then the bitmap from it? How?

  • Related: [How to construct a GDI+ Bitmap object from a Device-Dependent HBITMAP](https://stackoverflow.com/questions/45319996/), [How to Create a Gdiplus::Bitmap from an HBITMAP, retaining the alpha channel information?](https://stackoverflow.com/questions/335273/) – Remy Lebeau Jan 26 '22 at 17:14
  • 4
    [GetCurrentObject](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getcurrentobject) with `OBJ_BITMAP` – dialer Jan 26 '22 at 17:15
  • @dialer nice, I never knew about that function! – Remy Lebeau Jan 26 '22 at 17:16

1 Answers1

1

You can use GetCurrentObject() to access the HBITMAP (and HPALETTE) currently selected into an HDC.

Alternatively, you can create a new HBITMAP of desired dimension and color depth, SelectObject() it into a new memory HDC, and then BitBlt()/StretchBlt() the source HDC into it.

Either way, once you have an HBITMAP, you can create a new GDI+ Bitmap from it using the Bitmap(HBITMAP, HPALETTE) constructor or Bitmap::FromHBITMAP() method.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • You could also `SelectObject` a different bitmap, which will return the existing bitmap (and unlink it from the HDC, removing most limits on what you're allowed to do with the bitmap) – Ben Voigt Jan 26 '22 at 17:19
  • @BenVoigt Yes, I thought of that, but that is a potentially destructive operation, depending on where the `HDC` is coming from. You would typically have to remember to restore the old bitmap when finished using it, and hope your code doesn't crash before then. – Remy Lebeau Jan 26 '22 at 17:19
  • Well, you can (and should) select the original bitmap back in the way you found it. But you could have read from the bitmap before doing so. Of course, that simply changes a race condition from "modifying the bitmap data while you are in the middle of reading it" to "making modifications to the wrong bitmap" – Ben Voigt Jan 26 '22 at 17:22
  • Do you know if there's any way/tip to reduce the size of bitmaps stored in the memory? –  Jan 26 '22 at 17:59
  • @Ruan the only way I know of is to create a new bitmap that has lower dimensions/color depth, or enables compression, etc and then copy the pixels from the old bitmap to the new bitmap. Or, simply don't use bitmaps at all, use a smaller format instead, like JPG/GIF/etc. – Remy Lebeau Jan 26 '22 at 18:18