How to Clone (Duplicate) a bitmap?

 

The following code snippet describes, how to clone a given bitmap. Same type sample also exisitng in MSDN but it’s lacking of some error checking and all.  The idea for duplicating a bitmap is very simple.

1. Create a empty bitmap having same dimensions.

2. Create a source DC and select the input bitmap

3. Create a destination DC and select the empty bitmap created

4. Blit the source dc to destination dc. this will blit the source bitmap (currently selected object of source DC) to destination DC (there we have the newly created bitmap as the drawing object). So the source bitmap content will be copied to destination bitmap.

5. now your new bitmap is ready and return it.

6. Before returning do the cleanup activities for the temporary GDI objects we have created.

7.  The caller function should do the cleanup activities. i.e to delete the bitmap object returned after use. 

See the sample code.

HBITMAP CloneBitmap( HBITMAP hSourceBitmap )
{
    // Pointer to access the pixels of bitmap
    HDC hdcSrc = CreateCompatibleDC( NULL );
    HDC hdcDst = CreateCompatibleDC( NULL );
    HBITMAP hNewBitmap;
    BITMAP stBitmap = {0};
    GetObject( hSourceBitmap, sizeof(stBitmap), &stBitmap );
    hNewBitmap = CreateBitmap( stBitmap.bmWidth, stBitmap.bmHeight,
                                stBitmap.bmPlanes,stBitmap.bmBitsPixel,NULL);
    if( hNewBitmap )
    {
        SelectObject( hdcSrc, hSourceBitmap);
        SelectObject(hdcDst, hNewBitmap);
        // Blit existing bitmap to newly created bitmap
        BitBlt(hdcDst, 0, 0, stBitmap.bmWidth, stBitmap.bmHeight, hdcSrc, 0, 0, SRCCOPY);
    }

    // Cleanup the created Device contexts
    SelectObject(hdcSrc, 0 );
    SelectObject(hdcDst, 0 );
    DeleteDC(hdcSrc);
    DeleteDC(hdcDst);
    return hNewBitmap;
}

 
  • EmoBemo

    Not bad, but not so efficient in multithreaded environment, since one HBITMAP can be selected only in one HDC and if you want to duplicate bitmaps from many thread they have to wait for each other even though they want to read only. I am still looking for solution where SelectObject is not used.

  • http://free-sk.t-com.hr/T800/index.html T800

    This example has memory leak – every created DC has a 1×1 monocrome bitmap already selected in it (see MSDN).
    Wrong:
    SelectObject( hdcSrc, hSourceBitmap);
    SelectObject(hdcDst, hNewBitmap);
    ….
    SelectObject(hdcSrc, 0 );
    SelectObject(hdcDst, 0 );

    Correct:
    HBITMAP hOld1=SelectObject( hdcSrc, hSourceBitmap);
    HBITMAP hOld2=SelectObject(hdcDst, hNewBitmap);
    ….
    SelectObject(hdcSrc, hOld1);
    SelectObject(hdcDst, hOld2);