What is Bitmap and BMP file?

Bitmap is a collection of bits that represents a rasterized photographic image where each pixel being represented as a group of bits. Bitmap file (.bmp) is a file format to store image pixels in terms of data bits in a file. It is an array of bits where each pixel is represented by a group of 4 bits, 8 bits, 16 bits, 24 bits or 32 bits. The 2D pixel array in the picture is stored as a flat series of bits. The width of pixel bits is directly proportional to the color depth of the bitmap picture. Bitmap with 4 bits per pixel can hold a maximum of 16 colors. Thus 8 bits can have 256 colors and 16 bit 65K colors, 24bits and 32bits can have 16 millions possible colors in one pixel.

Where does bitmaps used in programming?

Bitmaps are the graphical media files used to show a picture to the users. A graphical application can use a bitmap in tool-bars, buttons, menus and many other places. Image editor applications can create, manipulate (scale, scroll, rotate, and paint), and store images as files on a disk. Win32 or Linux graphical subsystem reads these bits one by one and creates pixels in the screen. Thus the entire picture is formed in the screen.

What are the bitmap APIs available?

Now we know the bitmap and its usage we should learn how to use a bitmap in our visual C/C++ program. We will be using some APIs like LoadBitmap, LoadImage, CreateCompatibleDC, SelectObject, BitBlt, DeleteObject, DeleteDC for our example program.

LoadBitmap function

The LoadBitmap function loads the input bitmap resource from a module's executable file and returns the handle. This function has been superseded by the generic LoadImage function.

HBITMAP LoadBitmap(
  HINSTANCE hInstance,  /* handle to application instance */
  LPCTSTR lpBitmapName  /* address of bitmap resource name */
);

Parameters

  • HINSTANCE hInstance - A valid handle to the instance of the module executable file that contains the bitmap to be loaded.
  • LPCTSTR lpBitmapName - Pointer to a null-terminated input string that contains the name of the bitmap resource to be loaded. Alternate way to give this parameter is to provide the resource identifier in the low-order word and zero in the high-order word. MAKEINTRESOURCE macro can be used to create this id value.

Return Values

If the function succeeds, the return value is the handle to the specified bitmap. This handle to bitmap can be used further in various drawing/GDI functions. If the function fails, the return value is NULL.

LoadImage function

Loads an icon file(ico), cursor file (.cur), animated cursor (.cur), or bitmap file (.bmp) from resource or from external disk file. This has made the use of LoadBitmap, LoadCursor, LoadIcon as obsolete in the programming.

HANDLE LoadImage(
  HINSTANCE hInst,
  LPCSTR    lpStrname,
  UINT      ntype,
  int       cx,
  int       cy,
  UINT      fuLoad
);

Parameters

HINSTANCE hInst - A valid and non-NULL handle to the instance of the module or application or instance of the resource DLL where the image is located. This should be given as NULL when loading image file from filesystem of disk or loading OEM images of the operating system.

LPCTSTR lpStrname - A null terminated string holding name of the image of the path of image to be loaded. Loading an image file from filesystem can be done by providing hInst as NULL and fuLoad as LR_LOADFROMFILE value. lpszName should be the path of the file that contains icon, cursor, or bitmap file.

Loading an image from the application resource can be done while hInst is set as the module handle and fuLoad as a value other than LR_LOADFROMFILE. lpszName should be the resource name of the icon, cursor, or bitmap. MAKEINTRESOURCE macro to convert the image ordinal into a form that can be passed to the LoadImage function.

Operating system bitmaps, icons, cursors can be loaded when hinst parameter is NULL and fuLoad parameter is LR_SHARED and LR_LOADFROMFILE is not used. Windows defines a set of OEM image constants for the users to use in the application and they are defined in Winuser.h. There are three types and they start with these prefixes -

  • OBM_XXX - OEM bitmaps
  • OIC_XXX - OEM icons
  • OCR_XXX - OEM cursors
