Printing a TBitmap with StretchDIBits
The simple way to print a TBitmap is to use the Draw method of a TPrinter Canvas ThePrinterCanvas->Draw ( PositionX, PositionY, TheBitmap);. This works, except that on many machines this will fail to print (or print out too small). The following code will print the TBitmap at a size that is adjusted for the printer device using StretchDIBits. You could change the scaling and have it print to whatever size you want...
The image must contain a Bitmap. This particular function will only work if it is a Bitmap, icons and cursors will not work.
-
/********************************************************************************************
-
* NAME:
-
* PrintImage
-
* PURPOSE:
-
* Print a bitmap with StretchDIBits
-
* NOTES:
-
* The image must contain a Bitmap. This particular function will only
-
* work if it is a Bitmap, icons and cursors will not work.
-
*
-
* PARAMS: PrinterCanvas : printer canvas (TPrinter->Canvas)
-
* pX : bitmap X position on printer page
-
* pY : bitmap Y position on printer page
-
* TheBitmap: TBitmap to be printed
-
* RETURNS:
-
* void
-
**********************************************************************************************/
-
void __fastcall TForm1::PrintImage(TCanvas *PrinterCanvas,int pX,int pY, Graphics::TBitmap *TheBitmap)
-
{
-
-
// create a memory dc for the image
-
HDC h_dc = TheBitmap->Canvas->Handle;
-
int bmp_w = TheBitmap->Width, bmp_h = TheBitmap->Height;
-
-
HDC h_mem_dc = ::CreateCompatibleDC (h_dc);
-
HBITMAP h_mem_bmp = ::CreateCompatibleBitmap (h_dc, bmp_w, bmp_h);
-
HBITMAP h_old_bmp = ::SelectObject (h_mem_dc, h_mem_bmp);
-
-
// fix up bad video drivers
-
bool is_pal_dev = false;
-
LOGPALETTE *pal;
-
HPALETTE h_pal, h_old_pal;
-
-
if ( ::GetDeviceCaps (TheBitmap->Canvas->Handle, RASTERCAPS) & RC_PALETTE)
-
{
-
pal = static_cast<LOGPALETTE*>(malloc (sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256)));
-
memset (pal, 0, sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256));
-
pal->palVersion = 0x300;
-
pal->palNumEntries = ::GetSystemPaletteEntries(TheBitmap->Canvas->Handle, 0, 256, pal->palPalEntry);
-
if (pal->palNumEntries != 0)
-
{
-
h_pal = ::CreatePalette (pal);
-
h_old_pal = ::SelectPalette (h_mem_dc, h_pal, false);
-
is_pal_dev = true;
-
}
-
else
-
{
-
free (pal);
-
}
-
}
-
-
// copy the image on to the memory dc
-
::BitBlt (h_mem_dc, 0, 0, bmp_w, bmp_h, h_dc, 0, 0, SRCCOPY);
-
-
if (is_pal_dev)
-
{
-
::SelectPalette (h_mem_dc, h_old_pal, false);
-
::DeleteObject (h_pal);
-
}
-
-
// delete the mem dc
-
::SelectObject (h_mem_dc, h_old_bmp);
-
::DeleteDC (h_mem_dc);
-
-
// get memory for a BITMAPIFO Structure
-
HANDLE h_bmp_info = ::GlobalAlloc (GHND, sizeof (BITMAPINFO) + (sizeof (RGBQUAD) * 256));
-
BITMAPINFO* bmp_info = static_cast<BITMAPINFO*>(::GlobalLock (h_bmp_info));
-
//Set up the structure
-
-
memset (bmp_info, NULL, sizeof (BITMAPINFO) + (sizeof (RGBQUAD) * 255));
-
bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-
bmp_info->bmiHeader.biPlanes = 1;
-
bmp_info->bmiHeader.biBitCount = 16;//or 8
-
bmp_info->bmiHeader.biWidth = bmp_w;
-
bmp_info->bmiHeader.biHeight = bmp_h;
-
bmp_info->bmiHeader.biCompression = BI_RGB;
-
-
// find out how much memory for the bits
-
::GetDIBits (h_dc, h_mem_bmp, 0, bmp_h, NULL, bmp_info, DIB_RGB_COLORS);
-
-
// Allocate memory for the bits
-
HANDLE h_bits = GlobalAlloc (GHND, bmp_info->bmiHeader.biSizeImage);
-
void *bits = ::GlobalLock (h_bits);
-
-
// this time get the bits
-
::GetDIBits (h_dc, h_mem_bmp, 0, bmp_h, bits, bmp_info, DIB_RGB_COLORS);
-
-
// fix up for bad video driver
-
if (is_pal_dev)
-
{
-
for (int i = 0; i <pal->palNumEntries; i++)
-
{
-
bmp_info->bmiColors[i].rgbRed = pal->palPalEntry[i].peRed;
-
bmp_info->bmiColors[i].rgbGreen = pal->palPalEntry[i].peGreen;
-
bmp_info->bmiColors[i].rgbBlue = pal->palPalEntry[i].peBlue;
-
}
-
free (pal);
-
}
-
-
-
// fix up for print with palette
-
is_pal_dev = false;
-
if ( ::GetDeviceCaps (h_dc, RASTERCAPS) & RC_PALETTE)
-
{
-
pal = static_cast<LOGPALETTE*>(malloc (sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256)));
-
memset (pal, 0, sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256));
-
pal->palVersion = 0x300;
-
pal->palNumEntries = 256;
-
for (int i = 0; pal->palNumEntries; i++)
-
{
-
pal->palPalEntry[i].peRed = bmp_info->bmiColors[i].rgbRed;
-
pal->palPalEntry[i].peGreen = bmp_info->bmiColors[i].rgbGreen;
-
pal->palPalEntry[i].peBlue = bmp_info->bmiColors[i].rgbBlue;
-
}
-
h_pal = CreatePalette(pal);
-
free (pal);
-
h_old_pal = SelectPalette(PrinterCanvas->Handle, h_pal, false);
-
is_pal_dev = true;
-
}
-
-
-
// adjust bitmap dimensions for the printer device:
-
int PrnXRes= GetDeviceCaps(PrinterCanvas->Handle, LOGPIXELSX); //Get dpi of printer along width
-
int PrnYRes= GetDeviceCaps(PrinterCanvas->Handle, LOGPIXELSY); //Get dpi of printer along height
-
bmp_w= floor(((double)TheBitmap->Width / (double)Screen->PixelsPerInch) * (double)PrnXRes);
-
bmp_h= floor(((double)TheBitmap->Height / (double)Screen->PixelsPerInch) * (double)PrnYRes);
-
-
// send the bits to the printer
-
StretchDIBits(PrinterCanvas->Handle, pX,pY, bmp_w, bmp_h,
-
0, 0, TheBitmap->Width,TheBitmap->Height, bits,bmp_info, DIB_RGB_COLORS, SRCCOPY);
-
-
// clean up
-
::DeleteObject (h_mem_bmp);
-
if (is_pal_dev)
-
{
-
::SelectObject (PrinterCanvas->Handle, h_old_pal);
-
::DeleteObject (h_pal);
-
}
-
::GlobalUnlock (bits);
-
::GlobalFree (h_bits);
-
::GlobalUnlock (bmp_info);
-
::GlobalFree (h_bmp_info);
-
}
related things:
Author: Raz | On February 2nd, 2007 | C++ Builder, [ En ] | No Comments
Q: So what can I do next?
A: You can Buy me a Beer or Coffee. You can say Hi! or peek on the related stuff. You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.
Spammers: Beware of » my Dog! «




