TIFF 与 GIF 是多帧图像; GIF 还可以关联时间形成动画.
在编码或解码多帧图像的过程中会用到下面两个常数值:
FrameDimensionPage (用于 TIFF)
FrameDimensionTime (用于 GIF)
GDI+1.0 不能编码 GIF 动画; 但都能解析.
解析 TIFF 多页图像的例子:
uses GdiPlus; procedure TForm1.FormDblClick(Sender: TObject); var Image: IGPImage; Graphics: IGPGraphics; PageCount: Integer; i: Integer; begin Image := TGPImage.Create('C:\GdiPlusImg\MultiFrame.tif'); PageCount := Image.GetFrameCount(FrameDimensionPage); Graphics := TGPGraphics.Create(Handle); for i := 0 to PageCount - 1 do begin Image.SelectActiveFrame(FrameDimensionPage, i); Graphics.DrawImage(Image, 10, 10, Image.Width, Image.Height); Graphics.TranslateTransform(Image.Width + 10, 0); end; end;
解析 GIF 多帧图像的例子:
这是原始 GIF 动画文件(本例是放在 C:\GdiPlusImg\Chicken.gif 使用):
这是解析结果:
uses GdiPlus; procedure TForm1.FormDblClick(Sender: TObject); var Image: IGPImage; Graphics: IGPGraphics; PageCount: Integer; i: Integer; begin Image := TGPImage.Create('C:\GdiPlusImg\Chicken.gif'); PageCount := Image.GetFrameCount(FrameDimensionTime); Graphics := TGPGraphics.Create(Handle); Graphics.Clear($FF000000); for i := 0 to PageCount - 1 do begin Image.SelectActiveFrame(FrameDimensionTime, i); Graphics.DrawImage(Image, 4, 4, Image.Width, Image.Height); Graphics.TranslateTransform(Image.Width + 4, 0); if (i+1) mod 7 = 0 then begin Graphics.TranslateTransform(-Graphics.Transform.OffsetX, Image.Height + 4); end; end; end;
编码 TIFF 多页图像的例子(可用 "Windows 图片和传真查看器" 查看编码效果):
uses GdiPlus; procedure TForm1.Button1Click(Sender: TObject); var Prams: IGPEncoderParameters; Img1,Img2,Img3,Img4: IGPImage; MultiFrameImgPath: string; begin ChDir('C:\GdiPlusImg\'); Img1 := TGPImage.Create('Apple.gif'); Img2 := TGPImage.Create('Bird.bmp'); Img3 := TGPImage.Create('Cereal.gif'); Img4 := TGPImage.Create('Collage.png'); MultiFrameImgPath := 'MultiFrame_Test.tif'; Prams := TGPEncoderParameters.Create; Prams.Add(EncoderSaveFlag, EncoderValueMultiFrame); Img1.Save(MultiFrameImgPath, TGPImageFormat.Tiff, Prams); Prams.Clear; Prams.Add(EncoderSaveFlag, EncoderValueFrameDimensionPage); Img1.SaveAdd(Img2, Prams); Img1.SaveAdd(Img3, Prams); Img1.SaveAdd(Img4, Prams); Prams.Clear; Prams.Add(EncoderSaveFlag, EncoderValueFlush); Img1.SaveAdd(Prams); end;
GDI+ 可以播放 gif 动画吗?
gif 动画数据中还有时间间隔(它可能不一样), 如果能读出每帧的时间间隔就好办了.
下面的代码就把上面 Gif 动画每帧的时间间隔读入到了一个数组:
uses GdiPlus; procedure TForm1.FormDblClick(Sender: TObject); var Image: IGPImage; PropertyItem: IGPPropertyItem; Count: Integer; FrameTimeArr: array of Cardinal; begin Image := TGPImage.Create('C:\GdiPlusImg\Chicken.gif'); { 获取 Gif 动画的时间属性, 这是一个 Cardinal 数组 } PropertyItem := Image.GetPropertyItem(PropertyTagFrameDelay); { 帧总数 } Count := PropertyItem.Length div 4; { 复制到需要的数组 } SetLength(FrameTimeArr, Count); CopyMemory(FrameTimeArr, PropertyItem.Value, PropertyItem.Length); end;