Board index » delphi » Printing Static GIF or JPG Image on Delphi

Printing Static GIF or JPG Image on Delphi

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

 

Re:Printing Static GIF or JPG Image on Delphi


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

Quote
> 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

Re:Printing Static GIF or JPG Image on Delphi


Quote
"Finn Tolderlund" <XnospamYfinn.tolderlu...@Ymobilixnet.dkXnospamY> wrote in message

news:39a9691f_1@dnews...

Quote
> 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:  EarlGl...@att.net
Overland Park, KS  USA

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

Re:Printing Static GIF or JPG Image on Delphi


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.

Thrse

Re:Printing Static GIF or JPG Image on Delphi


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

Quote
> "Finn Tolderlund" <XnospamYfinn.tolderlu...@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

Re:Printing Static GIF or JPG Image on Delphi


"Thrse Hanquet" <therese.hanq...@skynet.be> skrev i en meddelelse
news:39a99233$1_2@dnews...

Quote
> 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

Re:Printing Static GIF or JPG Image on Delphi


Quote
"Finn Tolderlund" <XnospamYfinn.tolderlu...@Ymobilixnet.dkXnospamY> wrote in message

news:39a99408$1_1@dnews...

Quote
> 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.

--
efg

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

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

Re:Printing Static GIF or JPG Image on Delphi


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.tolderlu...@Ymobilixnet.dkXnospamY> wrote in
message news:39a99408$1_1@dnews...
Quote

> "Earl F. Glynn" <EarlGl...@att.net> skrev i en meddelelse
> news:8oc2vr$14c5@bornews.borland.com...
> > "Finn Tolderlund" <XnospamYfinn.tolderlu...@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

Re:Printing Static GIF or JPG Image on Delphi


Quote
"Emmanuel Lamy" <L...@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.

--
efg

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

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

Re:Printing Static GIF or JPG Image on Delphi


Quote
> 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

Re:Printing Static GIF or JPG Image on Delphi


On Mon, 28 Aug 2000 17:56:54 -0500, "Joe C. Hecht"

Quote
<joehe...@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

Other Threads