Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Printing Static GIF or JPG Image on Delphi

606 views
Skip to first unread message

Emmanuel Lamy

unread,
Aug 27, 2000, 3:00:00 AM8/27/00
to
I am working on a Delphi project where I'll have to use on screen and print
a graphic file that contains the image of realtime "official forms". I am
very attracted by the small footprint on disk and the rendition quality on
screen produced by the GIF files. I could load the GIF file to the Delphi
"Image.picture" property of the container form, using the RxLib's RxGif
unit. But I am breaking my neck trying to extract the bitmap out of the GIF
graphic and send it to printer. I tried the "PrintBitmap" procedure proposed
for Jpeg files on the efg's pages at
http://www.efg2.com/Lab/Library/Delphi/Printing/PrintJPEGTImage.txt. But all
I have got with the GIF image was blank page print outs. I replaced the GIF
files with Jpeg files. But an exception error message popped up at compile
time, saying that the printer is already in use. The project stopped. Can
somebody give me a hand here, please?

Emmanuel Lamy


Finn Tolderlund

unread,
Aug 27, 2000, 3:00:00 AM8/27/00
to

"Emmanuel Lamy" <emma...@gdi.net> skrev i en meddelelse
news:39a946cd$1_2@dnews...

> But I am breaking my neck trying to extract the bitmap out of the GIF
> graphic.

This works for me using Anders Melander's TGIFImage found at
http://www.melander.dk/

function LoadGifToBitmap(const FileName: String; const Bitmap: TBitmap):
Boolean;
{ This function loads a gif picture and converts it to a bitmap.
It is assumed that the bitmap has already been created. }
var
Gif: TGIFImage;
begin
Result := False;
if (AnsiUpperCase(ExtractFileExt(FileName)) = '.GIF') then
begin
Gif := TGIFImage.Create;
try
Gif.LoadFromFile(FileName);
Bitmap.PixelFormat := pf24bit; // avoid palette problems
Bitmap.Width := Gif.Width;
Bitmap.Height := Gif.Height;
Bitmap.Canvas.Draw(0,0, Gif);
Result := True;
finally
Gif.Free;
end;
end;
end;

Finn Tolderlund


Earl F. Glynn

unread,
Aug 27, 2000, 3:00:00 AM8/27/00
to
"Finn Tolderlund" <XnospamYfinn...@Ymobilixnet.dkXnospamY> wrote in message
news:39a9691f_1@dnews...

> This works for me using Anders Melander's TGIFImage found at
> http://www.melander.dk/
>
> function LoadGifToBitmap(const FileName: String; const Bitmap: TBitmap):
> Boolean;
> { This function loads a gif picture and converts it to a bitmap.
> It is assumed that the bitmap has already been created. }
> var
> Gif: TGIFImage;
> begin
> Result := False;
> if (AnsiUpperCase(ExtractFileExt(FileName)) = '.GIF') then
> begin
> Gif := TGIFImage.Create;
> try
> Gif.LoadFromFile(FileName);
> Bitmap.PixelFormat := pf24bit; // avoid palette problems
> Bitmap.Width := Gif.Width;
> Bitmap.Height := Gif.Height;
> Bitmap.Canvas.Draw(0,0, Gif);

I agree with everything to this point. You want to create the TGIFImage and
convert it to a TBitmap. BUT, you want to used StretchDIBits instead
of Draw or StretchDraw to print it -- or you'll just be lucky to get anything
printed on a variety of printers.

For StretchDIBits info, see Item #1 on this page:
http://www.efg2.com/Lab/Library/Delphi/Printing

For some info about Draw, StretchDraw, CopyRect Vs. StretchDIBits:
http://www.efg2.com/Lab/OtherProjects/PrinterDemo1.htm

Sometimes even the free StretchDIBits will not always work. Then you'll
need Joe Hecht's TExcellentImagePrinter
http://www.code4sale.com/joehecht/prndib.htm

--
efg

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

efg's Computer Lab: http://www.efg2.com/Lab

Thérèse Hanquet

unread,
Aug 28, 2000, 3:00:00 AM8/28/00
to
Hi Finn,

Sorry if it's a silly question but why don't you use
Bitmap.Assign(Gif) ? Because of possible palette problems?
I have written a "graphics convertor" (BMP, JPG, GIF) and I use the
same type of code as you but with Assign instead of Draw.

Thérèse

Finn Tolderlund

unread,
Aug 28, 2000, 3:00:00 AM8/28/00
to

"Earl F. Glynn" <Earl...@att.net> skrev i en meddelelse
news:8oc2vr$14...@bornews.borland.com...

