2

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

... 
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;
4

1 回答 1

0

我通过将 svg 文件(类似于 XML)加载到 TStringList 解决了这个问题,用新颜色替换了 fill:#000000 和 stroke:#000000,保存到 TMemoryStream,然后使用 TMemoryStream 作为参数创建 TRSVGObject:

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;

接着:

    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;
于 2015-08-19T07:22:34.707 回答