Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

image printing article

Status
Not open for further replies.

markymsofth

Programmer
Jun 6, 2004
26
US
any help making this work with bcb6
taken from here

void __fastcall Tmain_form::print_image_btnClick(TObject *Sender)
{
TPrinter *p = Printer();

// create a memory dc for the image
HDC h_dc = image->Picture->Bitmap->Canvas->Handle;
int bmp_w = image->Picture->Bitmap->Width,
bmp_h = image->Picture->Bitmap->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 (image->Canvas->Handle, RASTERCAPS) & RC_PALETTE)
{
pal = static_cast(malloc (sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256)));
memset (pal, 0, sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256));
pal->palVersion = 0x300;
pal->palNumEntries = ::GetSystemPaletteEntries(image->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:):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 = 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.rgbRed = pal->palPalEntry.peRed;
bmp_info->bmiColors.rgbGreen = pal->palPalEntry.peGreen;
bmp_info->bmiColors.rgbBlue = pal->palPalEntry.peBlue;
}
free (pal);
}

// begin the printing
p->BeginDoc ();

// scale print size
int scale_x, scale_y;
if (p->PageWidth < p->PageHeight)
{
scale_x = p->PageWidth;
scale_y = image->Picture->Height * (p->PageWidth / bmp_w);
}
else
{
scale_x = image->Picture->Width * (p->PageHeight / bmp_h);
scale_y = p->PageHeight;
}

// fix up for print with palette
is_pal_dev = false;
if :):GetDeviceCaps (h_dc, RASTERCAPS) & RC_PALETTE)
{
pal = static_cast(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.peRed = bmp_info->bmiColors.rgbRed;
pal->palPalEntry.peGreen = bmp_info->bmiColors.rgbGreen;
pal->palPalEntry.peBlue = bmp_info->bmiColors.rgbBlue;
}
h_pal = CreatePalette(pal);
free (pal);
h_old_pal = SelectPalette(p->Canvas->Handle, h_pal, false);
is_pal_dev = true;
}

// send the bits to the printer
StretchDIBits(p->Canvas->Handle, 0, 0, scale_x, scale_y,
0, 0, bmp_w, bmp_h, bits,bmp_info, DIB_RGB_COLORS, SRCCOPY);

// end the print
p->EndDoc ();

// clean up
::DeleteObject (h_mem_bmp);
if (is_pal_dev)
{
::SelectObject (p->Canvas->Handle, h_old_pal);
::DeleteObject (h_pal);
}
::GlobalUnlock (bits);
::GlobalFree (h_bits);
::GlobalUnlock (bmp_info);
::GlobalFree (h_bmp_info);
}
 
Hi,

I had a quick go at getting this to run.

1)
The image variable that is referenced should exist or be passed to the function. For my test I had Image1 on the form and changed the name to that.
e.g HDC h_dc = image->Picture->Bitmap->Canvas->Handle;
became
HDC h_dc = Image1->Picture->Bitmap->Canvas->Handle;

2)Static casts should be altered

pal = static_cast(malloc(sizeof(LOGPALETTE)+(sizeof (PALETTEENTRY) * 256)));

becomes

pal = static_cast<LOGPALETTE *>(malloc (sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256)));


BITMAPINFO* bmp_info = static_cast:):GlobalLock (h_bmp_info));

becomes

BITMAPINFO* bmp_info = static_cast<BITMAPINFO*>:):GlobalLock (h_bmp_info));


and
pal = static_cast(malloc (sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256)));

becomes

pal = static_cast<LOGPALETTE *>(malloc (sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256)));


Ok Hope that helped.
/TremorBlue
 
is there any way to modify this code to print
bitmaps at a higher resolution. I have noticed
that the code as written will only print in 8 bit
res. this sucks for most images other than black
white and gray.



tomcruz.net
 
thanks for reply
if your printer driver supports stretchdraw u can use the following to print out. i only have a b/w laser set at 600 dpi so im guessing it will probably work for color.

TRect TheRect;
TheRect= Rect(0,0,2560,1920);
TPrinter *Prntr = Printer();
Prntr->BeginDoc();
Prntr->Canvas->StretchDraw(TheRect,Image1->Picture->Graphic);
Prtr->EndDoc();

supposedly not all printers support this which is why the need for the code above in the

void __fastcall Tmain_form::print_image_btnClick(TObject *Sender)
{


 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top