Topic : Bitmaps in MFC
Author : Unknown
Page : << Previous 9  
Go to page :

by calling this function. Next, we draw the highlighted outline of the grayed bitmap using the standard highlighted color:

(Code omitted)

Also, the shadowed outline is drawn on the grayed image in the same way:

(Code omitted)

Finally, some clean up routines. Before this function exits, we call function CBitmap::Detach() to detach HBITMAP type handle fromCBitmap type variable. This is because we want to leave the HBITMAP handle for further use. If we do not detach it, when CBitmap type variable goes out of scope, the destructor will destroy the bitmap automatically, and therefore, the bitmap handle will no longer be valid from then on.

Function CGDIView::LoadBitmap(...) & CGDIView::OnDraw(...)

In the sample, funciton CGDIView::LoadBitmap(...) is changed so that when the user opens a normal color bitmap, the application will automatically convert it to a grayed bitmap image. The original variables that are used to implement image transparency along with the relavant functions are deleted. The only variable remained in class CGDIView are m_bmpDraw, m_dcMem, m_pBmpOld and m_pPalOld:

(Code omitted)

Function CGDIView::OnInitialUpdate(...) and CGDIView::OnCleanUp() are modified in order to conform this change. Also, WM_ERASEBKGND message handler is removed through using Class Wizard.

In function CGDIView::OnLoadBitmap(...), after the palette is created, we call function CGDIView:: CreateGrayedBitamp(...) to create the grayed bitmap and attach the returned handle to variable m_bmpDraw:

(Code omitted)

The bitmap that was originally created by function ::CreateDIBSection(...) is destroyed. Finally, function CGIDView::OnDraw(...) is changed to draw the grayed bitmap to the client window:

(Code omitted)

With the above implementations, the application is able to create grayed images with chiselled effect.


1) Usually an image is stored to disk using DIB format. To display it on a specific type of device, we must first convert it to DDB format, which may be different from device to device.

2) To draw bitmap, we must prepare a memory DC, select the bitmap into it, and copy the image between the memory DC and target DC.

3) Function CDC::BitBlt(...) can be used to draw the image with 1:1 ratio. To draw an image with an enlarged or shrunk size, we need to use function CDC::StretchBlt(...).

4) A DIB contains three parts: 1) Bitmap information header. 2) Color Table. 3) DIB bit values. For the DIB files stored on the disk, there is an extra bitmap file header ahead of DIB data.

5) We can call function ::GetDIBits(...) to get DIB bit values from a DDB selected by a DC, and call function ::SetDIBits(...) to set DIB bit values to the DDB.

6) There are several DIB formats: monochrom format (2 colors), 16-color format, 256-color format, 24-bit format. For each format, the total number of colors contained in the color table is different. The pixels of 24-bit DIB contain explict RGB values, for the rest formats, they contain indices to a color table which resides in the bitmap information header.

7) In order to accelarate bitmap image loading and saving, each raster line of the imge must use multiple of 4 bytes for storing the image data. The extra buffers will simply be wasted if there are not enough image data.

8) The following information contained in the bitmap information header is very important: 1) The dimension of the image (width and height). 2) Bit count per pixel. 3) Image size, which can be calculated from the image dimension and bit cout per pixel.

9) The size of a color table (in number of bytes) can be calculated from the following formula:

for 24-bit format: 0

for other formats that contain color table: (size of structure RGBQUAD) ( 2Bit count per pixel

10) The total image size can be calculated from the following formula:

for 24-bit format:

(size of bitmap information header) + (number of bytes for one raster line) ( image height

for other formats that contain color table:

(size of bitmap information header) + size of color table + (number of bytes for one raster line) ( image height

where number of bytes for on raster line can be calculated as:

(((bit count per pixel) ( (image width) + 31)/32) ( 4

Before preparing DIB, we need the above information to allocate enough buffers for storing DIB data.

11) Function ::SetDIBitsToDevice(...) can be used to draw DIB directly to a device. We don't need to implement any DIB-to-DDB conversion. However, using this function, we also lose the control over DDB.

12) DIB section can be created for managing the image in both DIB and DDB format.

13) Bitmap with transparency can be implemented by using a mask image, and drawing the normal and mask images using bit-wise XOR and AND operation modes.

14) We can convert a color bitmap to a grayed image with chiselled or embossed effect by finding out the outline of the object, then drawing the portion facing the light with highlighted (shadowed) color and the portion facing away from the light with shadowed (highlighted) color.

Page : << Previous 9