gpt4 book ai didi

delphi - 如何使用 Delphi 将 SVG 文件转换为透明的 PNG 文件

转载 作者:行者123 更新时间:2023-12-05 02:26:54 25 4
gpt4 key购买 nike

我想以编程方式将 SVG 文件转换为 PNG 文件。

我正在使用 Delphi 10.3.3 和 Skia4Delphi ,但此代码片段不尊重透明度。它创建黑色背景。

var
LBitmap: TBitmap;
MyPng: TPNGImage;
begin
if opendialog1.Execute then
begin
LBitmap := TBitmap.Create;
try
LBitmap.SetSize(1000,1000);
LBitmap.Transparent := True;

LBitmap.SkiaDraw(
procedure (const ACanvas: ISKCanvas)
var
LSvgBrush: TSkSvgBrush;
begin
LSvgBrush := TSkSvgBrush.Create;
try
LSvgBrush.Source := TFile.ReadAllText(opendialog1.FileName);
LSvgBrush.Render(ACanvas, RectF(0, 0, LBitmap.Width, LBitmap.Height), 1);
finally
LSvgBrush.Free;
end;
end);

if savedialog1.Execute then
begin
MyPng := TPngImage.Create;
try
MyPng.Assign(LBitmap);
MyPng.SaveToFile(savedialog1.FileName);
finally
MyPng.Free;
end;
end;
finally
LBitmap.Free;
end;
end;
end;

最佳答案

您的问题是在 SkiaDraw 之后,将位图保存为 png 格式。这可以在不使用 TPNGImage 的情况下非常简单地完成:

if savedialog1.Execute then
LBitmap.ToSkImage.EncodeToFile(savedialog1.FileName);

但是,在当前版本 (3.4.1) 中存在与 Bitmap.ToSkImage 相关的问题:https://github.com/skia4delphi/skia4delphi/issues/150

另一种解决方案是使用 TPNGImage,但方式不同:

function CreatePNGFromTransparentBitmap(const ABitmap: TBitmap): TPNGImage;
type
TRGB = packed record
B, G, R: Byte;
end;
TRGBAArray = array[0..$effffff] of packed record
B, G, R, A: Byte;
end;
var
X, Y: Integer;
BmpRGBA: ^TRGBAArray;
PngRGB: ^TRGB;
begin
Result := TPNGImage.CreateBlank(COLOR_RGBALPHA, 8, ABitmap.Width , ABitmap.Height);
try
Result.CreateAlpha;
Result.Canvas.CopyMode := cmSrcCopy;
Result.Canvas.Draw(0, 0, ABitmap);
for Y := 0 to Pred(ABitmap.Height) do
begin
BmpRGBA := ABitmap.ScanLine[Y];
PngRGB := Result.ScanLine[Y];
for X := 0 to Pred(ABitmap.Width) do
begin
Result.AlphaScanline[Y][X] := BmpRGBA[X].A;
if ABitmap.AlphaFormat in [afDefined, afPremultiplied] then
begin
if BmpRGBA[X].A <> 0 then
begin
PngRGB^.B := Round(BmpRGBA[X].B / BmpRGBA[X].A * 255);
PngRGB^.R := Round(BmpRGBA[X].R / BmpRGBA[X].A * 255);
PngRGB^.G := Round(BmpRGBA[X].G / BmpRGBA[X].A * 255);
end
else
begin
PngRGB^.B := Round(BmpRGBA[X].B * 255);
PngRGB^.R := Round(BmpRGBA[X].R * 255);
PngRGB^.G := Round(BmpRGBA[X].G * 255);
end;
end;
Inc(PngRGB);
end;
end;
except
Result.Free;
raise;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
LBitmap: TBitmap;
MyPng: TPNGImage;
begin
if opendialog1.Execute then
begin
LBitmap := TBitmap.Create;
try
LBitmap.SetSize(1000, 1000);
LBitmap.SkiaDraw(
procedure (const ACanvas: ISKCanvas)
var
LSvgBrush: TSkSvgBrush;
begin
LSvgBrush := TSkSvgBrush.Create;
try
LSvgBrush.Source := TFile.ReadAllText(opendialog1.FileName);
LSvgBrush.Render(ACanvas, RectF(0, 0, LBitmap.Width, LBitmap.Height), 1);
finally
LSvgBrush.Free;
end;
end);

if savedialog1.Execute then
begin
MyPng := CreatePNGFromTransparentBitmap(LBitmap);
try
MyPng.SaveToFile(savedialog1.FileName);
finally
MyPng.Free;
end;
end;
finally
LBitmap.Free;
end;
end;
end;

关于delphi - 如何使用 Delphi 将 SVG 文件转换为透明的 PNG 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73570699/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com