首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用cairo,librsvg和delphi绘制SVG,改变所有路径的颜色

使用cairo,librsvg和delphi绘制SVG,改变所有路径的颜色
EN

Stack Overflow用户
提问于 2015-08-17 16:07:22
回答 1查看 1.3K关注 0票数 2

我正在绘制矢量图像从SVG文件到TImage。我想在运行时将所有路径的颜色更改为不同的一种颜色,但下面的代码仅更改SVG的第一个路径的颜色。SVG中的所有路径都有相同的颜色(黑色- #000000)。有人知道,如何改变所有路径的颜色?

代码语言:javascript
复制
... 
img1: TImage; // TImage placed on the TForm1
...

procedure TForm1.DrawSVG(const aFileName: TFileName);
var
    wSVGObject:        IRSVGObject;
    wSurface:          IWin32Surface;
    wContext:          ICairoContext;
    wRect:             TRect;
begin
    wSVGObject := TRSVGObject.Create(aFileName);
    // img1 initialization
    wRect.Left := 0;
    wRect.Top := 0;
    wRect.width := img1.width;
    wRect.height := img1.height;
    img1.Canvas.Brush.Color := clWhite;
    img1.Canvas.FillRect(wRect);

    wSurface := TWin32Surface.CreateHDC(img1.Canvas.Handle);
    wContext := TCairoContext.Create(wSurface);
    wContext.Antialias := CAIRO_ANTIALIAS_DEFAULT;

    // try to change color of vector image, but only first path changes color
    wContext.SetSourceRGB(0.5, 0.5, 0.5);
    wContext.Rectangle(wRect.Left, wRect.Top, wRect.width, wRect.height);
    wSurface.Flush;
    wContext.FillPreserve;

    wContext.RenderSVG(wSVGObject);
end;
EN

回答 1

Stack Overflow用户

发布于 2015-08-19 15:22:35

我解决这个问题的方法是将svg文件(像XML一样)加载到TStringList中,用新的颜色替换fill:#000000和stroke:#000000,保存到TMemoryStream中,然后以TMemoryStream为参数创建TRSVGObject:

代码语言:javascript
复制
procedure TForm1.ChangeImageColor(const aMStream: TMemoryStream; const aFileName: TFileName; const aOldColor, aNewColor: TColor);
var
    wStringList:          TStringList;
    wNewColor, wOldColor: string;
const
    cHEX_NUMBERS = 6;
begin
    wOldColor := IntToHex(ColorToRGB(aOldColor), cHEX_NUMBERS);
    wNewColor := IntToHex(ColorToRGB(aNewColor), cHEX_NUMBERS);

    wStringList := TStringList.Create;
    try
        wStringList.LoadFromFile(aFileName);
        wStringList.Text := StringReplace(wStringList.Text, 'fill:#' + wOldColor, 'fill:#' + wNewColor,
        [rfReplaceAll, rfIgnoreCase]);
        wStringList.Text := StringReplace(wStringList.Text, 'stroke:#' + wOldColor, 'stroke:#' + wNewColor,
        [rfReplaceAll, rfIgnoreCase]);

        wStringList.SaveToStream(aMStream);
    finally
        FreeAndNil(wStringList);
    end;
end;

然后:

代码语言:javascript
复制
    wMemStream := TMemoryStream.Create;
    try
        if aOldColor <> aNewColor then
            ChangeImageColor(wMemStream, aFileName, aOldColor, aNewColor)
        else
            wMemStream.LoadFromFile(aFileName);

        wSVGObject := TRSVGObject.Create(wMemStream);
...
...
        // try to change color of vector image, but only first path changes color
        // wContext.SetSourceRGB(0.5, 0.5, 0.5);
        // wContext.Rectangle(wRect.Left, wRect.Top, wRect.width, wRect.height);
        // wSurface.Flush;
        // wContext.FillPreserve;

        wContext.RenderSVG(wSVGObject);
    finally
        FreeAndNil(wMemStream);
    end;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32045470

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档