Working with HBITMAP (win32 api) Read from external file, Get raw data and Create one programmatically

This article shows how to work with bitmap using win32 API, includes read bitmap from external file, copy and stretch the bitmap size, then retrieve the raw data from bitmap handle. The bitmap is in most simple format with one layer and 4 bytes per pixel (i.e. no alignment for each width).

Read from file “one.bmp”

HBITMAP hBitmap;

// Without LR_CREATEDIBSECTION flag, LoadImage() will not
// use CreateDIBSection to create bitmap. It will cause
// the bmBits = NULL
hBitmap = (HBITMAP)LoadImage(NULL, 
    L"one.bmp", 
    IMAGE_BITMAP, 
    0, 
    0, 
    LR_LOADFROMFILE | LR_CREATEDIBSECTION);

Create/Stretch a bitmap programmatically from other bitmap named ‘hbitmap’

HDC        srcDC, destDC;
HBITMAP    destBM;
BITMAP     srcBitmap, destBitmap;
BOOL       bResult;
BYTE*      ppvBits;

// create a destination bitmap and DC with size w/h
BITMAPINFO bmi;
ZeroMemory(&bmi, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biWidth = w;
bmi.bmiHeader.biHeight = h;
bmi.bmiHeader.biPlanes = 1;

// Do not use CreateCompatibleBitmap otherwise api will not allocate memory for bitmap
destBM = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**)&ppvBits, NULL, 0);
destDC = CreateCompatibleDC(NULL);
SelectObject(destDC, destBM);

// create a hdc and select the source bitmap names 'hbitmap'
srcDC = CreateCompatibleDC(NULL);
GetObject(hbitmap, sizeof(BITMAP), (LPSTR)&srcBitmap);
SelectObject(srcDC, hbitmap);

// copy and scaling to new width/height (w,h)
SetStretchBltMode(destDC, HALFTONE); // important!
bResult = StretchBlt(destDC, 0, 0, w, h,
    srcDC, 0, 0, destBitmap.bmWidth, destBitmap.bmHeight, 
    SRCCOPY);

// get destination bitmap information
if (bResult == TRUE)
{
    // raw data is inside destBitmap.bmBits
    GetObject(destBM, sizeof(BITMAP), (LPSTR)&destBitmap);
}

DeleteDC(destDC);
DeleteDC(srcDC);