Board index » delphi » Printing of Bitmap image ?

Printing of Bitmap image ?

I wish to print a bitmap image direct from a printer unit.

Using the example direct from the Help for Printer (below), I get a nice
clean page - no image at all.

If I put an TImage on a form and copy the ImageRect to PrinterRect
everything is fine but I do not want to have to use a form if at all
possible.

Could somebody please enlighten me as to what needs to be done.

Roy Granich

*****
procedure TForm1.Button1Click(Sender: TObject);

var
  Bmp: TBitmap;
begin
  Bmp := TBitmap.Create;
  try
    Bmp.LoadFromFile('MyBitmap.bmp');
    with Printer do
    begin
      BeginDoc;
      Canvas.Draw((PageWidth - Bmp.Width) div 2,
                  (PageHeight - Bmp.Height) div 2,
                  Bmp);
      EndDoc;
    end;
  finally
    Bmp.Free;
  end;
end;

*******

 

Re:Printing of Bitmap image ?


Quote
Roy Granich <sacomput...@xtra.co.nz> wrote in message news:371EE1C2.2CD8@xtra.co.nz...
> I wish to print a bitmap image direct from a printer unit.

> Using the example direct from the Help for Printer (below), I get a nice
> clean page - no image at all.
>       Canvas.Draw((PageWidth - Bmp.Width) div 2,
>                   (PageHeight - Bmp.Height) div 2,
>                   Bmp);

For reasons I don't understand, most examples in nearly all of the Delphi books say to use Draw or StretchDraw to print a bitmap.
These sources are all wrong.

You will get good results printing bitmaps on a variety of printers only if you use the StretchDIBits API call.  For details of how
to use StretchDIBits, see Item 1, "How can I print a bitmap?" at
www.efg2.com/lab/library/Delphi/Printing

efg
________________________________
efg's Computer Lab:       www.efg2.com/lab
Delphi Books:  www.efg2.com/lab/TechBooks/Delphi.htm

Earl F. Glynn     E-Mail:  EarlGl...@att.net
Overland Park, KS  USA

Re:Printing of Bitmap image ?


use BitBlt to print on printers canvas, it work fine for me.
Quote
Roy Granich wrote:
> I wish to print a bitmap image direct from a printer unit.

> Using the example direct from the Help for Printer (below), I get a nice
> clean page - no image at all.

> If I put an TImage on a form and copy the ImageRect to PrinterRect
> everything is fine but I do not want to have to use a form if at all
> possible.

> Could somebody please enlighten me as to what needs to be done.

> Roy Granich

> *****
> procedure TForm1.Button1Click(Sender: TObject);

> var
>   Bmp: TBitmap;
> begin
>   Bmp := TBitmap.Create;
>   try
>     Bmp.LoadFromFile('MyBitmap.bmp');
>     with Printer do
>     begin
>       BeginDoc;
>       Canvas.Draw((PageWidth - Bmp.Width) div 2,
>                   (PageHeight - Bmp.Height) div 2,
>                   Bmp);
>       EndDoc;
>     end;
>   finally
>     Bmp.Free;
>   end;
> end;

> *******

Re:Printing of Bitmap image ?


Quote
Roy Granich wrote:

> I wish to print a bitmap image direct from a printer unit.

> Using the example direct from the Help for Printer (below), I get a nice
> clean page - no image at all.

I had the exact same problem, and from what I understand Earl is right, you
can't use Draw or BitBlt to copy images from a screen device to a printer
device.

A kind soul gave me a copy of a free library called CDib wich replaces the
Draw method with one that uses StretchDibBits or something in the
background. I get all my bitmaps showing now, and it was very easy to
implement, so if you want I can send it to you.

However, I must admit that although all my bitmaps turn out nicely, my
printer drivers seem to crash from time to time (HP 1120C and HP 1150C)
with some unknown internal Windows error. I still don't know if this is
caused by there still being some bug / incompatibility in the bitmap
drawing routines or if it's just a general problem with Delphi or my
printer drivers...

--
Josef Garvi
Eden Foundation, BP 174, Zinder, Niger Republic
Tel:+227 510601, Fax:+227 510263
E-Mail: jo...@eden-foundation.org
WWW: http://www.eden-foundation.org/

