简体   繁体   English

如何使用 Delphi 将 SVG 文件转换为具有透明度的 PNG 文件

[英]How to convert SVG file to PNG file with transparency using Delphi

I want to convert a SVG file to PNG file programmatically.我想以编程方式将 SVG 文件转换为 PNG 文件。

I'm using Delphi 10.3.3 with Skia4Delphi , but this code snippet doesn't respect transparency.我使用 Delphi 10.3.3 和Skia4Delphi ,但这个代码片段不尊重透明度。 It creates black background.它创建黑色背景。

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;

Your problem is after SkiaDraw, save the bitmap in png format.您的问题是在 SkiaDraw 之后,将 bitmap 保存为 png 格式。 This could be done very simply without using TPNGImage:这可以非常简单地完成,无需使用 TPNGImage:

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

However, in the current version (3.4.1) there is an issue related to Bitmap.ToSkImage: https://github.com/skia4delphi/skia4delphi/issues/150但是,在当前版本(3.4.1)中存在与 Bitmap.ToSkImage: https://github.com/skia4delphi/skia4delphi/issues/150相关的问题

Another solution would be to use TPNGImage, but in a different way:另一种解决方案是使用 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM