Stretching Bitmaps with StretchBlt

StretchBlt adds two parameters to the BitBlt call:

StretchBlt (hdcDest, xDest, yDest, xDestWidth, yDestHeight,

hdcSrc, xSrc, ySrc, xSrcWidth, ySrcHeight, dwROP) ;

Because StretchBlt accepts different width and height parameters for the source and destination rectangles, it allows you to stretch or compress a bitmap in the source device context to fit a larger or smaller area in the destination device context.

Just as BitBlt provides a superset of PatBlt's functionality, StretchBlt expands on BitBlt by allowing you to specify the sizes of the source and destination rectangles separately. As with PatBlt and BitBlt, all coordinates and values in StretchBlt are in logical units. (We've already used StretchBlt in two programs: The BLOWUP1 program in Chapter 4 used the function to copy an area of the display into BLOWUP1's client area; the GRAFMENU program in Chapter 9 used StretchBlt to expand the size of a bitmap for use in a menu.)

StretchBlt also allows you to flip an image vertically or horizontally. If the signs of xSrcWidth and xDestWidth (when converted to device units) are different, then StretchBlt creates a mirror image: Left becomes right, and right becomes left. If ySrcHeight and yDestHeight are different, then StretchBlt turns the image upside down. You can verify this with the BLOWUP1 program by capturing the image starting at the upper right corner (a negative width), the lower left corner (a negative height), or the lower right corner (a negative height and width).

If you've experimented with BLOWUP1, you've probably discovered that StretchBlt can be slow, particularly when it works with a large bitmap. StretchBlt also has some problems related to the inherent difficulties of scaling bitmaps. When expanding a bitmap, StretchBlt must duplicate rows or columns of pixels. If the expansion is not an integral multiple, then the process can result in some distortion of the image.

When shrinking a bitmap, StretchBlt must combine two or more rows or columns of pixels into a single row or column. It does this in one of three ways, depending on the stretching mode attribute in the device context. You can use the SetStretchBltMode function to change this attribute:

SetStretchBltMode (hdc, nMode) ;

The value of nMode can be one of the following:

BLACKONWHITE (default)—If two or more pixels have to be combined into one pixel, StretchBlt performs a logical AND operation on the pixels. The resulting pixel is white only if all the original pixels are white, which in practice means that black pixels predominate over white pixels.

WHITEONBLACK—If two or more pixels have to be combined into one pixel, StretchBlt performs a logical OR operation. The resulting pixel is black only if all the original pixels are black, which means that white pixels predominate.

COLORONCOLOR—StretchBlt simply eliminates rows or columns of pixels without doing any logical combination. This is often the best approach for color bitmaps, because the other two modes can cause color distortions.