2015-08-17 4 views
2

Je dessine l'image vectorielle du fichier SVG à TImage. Je veux changer la couleur de tous les chemins en une seule couleur à l'exécution, mais le code suivant change de couleur pour le premier chemin de SVG. Tous les chemins en SVG ont la même couleur (noir - # 000000). Quelqu'un sait, comment changer la couleur de tous les chemins?Dessiner SVG avec cairo, librsvg et delphi, changer les couleurs de tous les chemins

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

Ma solution a ajouté 18,8. – vnc

+0

Pouvez-vous s'il vous plaît partager où télécharger les dernières versions de cairo + librsvg afin que nous puissions également tester ce code? – zig

+1

le lien est ici: https://code.google.com/p/delphignomevectorgraphic/source/browse/trunk/?r=4, il y a des binaires et des unités delphi. Si vous voulez utiliser du code, vous devez définir ces deux directives: {$ Define CAIRO_HAS_RSVG_FUNCTIONS} {$ Define CAIRO_HAS_WIN32_SURFACE} – vnc

Répondre

0

Je résolu ce problème en chargeant le fichier svg (il est st comme XML) à TStringList, remplacé fill: # 000000 et course: # 000000 avec une nouvelle couleur, enregistrée à TMemoryStream puis créer TRSVGObject avec TMemoryStream comme paramètre :

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; 

Et puis:

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;