Re:Printing of Bitmap image ?


Quote
darko wrote:

> use BitBlt to print on printers canvas, it work fine for me.

Could you please give me actual coding assuming the file if
'mybitmap.bmp'.

I'm affraid the WinAPI is too intimading for me to follow.

Roy

Re:Printing of Bitmap image ?


Quote
Zsolt wrote:

> >to use StretchDIBits, see Item 1, "How can I print a bitmap?" at
> >www.efg2.com/lab/library/Delphi/Printing

> >efg

> I tried out the PrintBitmap function i found there... bit ihave the
> following problem (i tried it out on several printers and i got the same
> result on all of them)

> if i call the PrintBitmap function like:
> PrintBitmap(Printer.Canvas,Rect(100,100,2000,2000),Bitmap)
> then everything is ok

> but if i do it like
> PrintBitmap(Printer.Canvas,Rect(100,100,3000,3000),Bitmap)
> so i would like to print the bitmap to a bigger destination rectagnle then
> NOTHING is printed and all i get is an empty paper.

> What could be the problem?

1) Windows can only work safely with bitmaps that are:
a) screensize or smaller
b) use less memory than the screensize

2) Windows has a limitation on stetching and shrinking
bitmaps. I forgot exactly what the limts were, but it
was something like 8 times larger and 16 times smaller.

Joe
--
Joe C. Hecht
http://home1.gte.net/joehecht/index.htm

Re:Printing of Bitmap image ?


Quote
>to use StretchDIBits, see Item 1, "How can I print a bitmap?" at
>www.efg2.com/lab/library/Delphi/Printing

>efg

I tried out the PrintBitmap function i found there... bit ihave the
following problem (i tried it out on several printers and i got the same
result on all of them)

if i call the PrintBitmap function like:
PrintBitmap(Printer.Canvas,Rect(100,100,2000,2000),Bitmap)
then everything is ok

but if i do it like
PrintBitmap(Printer.Canvas,Rect(100,100,3000,3000),Bitmap)
so i would like to print the bitmap to a bigger destination rectagnle then
NOTHING is printed and all i get is an empty paper.

What could be the problem?

Re:Printing of Bitmap image ?


Quote
Zsolt <zs...@{*word*104}dude.com> wrote in message

news:7hrde6$bie15@forums.borland.com...

Quote
> but if i do it like
> PrintBitmap(Printer.Canvas,Rect(100,100,3000,3000),Bitmap)
> so i would like to print the bitmap to a bigger destination rectagnle then
> NOTHING is printed and all i get is an empty paper.

Are either of your "3000" values greater than Printer.PageWidth or
Printer.PageHeight?

To be portable across a variety of printers, I would recommend using fractions
of Printer.PageWidth or Printer.PageHeight instead of absolute values.
For example, use something like:

  MulDiv(Printer.PageWidth, 10, 100)   for a "10%" left margin

If you still can't print your bitmap, I'd be willing to take a look at your code
if you can E-mail a small example that demonstrates the problem.

efg
_________________________________
efg's Computer Lab:  http://www.efg2.com/lab
Delphi Books:  http://www.efg2.com/lab/TechBooks/Delphi.htm

Earl F. Glynn     E-Mail:  EarlGl...@att.net
Overland Park, KS  USA

Re:Printing of Bitmap image ?


Quote
> Are either of your "3000" values greater than Printer.PageWidth or
> Printer.PageHeight?

> If you still can't print your bitmap, I'd be willing to take a look at
your code
> if you can E-mail a small example that demonstrates the problem.

So, the code i tried out is attached below. The value of Pagewidth is 4646
and PageHeight is 6738. So, both of them is much greater then the 3000 i
used in the code.

The program contains a form only with one button. After starting the program
i
press the alt-printscreen to copy the form to the clipboard and then press
the
BUTTON on the form.
If i use the PrintBitmap function with 2000,2000 then the bitmap is printed
out
but when i use the 3000,3000 values (like in the code below) then only an
empty paper is printed.
What could be the problem?
Thanx in advance,
Zsolt

