You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用TSVGIconImage导出SVG为位图时如何设置透明区域填充色

问题描述

我使用TSVGImageIcon读取SVG矢量图像,编写了如下函数实现将图像保存为指定尺寸的位图:

function SVG2Bitmap(Imatge: TBytes; x, y: integer): TBytes;
var SVG: TSVGIconImage;
    Stream: TBytesStream;
    Bitmap: TBitmap;
    Resultat: TBytesStream;
    Form: TForm;
begin
  try
    SVG := nil;
    Form := nil;
    Stream := nil;
    Bitmap := nil;
    Resultat := nil;
    Stream := TBytesStream.Create(Imatge);
    Stream.Position := 0;
    Form := TForm.Create(nil);  // 不在Form内挂载的话SVGIconImage会抛出异常
    SVG := TSVGIconImage.Create(Form);
    SVG.Parent := Form;
    SVG.Stretch := True;
    SVG.Proportional := True;
    SVG.LoadFromStream(Stream);
    SVG.Width := x;
    SVG.Height := y;
    Bitmap := TBitmap.Create;
    Bitmap.SetSize(x, y);
    SVG.PaintTo(Bitmap.Canvas, 0, 0); 
    Resultat := TBytesStream.Create;
    Bitmap.SaveToStream(Resultat);
    Result := Resultat.Bytes;
  finally
    if Assigned(SVG) then try SVG.Free except end;
    if Assigned(Form) then try Form.Free except end;
    if Assigned(Bitmap) then try Bitmap.Free except end;
    if Assigned(Stream) then try Stream.Free except end;
    if Assigned(Resultat) then try Resultat.Free except end;
  end;
end;

该代码运行正常,但导出的位图中透明区域会被填充为灰色,我希望将透明区域设置为白色。请问是否有方案可以在导出SVG为位图时直接设置透明区域的填充色,还是需要遍历位图将灰色像素修改为白色?


解决方案

不需要逐像素修改,你只需在绘制SVG到位图前预先填充白色背景即可,实现简单且运行效率更高。
出现灰色透明区域的原因是你创建TBitmap后没有手动初始化画布背景,SVG的透明区域绘制时会直接透底,空白画布导出时就会被默认填充为灰色。

你只需在原有代码的Bitmap.SetSize(x, y);语句之后、SVG.PaintTo调用之前,添加两行背景填充代码即可:

Bitmap.Canvas.Brush.Color := clWhite;
Bitmap.Canvas.FillRect(Rect(0, 0, x, y));

如果编译时提示clWhite或Rect未定义,在单元的uses引用列表中添加Vcl.Graphics即可。

修改后的完整代码

function SVG2Bitmap(Imatge: TBytes; x, y: integer): TBytes;
var SVG: TSVGIconImage;
    Stream: TBytesStream;
    Bitmap: TBitmap;
    Resultat: TBytesStream;
    Form: TForm;
begin
  try
    SVG := nil;
    Form := nil;
    Stream := nil;
    Bitmap := nil;
    Resultat := nil;
    Stream := TBytesStream.Create(Imatge);
    Stream.Position := 0;
    Form := TForm.Create(nil);  // 不在Form内挂载的话SVGIconImage会抛出异常
    SVG := TSVGIconImage.Create(Form);
    SVG.Parent := Form;
    SVG.Stretch := True;
    SVG.Proportional := True;
    SVG.LoadFromStream(Stream);
    SVG.Width := x;
    SVG.Height := y;
    Bitmap := TBitmap.Create;
    Bitmap.SetSize(x, y);
    // 新增代码:预先填充白色背景
    Bitmap.Canvas.Brush.Color := clWhite;
    Bitmap.Canvas.FillRect(Rect(0, 0, x, y));
    SVG.PaintTo(Bitmap.Canvas, 0, 0); 
    Resultat := TBytesStream.Create;
    Bitmap.SaveToStream(Resultat);
    Result := Resultat.Bytes;
  finally
    if Assigned(SVG) then try SVG.Free except end;
    if Assigned(Form) then try Form.Free except end;
    if Assigned(Bitmap) then try Bitmap.Free except end;
    if Assigned(Stream) then try Stream.Free except end;
    if Assigned(Resultat) then try Resultat.Free except end;
  end;
end;

如果你后续需要保留透明通道而不是替换为白色,只需将Bitmap的PixelFormat设置为pf32bit即可,不需要修改其他逻辑。


内容的提问来源于stack exchange,提问作者Marc Guillot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 00:18:03