// Robert Poyntz, rpoyntz@vaneyk.com.au // // Assumes TGIFImage is installed: http://www.melander.dk/delphi/gifimage // // September 2000 unit GraphicUtils; interface uses SysUtils, Windows, Graphics, Classes; Procedure SpecialGIF(ABitmap: TBitmap; Const ARes: Integer; Const AFileName: String); implementation Uses GIFImage; // Assumes TGIFImage is installed: Procedure SpecialGIF(ABitmap: TBitmap; Const ARes: Integer; Const AFileName: String); Const HeaderOffset = $36; PixelFormats : Array[1..6] of Integer = (1, 4, 8, 15, 16, 24); Var FileHeader: TBitmapFileHeader; InfoHeader: TBitmapInfo; ImageSize: Integer; BMP: TBitmap; GIF: TGIFImage; SourceStream: TMemoryStream; DestStream: TMemoryStream; AlignBytes: Integer; Begin If not(ABitmap.PixelFormat in [pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit]) then Raise Exception.Create('Cannot process this bitmap type'); // Bitmap rows need to be word aligned, hence the need for the AlignBytes variable AlignBytes := ABitmap.Width mod 2; // Calculate the size of the bitmap image data ImageSize := (ABitmap.Height * ABitmap.Width) + (ABitmap.Height * AlignBytes); // Set up the bitmap file header FileHeader.bfType := $4d42; FileHeader.bfSize := SizeOf(TBitmapInfoHeader) + SizeOf(TBitmapInfo) + ImageSize; FileHeader.bfReserved1 := 0; FileHeader.bfReserved2 := 0; FileHeader.bfOffBits := SizeOf(TBitmapFileHeader) + SizeOf(TBitmapInfo); // Now set up the bitmap info header InfoHeader.bmiHeader.biSize := SizeOf(TBitmapInfoHeader); InfoHeader.bmiHeader.biWidth := ABitmap.Width; InfoHeader.bmiHeader.biHeight := ABitmap.Height; InfoHeader.bmiHeader.biPlanes := 1; InfoHeader.bmiHeader.biBitCount := PixelFormats[Ord(ABitmap.PixelFormat)]; InfoHeader.bmiHeader.biCompression := BI_RGB; InfoHeader.bmiHeader.biSizeImage := 0; InfoHeader.bmiHeader.biXPelsPerMeter := ARes; InfoHeader.bmiHeader.biYPelsPerMeter := ARes; InfoHeader.bmiHeader.biClrUsed := 0; InfoHeader.bmiHeader.biClrImportant := 0; SourceStream := TMemoryStream.Create; Try ABitmap.SaveToStream(SourceStream); DestStream := TMemoryStream.Create; Try DestStream.Write(FileHeader, SizeOf(FileHeader)); DestStream.Write(InfoHeader.bmiHeader, SizeOf(InfoHeader.bmiHeader)); SourceStream.Position := HeaderOffset; DestStream.CopyFrom(SourceStream, SourceStream.Size - HeaderOffset); BMP := TBitmap.Create; Try DestStream.Position := 0; BMP.LoadFromStream(DestStream); GIF := TGIFImage.Create; Try GIF.Assign(BMP); GIF.OptimizeColorMap; GIF.SaveToFile(AFileName); Finally GIF.Free; End; Finally BMP.Free; End; Finally DestStream.Free; End; Finally SourceStream.Free; End; End; end.