High DPI Images

4/8/2010

All raster-based image files, icons, and cursors, such as BMP, JPEG, and GIF are called images in this context. Because their dimensions are fixed in pixel units, they present unique problems for a DPI-aware application. Although image scaling can stretch images to the correct logical sizes, to take advantage of the high-DPI screen and create a positive customer experience, you should manually recreate high-visibility graphics.

Stretching Images

If the display's DPI is not the same as the DPI for which the image was designed, the image needs to be stretched to display the correct physical size. However, you will need to determine whether the image should be stretched every time it is painted or whether a new bitmap should be created that is stretched only once.

If the bitmap painting code is accessible to you, changing the code to stretch the bitmap when it paints is less memory intensive than stretching the bitmap when it loads. However, if you are using a function or object that does not allow you to scale the bitmap, such as an image list function, you might need to stretch the bitmap when it loads.

To stretch the bitmap when it paints, you can scale it by calling the StretchBlt function instead of the BitBlt function. The following code example assumes the bitmap was authored at 96-dpi dimensions and therefore should be stretched from its native width and height to SCALEX(width) and SCALEY(height).

BITMAP info;
GetObject(bitmap, sizeof(info), (PTSTR) &info);
HDC hdcBitmap = CreateCompatibleDC(target);
SelectObject(hdcBitmap, bitmap);
StretchBlt(target, x, y, SCALEX(info.bmWidth), SCALEY(info.bmHeight),
    hdcBitmap, 0, 0, info.bmWidth, info.bmHeight, SRCCOPY);
DeleteDC(hdcBitmap);

To stretch the bitmap when it loads, you can use the functions HIDPI_StretchBitmap or HIDPI_ImageList_LoadImage provided with the CrosswordSample code sample.

Working with Bitmaps

Because ImageList_LoadImage function assumes no scaling, it has only one parameter, cx, which represents the width of each image in the bitmap on the disk as well as on the screen. Likewise, HIDPI_ImageList_LoadImage has only one cx parameter, which represents the width of each image on the disk. To determine how wide each image should appear on the screen, HIDPI_ImageList_LoadImage uses special fields to identify the DPI resolution for which the bitmaps were authored: the biXPelsPerMeter and biYPelsPerMeter fields in the BITMAPINFO header. HIDPI_ImageList_LoadImage examines these fields and scales the bitmap only if this information is different from the DPI resolution of the screen.

Most graphics editing tools set these fields to 96 DPI by default. It's very important that your high-resolution image lists have them set correctly; otherwise, your bitmaps will be improperly scaled on high-DPI displays

See Also

Concepts

Developing DPI Aware Applications
High DPI Display
Multiple Images
Images in Static Controls