> "Finn Tolderlund" <XnospamYfinn...@Ymobilixnet.dkXnospamY> wrote
in message
> news:39a9691f_1@dnews...
>
> > Bitmap.Canvas.Draw(0,0, Gif);
>
> I agree with everything to this point. You want to create the TGIFImage
and
> convert it to a TBitmap. BUT, you want to used StretchDIBits instead
> of Draw or StretchDraw to print it -- or you'll just be lucky to get
anything
> printed on a variety of printers.

I don't understand you.
I am not printing, I am creating a TBitmap.
I see nothing wrong with this.
Please explain more.

Finn Tolderlund


Finn Tolderlund

unread,
Aug 28, 2000, 3:00:00 AM8/28/00
to

"Thérèse Hanquet" <therese...@skynet.be> skrev i en meddelelse
news:39a99233$1_2@dnews...

> Sorry if it's a silly question but why don't you use
> Bitmap.Assign(Gif) ? Because of possible palette problems?

Yes.
I do it that way because I want the TBitmap to have 24 bits per pixel.

Finn Tolderlund


Earl F. Glynn

unread,
Aug 28, 2000, 3:00:00 AM8/28/00
to
"Finn Tolderlund" <XnospamYfinn...@Ymobilixnet.dkXnospamY> wrote in message
news:39a99408$1_1@dnews...

> I don't understand you.
> I am not printing, I am creating a TBitmap.
> I see nothing wrong with this.
> Please explain more.

I am very sorry. I made a mistake. You are quite right.
Please accept my apology.

I saw "printing" in the title and a "draw" method and
had an allergic reaction -- sorry.

Emmanuel Lamy

unread,
Aug 28, 2000, 3:00:00 AM8/28/00
to
I think Earl has brought up a legitimate concern with the printing issue
since my actual problem was to print out the image. I mention about bitmap
just because I wanted to be able to use Earl's "PrintBitmap" procedure that,
if I understand well, is designed to load Jpeg graphic as bitmap and send it
to Printer.canvas. My question to Earl, now, is: Will the GIF image print,
if I replace the code line "Bitmap.Canvas.Draw" with
"Bitmap.Canvas.StretchDIBits"?

"Finn Tolderlund" <XnospamYfinn...@Ymobilixnet.dkXnospamY> wrote in
message news:39a99408$1_1@dnews...
>
> "Earl F. Glynn" <Earl...@att.net> skrev i en meddelelse
> news:8oc2vr$14...@bornews.borland.com...

> > "Finn Tolderlund" <XnospamYfinn...@Ymobilixnet.dkXnospamY>
wrote
> in message
> > news:39a9691f_1@dnews...
> >
> > > Bitmap.Canvas.Draw(0,0, Gif);
> >
> > I agree with everything to this point. You want to create the TGIFImage
> and
> > convert it to a TBitmap. BUT, you want to used StretchDIBits instead
> > of Draw or StretchDraw to print it -- or you'll just be lucky to get
> anything
> > printed on a variety of printers.
>
> I don't understand you.
> I am not printing, I am creating a TBitmap.
> I see nothing wrong with this.
> Please explain more.
>
> Finn Tolderlund
>
>
>

Earl F. Glynn

unread,
Aug 28, 2000, 3:00:00 AM8/28/00
to
"Emmanuel Lamy" <La...@eldatapronet.com> wrote in message news:39aa04e1_1@dnews...

> My question to Earl, now, is: Will the GIF image print,
> if I replace the code line "Bitmap.Canvas.Draw" with
> "Bitmap.Canvas.StretchDIBits"?

Sorry for the confusion. Finn's LoadGifToBitmap used Draw to convert a GIF to a TBitmap. You then
want to take that TBitmap and print it with StretchDBits -- so you
need Draw and StretchDIBits.

Actually, the original example that showed how to print a JPEG in a TImage works fine for a GIF if
you just add USES GIFImage.

Here's a complete example using a GIF:


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, GIFImage,
ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Image1: TImage;
ButtonPrint: TButton;
procedure ButtonPrintClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
{$R *.DFM}

USES
Printers;

// Based on posting to borland.public.delphi.winapi by Rodney E Geraghty, 8/8/97.
// Used to print bitmap on any Windows printer.
PROCEDURE PrintBitmap(Canvas: TCanvas; DestRect: TRect; Bitmap: TBitmap);
VAR
BitmapHeader: pBitmapInfo;
BitmapImage : POINTER;
HeaderSize : DWORD; // Use DWORD for D3-D5 compatibility
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};


FUNCTION CenterText(s: STRING): INTEGER;
BEGIN
RESULT := (Printer.PageWidth - Printer.Canvas.TextWidth(s)) DIV 2
END {CenterText};


