2015-08-17 85 views
2

我正在繪製矢量圖像從SVG文件到TImage。我想在運行時將所有路徑的顏色更改爲不同的顏色,但只有SVG的第一個路徑纔會更改顏色。 SVG中的所有路徑都具有相同的顏色(黑色 - #000000)。有人知道,如何改變所有路徑的顏色?繪製與開羅,librsvg和德爾福SVG,改變所有路徑的顏色

... 
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; 
+0

我的溶液18.8。 – vnc

+0

你可以請分享下載最新版本的cairo + librsvg的地方,以便我們也可以測試這些代碼嗎? – zig

+1

鏈接在這裏:https://code.google.com/p/delphignomevectorgraphic/source/browse/trunk/?r=4,有二進制和德爾福單位。如果你想使用代碼,你必須定義這兩個指令:{$ Define CAIRO_HAS_RSVG_FUNCTIONS} {$ Define CAIRO_HAS_WIN32_SURFACE} – vnc

回答

0

我通過加載SVG文件解決了這個問題(這是ST像XML)來的TStringList,更換填充:#000000和中風:#000000新的顏色,保存到內存流,然後用內存流創建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;