Use MAKEINTRESOURCE macro to convert the constant to use in LoadImage function. Example: To load the OCR_HAND cursor, pass lpName = MAKEINTRESOURCE(OCR_HAND), hinst = NULL, fuLoad = LR_SHARED.

UINT ntype - Numerical value that represents the type of image to be loaded. This API limited to 3 types of legacy images and they are

  • IMAGE_BITMAP - Loads a bitmap
  • IMAGE_CURSOR - Loads a cursor
  • IMAGE_ICON - Loads an icon
This parameter can be one of the following values.

int cx - The width of the image in pixels. If parameters are ntype = IMAGE_ICON / IMAGE_CURSOR, cx = 0, fuLoad = LR_DEFAULTSIZE, the function uses the system metric value of SM_CXICON or SM_CXCURSOR to set the width. If parameters are ntype = IMAGE_ICON / IMAGE_CURSOR, cx = 0, LR_DEFAULTSIZE is not used, the function uses the actual resource width.

int cy - The height of the image in pixels. If parameters are ntype = IMAGE_ICON / IMAGE_CURSOR, cx = 0, fuLoad = LR_DEFAULTSIZE, the function uses the system metric value of SM_CYICON or SM_CYCURSOR to set the height. If parameters are ntype = IMAGE_ICON / IMAGE_CURSOR, cx = 0, LR_DEFAULTSIZE is not used, the function uses the actual resource height.

UINT fuLoad - This parameter is to tell some attribute(s) of the image and can be one or more of the following values.

  • LR_CREATEDIBSECTION(0x2000) - When the uType parameter specifies IMAGE_BITMAP, causes the function to return a DIB section bitmap rather than a compatible bitmap. This flag is useful for loading a bitmap without mapping it to the colors of the display device.
  • LR_DEFAULTCOLOR(0) - The default flag also means image is not LR_MONOCHROME.
  • LR_DEFAULTSIZE(0x40) - Tell LoadImage to use width or height from the system metric values for cursors or icons, if the cx, cy values are set to zero. If this flag is not set and cx = 0 and cy = 0, the function uses the original width and height of the resource. If the resource contains multiple images, the function uses the size of the first image.
  • LR_LOADFROMFILE(0x10) - Loads the filesystem image from the path specified by lpszName (icon, cursor, or bitmap file).
  • LR_LOADMAP3DCOLORS(0x1000) - Searches the color table for the image and replaces the shades of gray with the corresponding 3-D color. This is not required for images with depth greater than 8bpp.
  • LR_LOADTRANSPARENT - Use the color value of the first pixel color value as transparent.
  • LR_MONOCHROME - Colors of the image in black and white or monochrome.
  • LR_SHARED - Load once and share first loaded image handle (used for OEM images)
  • LR_VGACOLOR - Images in true VGA colors.

Return value

Returns the HANDLE of the newly loaded image when this function is successful. Failure case returns a value of NULL and the elaborate error information can be obtained by calling GetLastError.

CreateCompatibleDC

This function creates a memory device context (DC) compatible with the device context given as input.

HDC CreateCompatibleDC(
  HDC hdc
);

Parameters

  • hdc - A handle to device context of existing Window. This creates a memory DC compatible with the application's current screen when the input is given as NULL.

Return value

  • On success it return value is the handle to a memory DC else invalid handle.

SelectObject

Select a GDI object like Bitmap, Brush, Font, Pen, Region to the handle to a device context.

HGDIOBJ SelectObject(
  HDC     hdc,
  HGDIOBJ h
);

Parameters

  • hdc - A handle to the device context.
  • h - A handle to the object to be selected. The specified object must have been created by using one of the following functions.

Return value

  • If the selected object is not a region and the function succeeds, the return value is a handle to the object being replaced. If the selected object is a region and the function succeeds, the return value is one of the following values.

BitBlt

The BitBlt function is also known as bit block transfer function. This performs a bit block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into a destination device context.

