如何使用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
相关产品推荐
相关产品推荐