PROCEDURE PrintFooterTimeStamp (CONST LeftMargin: INTEGER);
VAR
s: STRING;
BEGIN
// Footer
Printer.Canvas.Font.Name := 'Arial';
Printer.Canvas.Brush.Color := clWhite;
Printer.Canvas.Font.Height :=
MulDiv(GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSY), 8, 72);
s := FormatDateTime('m/d/yy h:nn', Now);
Printer.Canvas.TextOut(LeftMargin,
Printer.PageHeight-Printer.Canvas.TextHeight('X'),
s);
END {PrinterFooterTimeStamp};


////////////////////////////////////////////////////////////////////
//
// Print Bitmap in landscape orientation, with printed image width 80% of page.
//

procedure TForm1.ButtonPrintClick(Sender: TObject);
VAR
Bitmap : TBitmap;
iFromLeftMargin : INTEGER;
iPrintedImageWidth : INTEGER;
jDelta : INTEGER;
jFromTopOfPage : INTEGER;
jPrintedImageHeight: INTEGER;
s : STRING;

begin
Screen.Cursor := crHourGlass;
TRY
Printer.Orientation := poLandscape;
Printer.BeginDoc;
// Header
Printer.Canvas.Font.Height :=
MulDiv(GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSY), 12, 72);
Printer.Canvas.Font.Name := 'Arial';
jDelta := Printer.Canvas.TextHeight('X');
jFromTopOfPage := 3*jDelta;
s := 'Image Title';

Printer.Canvas.TextOut(CenterText(s), jFromTopOfPage, s);
// 5th line from top
jFromTopOfPage := 5*jDelta;

// Image position and size
// 12% left and right margin
iFromLeftMargin := MulDiv(Printer.PageWidth,12,100); // 12%

// Set printed bitmap with to be 76% of paper width
iPrintedImageWidth := MulDiv(Printer.PageWidth,76,100); // 76%
// Set printed bitmap height to maintain aspect ratio
jPrintedImageHeight := Image1.Picture.Height*iPrintedImageWidth DIV
Image1.Picture.Width; // maintain aspect ratio of bitmap

Bitmap := TBitmap.Create;
TRY
Bitmap.Width := Image1.Picture.Width;
Bitmap.Height := Image1.Picture.Height;
Bitmap.PixelFormat := pf24bit;
// Convert JPEG to BMP
Bitmap.Canvas.Draw(0,0, Image1.Picture.Graphic);

// Print Image
PrintBitmap (Printer.Canvas,
Rect(iFromLeftMargin, jFromTopOfPage,
iFromLeftMargin + iPrintedImageWidth,
jFromTopOfPage + jPrintedImageHeight),
Bitmap)
FINALLY
Bitmap.Free
END;

PrintFooterTimeStamp (iFromLeftMargin);

Printer.EndDoc;
FINALLY
Screen.Cursor := crDefault
END;
end;

end.

Note I changed the original Printer.Canvas.Font.Size statements to the more correct way of using
Printer.Canvas.Font.Height with a call to GetDeviceCaps to find out how many dots/inch exist in the
"Y" direction.

Joe C. Hecht

unread,
Aug 28, 2000, 3:00:00 AM8/28/00
to

> I have got with the GIF image was blank page print outs.

-----------------------------------------------------------------------
This solution is brought to you by Joe Hecht's TExcellent products,
solving Form.Print and bitmap printing problems. Joe Hecht's TExcellent
products can be found at: http://www.code4sale.com/joehecht
-----------------------------------------------------------------------

StretchDIBits() requires about 2000 lines of low level
graphics support code to work well, else many of your
customers will recieve blank or garbled pages, and or
system crashes.

TExcellentImagePrinter will reliably print images to any
graphics capable device. Images can be stretched
up to 2 billion pixels high and wide, even split across
multiple pages. TExcellentImagePrinter comes with
many helpfull utilities including a Printer Abort Dialog,
utilities to assist scaling images, deals with uneven
printer margines, and can reliably load images into
DIBs. Special code was added for reliability when
used in a multi-threaded applicaiton.

TExcellentImagePrinter can be found here:

http://www.code4sale.com/joehecht/

Joe

Lord Crc

unread,
Aug 28, 2000, 3:00:00 AM8/28/00
to
On Mon, 28 Aug 2000 17:56:54 -0500, "Joe C. Hecht"
<joeh...@code4sale.com> wrote:

> Images can be stretched up to 2 billion pixels high
> and wide, even split across multiple pages.

Uhm, id like a printer that can print those sqr(2 billion)
pixels on a plain piece of A4 paper ;)

Anyways, im just dead curious, have you actually
tested this on any printers ?

- Asbjørn

0 new messages