You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Skia4Delphi将TGS帧导出为PNG格式?

使用Skia4Delphi将TGS动画转换为PNG帧序列

完全可以实现TGS到PNG帧序列的转换,核心是利用Skia4Delphi对Lottie动画(TGS基于Lottie)的解析能力,逐帧渲染并导出。以下是两种可行的实现方案:

方案一:基于TSkAnimatedImage实现

如果已经在项目中使用了TSkAnimatedImage,可以直接复用该组件的动画解析能力:

procedure ConvertTGStoPNGFrames(const ATGSPath, AOutputDir: string);
var
  AnimatedImage: TSkAnimatedImage;
  SkBitmap: TSkBitmap;
  FrameIndex: Integer;
  OutputPath: string;
begin
  AnimatedImage := TSkAnimatedImage.Create(nil);
  try
    // 加载目标TGS文件
    AnimatedImage.LoadFromFile(ATGSPath);
    // 初始化动画到第一帧
    AnimatedImage.Animation.Seek(0);

    // 创建输出目录(不存在则自动创建)
    if not DirectoryExists(AOutputDir) then
      ForceDirectories(AOutputDir);

    // 遍历所有帧
    for FrameIndex := 0 to AnimatedImage.Animation.FrameCount - 1 do
    begin
      // 定位到当前帧
      AnimatedImage.Animation.SeekFrame(FrameIndex);
      // 创建与动画尺寸匹配的Bitmap
      SkBitmap := TSkBitmap.Create(AnimatedImage.Width, AnimatedImage.Height);
      try
        // 清空画布(保留透明通道)
        SkBitmap.Canvas.Clear(TAlphaColors.Null);
        // 将当前帧绘制到Bitmap
        AnimatedImage.Picture.Draw(SkBitmap.Canvas, RectF(0, 0, AnimatedImage.Width, AnimatedImage.Height));
        // 生成带序号的输出文件名
        OutputPath := IncludeTrailingPathDelimiter(AOutputDir) + Format('frame_%04d.png', [FrameIndex]);
        // 导出为PNG格式
        SkBitmap.EncodeToFile(OutputPath, TSkEncodedImageFormat.PNG);
      finally
        SkBitmap.Free;
      end;
    end;
  finally
    AnimatedImage.Free;
  end;
end;

方案二:直接基于TSkPicture和TSkAnimation实现

如果不需要在界面显示动画,可以直接用TSkPicture加载TGS,结合TSkAnimation处理帧:

procedure ConvertTGStoPNGFrames(const ATGSPath, AOutputDir: string);
var
  SkPicture: TSkPicture;
  SkAnimation: TSkAnimation;
  SkBitmap: TSkBitmap;
  FrameIndex: Integer;
  OutputPath: string;
  AnimationRect: TRectF;
begin
  SkPicture := TSkPicture.Create;
  try
    // 加载TGS文件到SkPicture
    SkPicture.LoadFromFile(ATGSPath);
    // 创建动画控制器
    SkAnimation := TSkAnimation.Create(SkPicture);
    try
      // 初始化动画
      SkAnimation.Seek(0);
      // 获取动画的实际尺寸
      AnimationRect := SkPicture.CullRect;

      if not DirectoryExists(AOutputDir) then
        ForceDirectories(AOutputDir);

      for FrameIndex := 0 to SkAnimation.FrameCount - 1 do
      begin
        // 定位到目标帧
        SkAnimation.SeekFrame(FrameIndex);
        // 创建匹配尺寸的Bitmap
        SkBitmap := TSkBitmap.Create(Round(AnimationRect.Width), Round(AnimationRect.Height));
        try
          SkBitmap.Canvas.Clear(TAlphaColors.Null);
          // 绘制当前帧到Bitmap
          SkAnimation.Draw(SkBitmap.Canvas, AnimationRect);
          OutputPath := IncludeTrailingPathDelimiter(AOutputDir) + Format('frame_%04d.png', [FrameIndex]);
          SkBitmap.EncodeToFile(OutputPath, TSkEncodedImageFormat.PNG);
        finally
          SkBitmap.Free;
        end;
      end;
    finally
      SkAnimation.Free;
    end;
  finally
    SkPicture.Free;
  end;
end;

注意事项

  • 确保使用最新版本的Skia4Delphi,旧版本可能存在TGS解析或帧渲染的bug
  • 如果导出的PNG为空白,检查是否正确调用SeekFrame方法,以及渲染矩形的尺寸是否匹配动画实际大小
  • TGS动画的尺寸可能为浮点数,建议用Round转换为整数避免Bitmap尺寸异常
  • 确保输出目录具备写入权限,否则会导致保存失败

内容的提问来源于stack exchange,提问作者Xel Naga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 17:07:01