In the first example, we load three TIFF images into an ImageList control. The sequence is
This example assumes that you previously created the three TIFF files ("test1.tif", "test2.tif", and "test3.tif") and they are all of the same dimensions and pixel depth.
#include <commctrl.h> // Must be linked with comctl32.lib HIMAGELIST Load3tiffs() { imgdes tempimage; TiffData tinfo; int rcode, imgCount, cFlag; // Make sure file exists and get its dimensions rcode = tiffinfo("test1.tif", &tinfo); if(rcode == NO_ERROR) { int width = tinfo.width; int length = tinfo.length; int bitcount = tinfo.vbitcount; HIMAGELIST hIml = 0; cFlag = ILC_COLOR24; // For simplicity always create a 24-bit ImageList // Create an empty image list hIml = ImageList_Create( // Windows function width, // width length, // height cFlag, // creation flag 3, // number of images 0); // amount this list can grow // Allocate space for the image rcode = allocimage(&tempimage, width, length, bitcount); if(rcode == NO_ERROR) { rcode = loadtif("test1.tif", &tempimage); if(rcode == NO_ERROR) ImageList_Add(hIml, tempimage.hBitmap, NULL); // Add first image rcode = loadtif("test2.tif", &tempimage); if(rcode == NO_ERROR) ImageList_Add(hIml, tempimage.hBitmap, NULL); // Add second image rcode = loadtif("test3.tif", &tempimage); if(rcode == NO_ERROR) ImageList_Add(hIml, tempimage.hBitmap, NULL); // Add third image } freeimage(&tempimage); return(hIml); }
This little example is all you need for a simple implementation of a image list if application will run in a 24-bit display mode. When ready to display an image, you can use the Windows ImageList_Draw function and select the image by image_index.
ImageList_Draw(hIml, image_index, hdc, x_position, y_position, ILD_NORMAL);
If, however, the application will not always display in 24-bit display mode then for best quality display you have to consider the type of image loaded and the display mode.
In the next example, a single image is loaded and processed to change the colors. In this case, we have to check the display mode and perhaps perform some color reduction for the best quality display.
#include <commctrl.h> // Must link with comctl32.lib HIMAGELIST hIml = 0; // Handle to image list HPALETTE HPalette; int displayBits; // Build image list command selected void DoBuildImageList(HWND hWnd, char *filnam) // Name of BMP file to add to image list { #define NUM_BITMAPS 4 int rcode, imgCount, cFlag; BITMAPINFOHEADER bdat; // Reserve space for struct imgdes image, timg8; imgdes *iptr; // InitCommonControls(); // May need this // Make sure file exists and get its dimensions rcode = bmpinfo(filnam, &bdat); if(rcode == NO_ERROR) { int bitcount = bdat.biBitCount; int width = (int)bdat.biWidth; int length = (int)bdat.biHeight; BOOL useStdPal; HDC hdc; hdc = GetDC(hWnd); // Get display bits: 4, 8, 24, or 32 displayBits = GetDeviceCaps(hdc, BITSPIXEL); ReleaseDC(hWnd, hdc); if(bitcount >= 16) // Load a 16-, 24-, or 32-bit file into a 24-bit buffer bitcount = 24; // Set buffwidth to 0 to check for allocation of timg8 later image.buffwidth = 0; timg8.buffwidth = 0; // Create image list with bitcount = 8 or 24 cFlag = (bitcount <= 8) ? ILC_COLOR8 : ILC_COLOR24; // Create an empty image list hIml = ImageList_Create( width, // width length, // height cFlag, // creation flags NUM_BITMAPS, // number of images 0); // amount this list can grow // Allocate space for the image rcode = allocimage(&image, width, length, bitcount); // Set flag to use standard halftone palette useStdPal = (bitcount <= 8 && displayBits <= 8); if(useStdPal && rcode == NO_ERROR) { // Allocate temp 8- or 1-bit image rcode = allocimage(&timg8, width, length, bitcount); // Use standard halftone palette for timg8 standard_palette(&timg8); } // Point iptr at image if we don't need timg8, // otherwise point iptr at timg8 iptr = useStdPal ? &timg8 : ℑ if(rcode == NO_ERROR) { // Load the image file(s) and add them to the list rcode = loadbmp(filnam, &image); if(rcode == NO_ERROR) { // Add 1st image // If display mode is 256 or fewer colors, // match image palette to standard palette if(useStdPal) rcode = matchcolorimageex(&image, &timg8, CR_TSDDIFF); ImageList_Add(hIml, iptr->hBitmap, NULL); // Add 2nd image negative(&image, &image); if(useStdPal) rcode = matchcolorimageex(&image, &timg8, CR_TSDDIFF); ImageList_Add(hIml, iptr->hBitmap, NULL); // Add 3rd image flipimage(&image, &image); if(useStdPal) rcode = matchcolorimageex(&image, &timg8, CR_TSDDIFF); ImageList_Add(hIml, iptr->hBitmap, NULL); // Get number of images in list (actually don't do anything with it here) imgCount = ImageList_GetImageCount(hIml); } if(image.buffwidth) freeimage(&image); // Release image buffers if(timg8.buffwidth) freeimage(&timg8); } } if(rcode != NO_ERROR) error_handler(hWnd, rcode); // Handle any errors } // Repaint a portion or all of the window. void DoPaint(HWND hWnd) { PAINTSTRUCT ps; // Holds PAINT info HDC hdc; int rcode = NO_ERROR; hdc = BeginPaint(hWnd, &ps); if(hIml != 0) { // If handle to image list exists... // Get number of images in list int imgno, imgCount = ImageList_GetImageCount(hIml); IMAGEINFO info; int cx, cy, width, length, bitcount; BOOL nRc; BITMAPINFOHEADER far *bmHdr; DIBSECTION dib; BOOL useStdPal; // Get size of an image in the image list ImageList_GetImageInfo(hIml, 0, &info); width = info.rcImage.right - info.rcImage.left; length = info.rcImage.bottom - info.rcImage.top; if(GetObject(info.hbmImage, sizeof(DIBSECTION), &dib) == sizeof(DIBSECTION)) { bmHdr = &dib.dsBmih; bitcount = bmHdr->biBitCount; } // Set flag to use standard halftone palette useStdPal = (bitcount <= 8 && displayBits <= 8); if(useStdPal == TRUE) { // Only necessary with 8-bit display mode if(HPalette) // Delete previous palette object DeletePalette(HPalette); // Retrieve the Windows halftone standard palette HPalette = CreateHalftonePalette(hdc); // Select and realize the palette SelectPalette(hdc, HPalette, 0); RealizePalette(hdc); } cx = 0; cy = 0; for(imgno=0; imgno<imgCount; imgno++) { nRc = ImageList_Draw(hIml, imgno, hdc, cx, cy, ILD_NORMAL); cx += width; } } EndPaint(hWnd, &ps); // Handle any errors if(rcode != NO_ERROR) error_handler(hWnd, rcode); } // Add 256-color standard halftone Window's palette to image->palette and fill in // image->colors. Returns number of colors added to image->palette, 0 or 256. // int standard_palette(imgdes far *image) { PALETTEENTRY pe[256]; HPALETTE hPal; RGBQUAD far *palptr = image->palette; HDC hdc = 0; int j, colorsMax, nColors; if(image->bmh->biBitCount != 8 || image->palette == 0) return(0); // Guard against a non 8-bit image hdc = GetDC(NULL); hPal = CreateHalftonePalette(hdc); // Get Windows halftone standard palette (256) // Retrieve up to 256 colors colorsMax = GetPaletteEntries(hPal, 0, 256, pe); // Convert from the PALETTEENTRY format to RGBQUAD format for(j=0, nColors=0; j<colorsMax; j++, nColors++) { palptr->rgbRed = pe[j].peRed; palptr->rgbGreen = pe[j].peGreen; palptr->rgbBlue = pe[j].peBlue; palptr++; // Update RGB quad pointer } if(hdc) ReleaseDC(NULL, hdc); // Fill in and return the number of palette colors return(image->colors = nColors); }
Victor Image Processing Library homepage | Victor Product Summary | more source code