BOOL BitBlt(
  HDC   hdc,
  int   x,
  int   y,
  int   cx,
  int   cy,
  HDC   hdcSrc,
  int   x1,
  int   y1,
  DWORD rop
);

Parameters

  • hdc - This is the handle to the destination device context where we want to transfer to.
  • x - The x-coordinate, in logical units, of the upper-left corner of the destination rectangle.
  • y - The y-coordinate, in logical units, of the upper-left corner of the destination rectangle.
  • cx - The width, in logical units, of the source and destination rectangles.
  • cy - The height, in logical units, of the source and the destination rectangles.
  • hdcSrc - A handle to the source device context.
  • x1 - The x-coordinate, in logical units, of the upper-left corner of the source rectangle.
  • y1 - The y-coordinate, in logical units, of the upper-left corner of the source rectangle.
  • rop - A raster-operation code. These codes define how the color data for the source rectangle is to be combined with the color data for the destination rectangle to achieve the final color.

The following list shows some common raster operation codes.
  • BLACKNESS Fills the destination rectangle using the color associated with index 0 in the physical palette. (This color is black for the default physical palette.)
  • CAPTUREBLT Includes any windows that are layered on top of your window in the resulting image. By default, the image only contains your window. Note that this generally cannot be used for printing device contexts.
  • DSTINVERT Inverts the destination rectangle.
  • MERGECOPY Merges the colors of the source rectangle with the brush currently selected in hdcDest, by using the Boolean AND operator.
  • MERGEPAINT Merges the colors of the inverted source rectangle with the colors of the destination rectangle by using the Boolean OR operator.
  • NOMIRRORBITMAP Prevents the bitmap from being mirrored.
  • NOTSRCCOPY Copies the inverted source rectangle to the destination.
  • NOTSRCERASE Combines the colors of the source and destination rectangles by using the Boolean OR operator and then inverts the resultant color.
  • PATCOPY Copies the brush currently selected in hdcDest, into the destination bitmap.
  • PATINVERT Combines the colors of the brush currently selected in hdcDest, with the colors of the destination rectangle by using the Boolean XOR operator.
  • PATPAINT Combines the colors of the brush currently selected in hdcDest, with the colors of the inverted source rectangle by using the Boolean OR operator. The result of this operation is combined with the colors of the destination rectangle by using the Boolean OR operator.
  • SRCAND Combines the colors of the source and destination rectangles by using the Boolean AND operator.
  • SRCCOPY Copies the source rectangle directly to the destination rectangle.
  • SRCERASE Combines the inverted colors of the destination rectangle with the colors of the source rectangle by using the Boolean AND operator.
  • SRCINVERT Combines the colors of the source and destination rectangles by using the Boolean XOR operator.
  • SRCPAINT Combines the colors of the source and destination rectangles by using the Boolean OR operator.
  • WHITENESS Fills the destination rectangle using the color associated with index 1 in the physical palette. (This color is white for the default physical palette.)

Return value

A boolean true or nonzero is returned if the function succeeds. Failure cases will return false or zero and error value can be obtained via calling GetLastError.

Remarks

BitBlt only does clipping on the destination DC. If a rotation or shear transformation is in effect in the source device context, BitBlt returns an error. If other transformations exist in the source device context (and a matching transformation is not in effect in the destination device context), the rectangle in the destination device context is stretched, compressed, or rotated, as necessary. If the color formats of the source and destination device contexts do not match, the BitBlt function converts the source color format to match the destination format. When an enhanced metafile is being recorded, an error occurs if the source device context identifies an enhanced-metafile device context. Not all devices support the BitBlt function. For more information, see the RC_BITBLT raster capability entry in the GetDeviceCaps function as well as the following functions: MaskBlt, PlgBlt, and StretchBlt. BitBlt returns an error if the source and destination device contexts represent different devices. To transfer data between DCs for different devices, convert the memory bitmap to a DIB by calling GetDIBits. To display the DIB to the second device, call SetDIBits or StretchDIBits.

