zoukankan      html  css  js  c++  java
  • GdiPlus[56]: 图像(八) 关于多帧图像


    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;
    
  • 相关阅读:
    pycharm 安装第三方库报错:AttributeError: 'module' object has no attribute 'main'
    工作冥想
    对于测试工作与测试人员未来出路的思考
    测试计划再谈
    python 反转列表的3种方式
    关于最近练习PYTHON代码的一点心得
    python sum()函数的用法
    python count()函数
    SpringCloud和SpringBoot的详细版本说明
    使用 lntelliJ IDEA 创建 Maven 工程的springboot项目
  • 原文地址:https://www.cnblogs.com/del/p/1636104.html
Copyright © 2011-2022 走看看