J'ai essayé de convertir des images SVG en PNG en utilisant C #, sans avoir à écrire trop de code. Quelqu'un peut-il recommander une bibliothèque ou un exemple de code pour ce faire?
J'ai essayé de convertir des images SVG en PNG en utilisant C #, sans avoir à écrire trop de code. Quelqu'un peut-il recommander une bibliothèque ou un exemple de code pour ce faire?
Réponses:
Vous pouvez appeler la version en ligne de commande d'Inkscape pour ce faire:
http://harriyott.com/2008/05/converting-svg-images-to-png-in-c.aspx
Il existe également un moteur de rendu C # SVG, principalement conçu pour permettre l'utilisation de fichiers SVG sur le Web sur un codeplex qui pourrait répondre à vos besoins si tel est votre problème:
Projet original
http://www.codeplex.com/svg
Fork avec des correctifs et plus d'activité: (ajouté 7/2013)
https://github.com/vvvv/SVG
image
élément n'a pas été implémenté - j'ai vérifié le code source. @FrankHale J'ai dû supprimer un xmlns du svg parce que Raphael l'a ajouté deux fois.
Il existe un moyen beaucoup plus simple d'utiliser la bibliothèque http://svg.codeplex.com/ (version plus récente @ GIT , @ NuGet ). Voici mon code
var byteArray = Encoding.ASCII.GetBytes(svgFileContents);
using (var stream = new MemoryStream(byteArray))
{
var svgDocument = SvgDocument.Open(stream);
var bitmap = svgDocument.Draw();
bitmap.Save(path, ImageFormat.Png);
}
image
élément.
object not set to an instance of an object
quand je veux exécuter var bitmap = svgDocument.Draw();
. quel est le problème?
Quand j'ai dû rastériser des svgs sur le serveur, j'ai fini par utiliser P / Invoke pour appeler les fonctions librsvg (vous pouvez obtenir les dll à partir d'une version Windows du programme d'édition d'images GIMP).
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetDllDirectory(string pathname);
[DllImport("libgobject-2.0-0.dll", SetLastError = true)]
static extern void g_type_init();
[DllImport("librsvg-2-2.dll", SetLastError = true)]
static extern IntPtr rsvg_pixbuf_from_file_at_size(string file_name, int width, int height, out IntPtr error);
[DllImport("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern bool gdk_pixbuf_save(IntPtr pixbuf, string filename, string type, out IntPtr error, __arglist);
public static void RasterizeSvg(string inputFileName, string outputFileName)
{
bool callSuccessful = SetDllDirectory("C:\\Program Files\\GIMP-2.0\\bin");
if (!callSuccessful)
{
throw new Exception("Could not set DLL directory");
}
g_type_init();
IntPtr error;
IntPtr result = rsvg_pixbuf_from_file_at_size(inputFileName, -1, -1, out error);
if (error != IntPtr.Zero)
{
throw new Exception(Marshal.ReadInt32(error).ToString());
}
callSuccessful = gdk_pixbuf_save(result, outputFileName, "png", out error, __arglist(null));
if (!callSuccessful)
{
throw new Exception(error.ToInt32().ToString());
}
}
J'utilise Batik pour cela. Le code Delphi complet:
procedure ExecNewProcess(ProgramName : String; Wait: Boolean);
var
StartInfo : TStartupInfo;
ProcInfo : TProcessInformation;
CreateOK : Boolean;
begin
FillChar(StartInfo, SizeOf(TStartupInfo), #0);
FillChar(ProcInfo, SizeOf(TProcessInformation), #0);
StartInfo.cb := SizeOf(TStartupInfo);
CreateOK := CreateProcess(nil, PChar(ProgramName), nil, nil, False,
CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS,
nil, nil, StartInfo, ProcInfo);
if CreateOK then begin
//may or may not be needed. Usually wait for child processes
if Wait then
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
end else
ShowMessage('Unable to run ' + ProgramName);
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;
procedure ConvertSVGtoPNG(aFilename: String);
const
ExecLine = 'c:\windows\system32\java.exe -jar C:\Apps\batik-1.7\batik-rasterizer.jar ';
begin
ExecNewProcess(ExecLine + aFilename, True);
end;
Batik
s'agit d'une bibliothèque Java que vous pouvez appeler à partir de C # ou de n'importe quel langage (dans ce cas, vous avez montré comment l'appeler en Delphi)
Pour ajouter à la réponse de @Anish, si vous rencontrez des problèmes pour ne pas voir le texte lors de l'exportation du SVG vers une image, vous pouvez créer une fonction récursive pour parcourir les enfants du SVGDocument, essayez de le convertir en SvgText si possible (ajoutez votre propre vérification d'erreur) et définissez la famille et le style de police.
foreach(var child in svgDocument.Children)
{
SetFont(child);
}
public void SetFont(SvgElement element)
{
foreach(var child in element.Children)
{
SetFont(child); //Call this function again with the child, this will loop
//until the element has no more children
}
try
{
var svgText = (SvgText)parent; //try to cast the element as a SvgText
//if it succeeds you can modify the font
svgText.Font = new Font("Arial", 12.0f);
svgText.FontSize = new SvgUnit(12.0f);
}
catch
{
}
}
Faites-moi savoir s'il y a des questions.
vous pouvez utiliser altsoft xml2pdf lib pour cela