Fitting an Image to a Window

To fit an image to a window, you only have to calculate a display rectangle that fits the window's client area, while preserving the image's aspect ratio. The following code snippets from the EZFUNC example program show how this can be done. (This example code includes some palette handling, which is explained more fully in Handling Palette Changes).

Variable declarations:

/* Global declarations */   
RECT rWndSize;   /* RECT for sizing the window. */   
RECT rClientSize;   /* RECT for the client area. */   
RECT rLeadDest;   /* RECT for the destination rectangle for painting. */        
RECT rLeadSource;   /* RECT for the source rectangle for painting. */     
HPALETTE hpalPaint;   /* Paint palette handle. */   
BITMAPHANDLE LeadBitmap;  /* Bitmap handle for the loaded image. */   
L_INT DisplayWidth, DisplayHeight;  /* Dimensions of the displayed image */   
/* Local declarations in the message-processing function */   
PAINTSTRUCT ps; /* Structure for processing the WM_PAINT message */   
HPALETTE hPalette = NULL; /* Temporary copy of the current system palette */   
HDC hdc; /* Device context used with the palette functions */   
int AdjustedWidth, AdjustedHeight; /* Adjusted dimensions of the window */ 

Code that sets the rectangles:

In this snippet from the message-processing function, the bitmap (LeadBitmap) has been loaded, but has not been displayed.

/* Get the current window size and client area */   
GetWindowRect(hWnd, &rWndSize);   
GetClientRect(hWnd,&rClientSize);   
/* Use this user-defined function to fit the displayed image in the client area. */   
CalcDisplay (  rClientSize.right,   /* Width allowed */   
               rClientSize.bottom,  /* Height allowed */   
               BITMAPWIDTH(&LeadBitmap),    /* Width factor, for aspect ratio */   
               BITMAPHEIGHT(&LeadBitmap),   /* Height factor, for aspect ratio */      
               NULL,                /* Resulting left value, not used */   
               NULL,                /* Resulting top value, not used */   
               &DisplayWidth,       /* Resulting width value */   
               &DisplayHeight);     /* Resulting height value */   
/* Adjust the window size to remove blank space at the right or bottom */   
AdjustedWidth = rWndSize.right - rWndSize.left + DisplayWidth - rClientSize.right;   
AdjustedHeight = rWndSize.bottom - rWndSize.top + DisplayHeight - rClientSize.bottom;   
MoveWindow(hWnd, rWndSize.left, rWndSize.top, AdjustedWidth, AdjustedHeight, FALSE);   
/* Get the client area of the adjusted window */   
GetClientRect(hWnd,&rClientSize);   
/* Make the destination rectangle for painting the same as the client area */   
rLeadDest = rClientSize;   
/* Set the source rectangle to use the whole bitmap */   
SetRect(&rLeadSource, 0, 0, LeadBitmap.Width, LeadBitmap.Height); 

Code that paints the image:

case WM_PAINT: 
/* Get the handle to the device context */ 
hdc = BeginPaint (hWnd, &ps); 
if (LeadBitmap.Flags.Allocated)  /* Do we have an image? */ 
{ 
   if (hpalPaint) /* If we have a paint palette, select it */ 
   { 
      hPalette = SelectPalette (hdc, hpalPaint, FALSE); 
      /* Uncomment this if you do not process WM_QUERYNEWPALETTE */ 
      /* RealizePalette (hdc); */ 
   } 
   /* Paint the image */ 
   L_PaintDC (hdc, 
   &LeadBitmap, 
   &rLeadSource,   /* Source rectangle */ 
   NULL,           /* Default source clip area */ 
   &rLeadDest,     /* Destination rectangle */ 
   &ps.rcPaint,    /* Dest clip set by WM_PAINT */ 
   SRCCOPY);       /* Normal Paint */ 
   if (hpalPaint)         /* Return the old palette */ 
      SelectPalette (hdc, hPalette, FALSE); 
} 
EndPaint (hWnd, &ps);     /* Return the DC */ 
return (0); 

Local function for calculating the display rectangle:

Parameters

WidthAllowed

Maximum width.

HeightAllowed

Maximum height.

WidthFactor

For preserving aspect ratio, usually bitmap width.

HeightFactor

For preserving aspect ratio, usually bitmap height.

*ResultLeft

Pass NULL if you do not care about centering. Otherwise, this is updated with the X offset.

*ResultTop

Pass NULL if you do not care about centering. Otherwise, this is updated with the Y offset.

*ResultWidth

Address of the width variable to update.

*ResultHeight

Address of the height variable to update.

Notes: Use this function to fit a displayed image in a particular space, while preserving the aspect ratio.

void CalcDisplay (L_INT WidthAllowed, L_INT HeightAllowed, 
L_INT WidthFactor, L_INT HeightFactor, 
L_INT *ResultLeft, L_INT *ResultTop, 
L_INT *ResultWidth, L_INT *ResultHeight) 
{ 
   /* Local variables for calculating results */ 
   L_INT Left, Top, Width, Height; 
   /* See if using the maximum width will make the image too tall */ 
   if(MulDiv(WidthAllowed, HeightFactor, WidthFactor) < HeightAllowed) 
   { /* Use the maximum width, and calculate the height and top values */ 
      Left = 0; 
      Width = WidthAllowed; 
      Height = MulDiv(Width, HeightFactor, WidthFactor); 
      Top = (HeightAllowed - Height) / 2; 
   } 
   else 
   { /* Use the maximum height, and calculate the width and left values */ 
      Top = 0; 
      Height = HeightAllowed; 
      Width = MulDiv(Height, WidthFactor, HeightFactor); 
      Left = (WidthAllowed - Width) / 2; 
   } 
   /* Update the top and left results, if the caller did not pass NULL */ 
   if (ResultTop != NULL) 
      *ResultTop = Top; 
   if (ResultLeft != NULL) 
      *ResultLeft = Left; 
   /* Update the width and height results */ 
   *ResultWidth = Width; 
   *ResultHeight = Height; 
   return; 
} 

Help Version 20.0.2020.4.3
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2020 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Raster Imaging C API Help