PROCEDURE PrintBitmap(Canvas:  TCanvas; DestRect:  TRect;  Bitmap:
TBitmap);
  VAR    BitmapHeader:  pBitmapInfo;    BitmapImage :  POINTER;
    HeaderSize  :  DWORD;    ImageSize   :  DWORD;
BEGIN
  GetDIBSizes(Bitmap.Handle, HeaderSize, ImageSize);
  GetMem(BitmapHeader, HeaderSize);
  GetMem(BitmapImage,  ImageSize);
  TRY
    GetDIB(Bitmap.Handle, Bitmap.Palette, BitmapHeader^, BitmapImage^);
    StretchDIBits(Canvas.Handle,
                  DestRect.Left, DestRect.Top,     // Destination Origin
                  DestRect.Right  - DestRect.Left, // Destination Width
                  DestRect.Bottom - DestRect.Top,  // Destination Height
                  0, 0,                            // Source Origin
                  Bitmap.Width, Bitmap.Height,     // Source Width & Height
                  BitmapImage,                  TBitmapInfo(BitmapHeader^),
                  DIB_RGB_COLORS,                  SRCCOPY)
   FINALLY
    FreeMem(BitmapHeader);    FreeMem(BitmapImage)
   END
  END {PrintBitmap};

procedure TForm1.Button1Click(Sender: TObject);
var
 Bitmap:TBitmap;
 i:Integer;
begin
 with Printer do
  begin
   BeginDoc;
   Bitmap:=TBitmap.Create;
   if Clipboard.HasFormat(CF_BITMAP) then
    begin
     Bitmap.Assign(ClipBoard);
     PrintBitmap(Canvas, Rect(200,200,3000,3000),Bitmap);
    end
   else
    MessageDlg('Clipboard is empty',mtError,[mbOk],0);
   Bitmap.Free;
   EndDoc;
  end;
end;

Re:Printing of Bitmap image ?


Makrai:

Sorry for the slow response.  I sometimes get backlogged on my E-mail replies.

Quote
> So, the code i tried out is attached below. The value of Pagewidth is 4646
> and PageHeight is 6738. So, both of them is much greater then the 3000 i
> used in the code.

> The program contains a form only with one button. After starting the program
> i
> press the alt-printscreen to copy the form to the clipboard and then press
> the
> BUTTON on the form.
> If i use the PrintBitmap function with 2000,2000 then the bitmap is printed
> out
> but when i use the 3000,3000 values (like in the code below) then only an
> empty paper is printed.
> What could be the problem?

You will get a blank sheet of paper (on some printers) because you did a
BeginDoc .. EndDoc.  See how I changed the order of your statements to
avoid this below.

Also, your code works fine with a 720 DPI Epson Stylus with a value
of 5000.    Note the use of the Assert statement to verify assumptions.

In general, and especially with printers, hard coding values like 3000
or 5000 is not a good idea since they can vary so much from printer
to printer.  Use something like MulDiv(Printer.PageWidth, 90, 100)
to get the 90% point for the right margin -- instead of 3000 or 5000.

  USES
    Printers,
    ClipBrd;

<snip>

procedure TForm1.Button1Click(Sender: TObject);
  var
    Bitmap:TBitmap;
begin
  if   Clipboard.HasFormat(CF_BITMAP)
  then begin
    with Printer do
    begin
      BeginDoc;
        Bitmap:=TBitmap.Create;
        TRY
          Bitmap.Assign(ClipBoard);
          ASSERT (Printer.PageWidth >= 5000, 'PageWidth < 5000');
          PrintBitmap(Canvas, Rect(200,200,5000,5000),Bitmap);
        FINALLY
         Bitmap.Free;
        END;
      EndDoc;
    end
  end
  else MessageDlg('Clipboard is empty',mtError,[mbOk],0);
end;

I hope this helps.

efg
_________________________________
efg's Computer Lab:  http://www.efg2.com/lab
Delphi Books:  http://www.efg2.com/lab/TechBooks/Delphi.htm

Earl F. Glynn     E-Mail:  EarlGl...@att.net
Overland Park, KS  USA

Other Threads