Emmanuel Lamy
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
> 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
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
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
Yes.
I do it that way because I want the TBitmap to have 24 bits per pixel.
Finn Tolderlund
> 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.
> 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.
-----------------------------------------------------------------------
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
> 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