随笔 - 2146  文章 - 97 评论 - 11761 trackbacks - 253


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;

posted on 2009-12-30 15:51 万一 阅读(...) 评论(...) 编辑 收藏