在Delphi中使用Skia实现画布SVG路径重绘及窗体缩放自适应?
Skia路径与SVG背景同步缩放解决方案
Skia提供了完整的矩阵变换API,无需自行编写复杂的坐标计算逻辑,就能实现路径与SVG背景的同步缩放。具体实现步骤如下:
- 计算统一缩放比例
当窗体尺寸变化时,先基于SVG原始尺寸与窗体当前尺寸计算缩放比例。如果需要等比缩放,取宽高比的最小值;如果允许拉伸,则直接使用宽高各自的比例:
var SVGOriginalSize: TSize; CurrentClientSize: TSize; ScaleX, ScaleY: Single; begin SVGOriginalSize := GetSVGOriginalDimensions; // 自行实现获取SVG原始宽高的逻辑 CurrentClientSize := Self.ClientSize; // 等比缩放(保持SVG比例不变) ScaleX := CurrentClientSize.Width / SVGOriginalSize.Width; ScaleY := CurrentClientSize.Height / SVGOriginalSize.Height; ScaleX := Min(ScaleX, ScaleY); ScaleY := ScaleX; // 若需拉伸适配(非等比),直接使用各自比例: // ScaleX := CurrentClientSize.Width / SVGOriginalSize.Width; // ScaleY := CurrentClientSize.Height / SVGOriginalSize.Height; end;
- 用Skia矩阵变换路径
使用TSkMatrix创建缩放矩阵,通过TSkPath.Transform方法直接对原始路径进行缩放变换,无需手动修改路径坐标:
var ScaleMatrix: TSkMatrix; OriginalPath: TSkPath; ScaledPath: TSkPath; begin OriginalPath := TSkPath.Create; try // 初始化你的原始路径(比如绘制图形) OriginalPath.AddRect(10, 10, 100, 100); ScaleMatrix := TSkMatrix.CreateScale(ScaleX, ScaleY); ScaledPath := OriginalPath.Transform(ScaleMatrix); // 使用ScaledPath在画布上绘制 Canvas.DrawPath(ScaledPath, Paint); finally OriginalPath.Free; ScaledPath.Free; end; end;
- 同步SVG背景的缩放
绘制SVG背景时,使用完全相同的缩放比例,通过画布的Scale方法实现同步:
var SVGImage: TSkSVG; begin SVGImage := TSkSVG.Create; try SVGImage.LoadFromFile('background.svg'); Canvas.Save; Canvas.Scale(ScaleX, ScaleY); SVGImage.Render(Canvas, SVGImage.ViewBox); Canvas.Restore; finally SVGImage.Free; end; end;
- 额外提示
- 若需要让路径或SVG居中显示,可在缩放后追加平移变换,使用
TSkMatrix.PostTranslate或画布的Translate方法调整位置。 - 确保原始路径的坐标系统与SVG的ViewBox保持一致,避免缩放后出现错位。
- 若需要让路径或SVG居中显示,可在缩放后追加平移变换,使用
内容的提问来源于stack exchange,提问作者Martin Kakhuis
相关产品推荐
相关产品推荐