DeleteObject function

The DeleteObject function is used to delete a GDI object like pen, brush, font, bitmap, region, or palette. It takes the handle of the resource and frees all system resources associated with the object and returns true (non zero). A value of false (0) will be returned when handle is not valid or some other issues happens.

BOOL DeleteObject(
  HGDIOBJ ho
);

DeleteDC function

The DeleteDC function deletes the specified device context (DC) and returns true on success.

BOOL DeleteDC(
  HDC hdc
);

Displaying Bitmap in VC++

Loading steps

  • Call LoadBitmap() with the bitmap file string name present in resource.
  • Create a new memory device context which is compatible to current Window DC using CreateCompatibleDC.
  • Select this bitmap to this newly created memory device context using SelectObject().
  • Copy bits from source of new device context to window device context using BitBlt().
  • Free bitmap resource using DeleteObject()
  • Free this new memory DC by calling DeleteDC()

Displaying Bitmap using C & Win32

#include <windows.h>

#define BMP_WIDTH 100
#define BMP_HEIGHT 40

HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND hWnd,
                         UINT message, 
                         WPARAM wParam,
                         LPARAM lParam);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
  WNDCLASS wc;
  MSG msg;
  HWND hWnd;
  ZeroMemory(&wc, sizeof(WNDCLASS));
  hInst = hInstance;
  wc.style           = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc     = (WNDPROC)WndProc;
  wc.hInstance       = hInstance;
  wc.hCursor         = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground   = (HBRUSH)(COLOR_BACKGROUND);
  wc.lpszClassName   = (LPCTSTR)"MyWin32Class";


  RegisterClass(&wc);

   hWnd = CreateWindow("MyBitmapWnd", "Bitmap loading demo!!", WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);
  while (GetMessage(&msg, NULL, 0, 0)) 
  {
    DispatchMessage(&msg);
  }
  return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  PAINTSTRUCT ps;
  HDC hdc, hmemdc;
  HBITMAP hbitmap;
  switch (message) 
  {
    case WM_PAINT:
    {
      hdc = BeginPaint(hWnd, &ps);
      GetClientRect(hWnd, &rt);
      hbitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAPLOGO));
      hmemdc = CreateCompatibleDC(hdc);
      SelectObject(hmemdc, hbitmap);
      BitBlt(hdc, (rt.right - rt.left)/2  - BMP_WIDTH/2,
            (rt.bottom - rt.top)/2  - BMP_HEIGHT/2,
             BMP_WIDTH, BMP_HEIGHT, hmemdc, 0, 0, SRCCOPY);
      DeleteObject(bitmap);
      DeleteDC(memdc);
      EndPaint(hWnd, &ps);
      break;
    }
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

Displaying Bitmap using C & Win32

LoadBitmap example demo application

About our authors: Team EQA

Further readings

Where is WinMain() function in MFC application ?

MFC hides WinMain in its framework and includes source file on WinMain(). This explains how framework calls global CWinApp::Initinstance() from entry WinMain.

What is the utility of CWinApp class?

This is constructed during global C++ objects are constructed and is already available when Windows calls the WinMain function, which is supplied by the ...

Basic steps in Win32 GUI Application with source code.

Define a custom Window class structure, Register the class name, CreateWindow, Show windows and write message get and dispatch loop statements. Define the Window CallBack procedure and write the handlers.

What is a Window CallBack procedure and what is its utility?

DispatchMessage() is a API which indirectly triggers the Window CallBack procedure. Message structure members from this function are passed to the CallBack procedure. CallBack procedure should implement event handlers depending on the need of the application.

What are LPARAM and WPARAM in window proc function?

LPARAM and WPARAM are the two parameters in Window CallBack procedure. They signifies parameters of various events. They are used in handing individual events.

What are the basic steps of a typical MFC based application?

We need to write WinMain and need to follow all these in a Win32 application. However we need not to write much if we are writing an application with MFC ...

#