|VC++ 6.0 ebook chapter index|
A bitmap is rectangular and has a spatial dimension, which is the width and height of the image in pixels. For example, this grid could represent a very small bitmap that is 9 pixels wide and 6 pixels high or, more concisely, 9 by 6:
By convention, the shorthand dimension of a bitmap is given with the width first. This bitmap has a total of 9 × 6, or 54, pixels. I'll often use the symbols cx and cy to refer to the width and height of a bitmap. The `c' stands for count, so cx and cy are the number of pixels along the x (horizontal) and y (vertical) axes.
We can indicate a particular pixel of the bitmap in terms of x and y coordinates. Generally (but not always, as we'll see), the origin of a bitmap is considered to be the upper left corner of the image, as I've numbered the pixels in the grid. Thus, the pixel at the bottom right corner of this bitmap is at the coordinate (8, 5). This is one less than the width and height of the bitmap because the numbering starts with zero.
The spatial dimensions of a bitmap are often referred to as its resolution, but this is a problematic word. We say that our video displays have a resolution of 640 by 480 but that our laser printers have a resolution of 300 dots per inch. I prefer the latter use of the word—resolution as the number of pixels per metrical unit. Bitmaps could have a resolution in this sense, meaning that some number of pixels in the bitmap correspond to a particular unit of measurement. Regardless, when I use the word resolution, it should be obvious from the context which definition I'm using.
Bitmaps are rectangular but computer memory is linear. Bitmaps are generally
(but not always) stored in memory by rows beginning with the top row of pixels and
ending with the bottom row. (The DIB is one major exception to this rule.) Within each row,
pixels are stored beginning with the leftmost pixel and continuing to the right. It's just like
storing the individual characters of several lines of text.
Color and Bitmaps
Besides having a spatial dimension, bitmaps also have a color dimension. This is the number of bits required for each pixel and is sometimes called the color depth of the bitmap or the bit-count or the number of bits per pixel (bpp). Each pixel in a bitmap has the same number of color bits.
A bitmap with 1 bit per pixel is called a bilevel or bicolor or monochrome bitmap. Each pixel is either a 0 or a 1. A value of 0 could mean black, and a 1 could mean white, but that's not necessarily always the case. Additional colors require more bits per pixel. The number of possible colors is equal to 2bit-count. With 2 bits, you get 4 colors, with 4 bits you get 16 colors, with 8 bits you get 256 colors, with 16 bits you get 65,536 colors, and with 24 bits you get 16,777,216 colors.
How exactly certain combinations of color bits correspond to real and familiar
colors is a question that persistently occupies (and often plagues) the mind of anyone
who works with bitmaps.
Bitmaps can be categorized based on the number of color bits they have; the various bitmap color formats are based on the color capabilities of common video display adapters available throughout the history of Windows. Indeed, one can think of video display memory as comprising a large bitmap—one that we see when we look at our monitors.
The most common video adapters used for Windows 1.0 were the IBM Color Graphics Adapter (CGA) and the Hercules Graphics Card (HGC). The HGC was a monochrome device, and the CGA had to be used in a monochrome graphics mode under Windows. The monochrome bitmap is still quite common (for example, mouse cursors are often monochrome), and monochrome bitmaps have other uses beyond the display of images.
With the introduction of the Enhanced Graphics Adapter (EGA), Windows users got access to 16 colors. Each pixel requires 4 color bits. (The EGA was actually a bit more complex than this, involving a palette of 64 colors from which an application could select any 16 colors, but Windows used the EGA in a simpler manner.) The 16 colors used on the EGA were black, white, two shades of gray, and dark and light versions of red, green, and blue (the three additive primaries), cyan (the combination of blue and green), magenta (the combination of blue and red), and yellow (the combination of red and green). These 16 colors are now regarded as a minimum standard for Windows. Likewise, 16-color bitmaps also still show up in Windows. Most icons use 16-color bitmaps. Simple cartoonlike images can usually be done with these 16 colors.
The color encoding used in 16-color bitmaps is sometimes called IRGB (Intensity-Red-Green-Blue) and actually derives from colors originally used in character modes of the IBM CGA. The four IRGB color bits used for each pixel map to Windows hexadecimal RGB colors as shown in the following table.
|IRGB||RGB Color||Color Name|
The memory in the EGA is organized in four "color planes," which means that the four bits that define the color of each pixel are not consecutive in memory. Instead, the video memory is organized so that all the Intensity bits are together, all the Red bits are together, and so forth. This certainly sounds like some device-dependent peculiarity that a Windows programmer shouldn't need to know anything about, and that is more or less the case. However, these color planes pop up in some API calls, such as GetDeviceCaps and CreateBitmap.
Windows 98 and Microsoft Windows NT require a VGA or higher resolution graphics card. This is the minimum-standard video graphics board that Windows currently accepts.
The original Video Graphics Array was introduced by IBM in 1987 with its PS/2 line of personal computers. It offered a number of different video modes, but the best graphics mode (the one that Windows uses) displays 640 pixels horizontally by 480 pixels vertically with 16 colors. To display 256 colors, the original VGA had to be switched into a 320 by 240 graphics mode, which is an inadequate number of pixels for Windows to work properly.
People often forget about the color limitations of the original VGA board because other hardware manufacturers soon developed "Super-VGA" (or SVGA) adapters that included more video memory and displayed 256 colors and more in the 640-by-480 mode. These are now the standard, and that's a good thing because 16 colors are simply inadequate for the display of real-world images.
A video adapter mode that displays 256 colors uses 8 bits per pixel. However, these 8-bit values do not necessarily correspond to particular colors. Instead, the video board incorporates a "palette lookup table" that allows software to specify how these 8-bit values map to real colors. In Windows, applications do not have direct access to this hardware palette lookup table; instead, Windows reserves 20 of the 256 colors and application programs use the Windows Palette Manager to customize the other 236 colors. I'll have much more to say about this in Chapter 16. The Palette Manager allows applications to display real-world bitmaps on 256-color displays. The 20 colors that Windows reserves are:
|Color Value||RGB Color||Color Name|
In recent years, full-color video adapter boards have become quite common. These use either 16 bits or 24 bits per pixel. Sometimes with 16 bits per pixel, one bit is unused and the other 15 bits are apportioned equally for the red, green, and blue primaries. This allows a total of 32,768 colors with combinations of 32 shades each of red, green, and blue. More commonly, 6 bits are used for green (the color that humans are most sensitive to) and 65,536 colors are available. For the nontechnical PC user who doesn't want to see wacky numbers like 32,768 or 65,536, such video display boards are usually said to be "high color" adapters that provide "thousands of colors."
Moving up to 24 bits per pixel gives us a total of 16,777,216 colors (or "true color" or "millions of colors"). Each pixel uses 3 bytes. This is likely to be the standard for years to come because it approximately represents the limits of human perception and also because it's very convenient.
When you call GetDeviceCaps (such as in the DEVCAPS program in Chapter 5), you can use the BITSPIXEL and PLANES constants to obtain the color organization of the video board. Over the years, these values have been those shown here.
|BITSPIXEL||PLANES||Number of Colors|
|15 or 16||1||32,768 or 65,536|
|24 or 32||1||16,777,216|
These days, you shouldn't encounter monochrome video displays, but your
application shouldn't react adversely if it finds one.
Bitmap Support in GDI
The Windows Graphics Device Interface has supported bitmaps since version 1.0. However, prior to Windows 3.0, the only bitmaps supported under Windows were GDI objects, which are referenced using a bitmap handle. These GDI bitmap objects are monochrome or have the same color organization as a real graphics output device, such as a video display. For example, a bitmap compatible with a 16-color VGA has four color planes. The problem is that these color bitmaps cannot not be saved and used on a graphics output device that has a different color organization, for example one having 8 bits per pixel and capable of rendering 256 colors.
Beginning in Windows 3.0, a new bitmap format was defined, called the device- independent bitmap, or DIB. The DIB includes its own color table that shows how the pixel bits correspond to RGB colors. DIBs can be displayed on any raster output device. The only problem is that the colors of the DIB must often be converted to colors that the device can actually render.
Along with the DIB, Windows 3.0 also introduced the Windows Palette Manager that allows programs to customize colors on 256-color displays. Applications often use the Palette Manager in conjunction with displaying DIBs, as we'll see in Chapter 16.
Microsoft has expanded the definition of the DIB in Windows 95 (and Windows NT 4.0) and again in Windows 98 (and Windows NT 5.0). These enhancements have generally involved something called Image Color Management (ICM) that allows DIBs to more accurately specify the exact colors needed for the image. I'll discuss ICM briefly in Chapter 15.
Despite the vital importance of the DIB, the older GDI bitmap objects still play a strong role when working with bitmaps. Probably the best strategy to mastering the field of bitmaps is to approach the material chronologically, beginning with the GDI bitmap object and the concept of the bit-block transfer.