如何在Delphi 12.1中用Skia将SVG加载到TBitmap并保留透明度
解决Delphi 12.1 VCL中用Skia加载SVG到TBitmap并保留透明度的问题
你的代码报错“Invalid Bitmap”的核心原因是TBitmap默认没有启用Alpha通道支持,Skia需要带透明通道的位图格式才能正确渲染SVG的透明区域。下面是修正后的可行方案:
关键修正点
- 创建TBitmap时必须指定
pf32bit像素格式,并设置AlphaFormat为afPremultiplied,确保位图支持透明度 - 可以选择更直接的
TSkSvg类加载SVG,比TSkSvgBrush更适合直接渲染场景
方案一:使用TSkSvg直接渲染到TBitmap
uses System.Skia, Vcl.Skia, System.Types, System.IOUtils; function LoadSVGToBitmap(const ASVGFile: string; const AWidth, AHeight: Integer): TBitmap; var LSvg: TSkSvg; begin Result := TBitmap.Create(AWidth, AHeight); try // 配置Bitmap支持Alpha通道 Result.PixelFormat := pf32bit; Result.AlphaFormat := afPremultiplied; LSvg := TSkSvg.Create; try LSvg.LoadFromFile(ASVGFile); // 使用SkiaDraw渲染SVG到Bitmap画布 Result.SkiaDraw( procedure(const ACanvas: ISKCanvas) var LDestRect: TRectF; begin // 计算目标矩形,保持SVG的宽高比(可选,也可以直接拉伸) LDestRect := LSvg.CalculateFitDestinationRect(RectF(0, 0, AWidth, AHeight)); LSvg.Render(ACanvas, LDestRect); end); finally LSvg.Free; end; except Result.Free; raise; end; end;
方案二:修正你的TSkSvgBrush代码
如果坚持用TSkSvgBrush,需要确保Bitmap的格式正确,同时调整渲染逻辑:
uses Vcl.Skia, System.Types, System.IOUtils; procedure LoadSVGWithBrush(const ASVGFile: string; out ABmp: TBitmap); var LSvgBrush: TSkSvgBrush; begin ABmp := TBitmap.Create(100, 100); try ABmp.PixelFormat := pf32bit; ABmp.AlphaFormat := afPremultiplied; ABmp.SkiaDraw( procedure(const ACanvas: ISKCanvas) begin LSvgBrush := TSkSvgBrush.Create; try LSvgBrush.Source := TFile.ReadAllText(ASVGFile); // 用Brush填充整个画布区域 ACanvas.DrawRect(RectF(0, 0, 100, 100), LSvgBrush.BlendMode, LSvgBrush); finally LSvgBrush.Free; end; end); except ABmp.Free; raise; end; end;
注意事项
- 必须确保SVG文件路径正确,且内容是有效的SVG格式
- 如果需要保持SVG的原始比例,使用
CalculateFitDestinationRect方法避免拉伸变形 - 渲染后的TBitmap可以直接赋值给TImage(设置TImage的
Transparent为True,或者用TSkImage控件效果更好)
内容的提问来源于stack exchange,提问作者user1580348
相关产品推荐
相关产品推荐

