Ich habe versucht, SVG-Bilder mit C # in PNG zu konvertieren, ohne zu viel Code schreiben zu müssen. Kann jemand eine Bibliothek oder einen Beispielcode dafür empfehlen?
Ich habe versucht, SVG-Bilder mit C # in PNG zu konvertieren, ohne zu viel Code schreiben zu müssen. Kann jemand eine Bibliothek oder einen Beispielcode dafür empfehlen?
Antworten:
Sie können dazu die Befehlszeilenversion von inkscape aufrufen:
http://harriyott.com/2008/05/converting-svg-images-to-png-in-c.aspx
Außerdem gibt es eine C # SVG-Rendering-Engine, die in erster Linie dafür ausgelegt ist, SVG-Dateien im Web auf Codeplex zu verwenden, die Ihren Anforderungen entsprechen könnten, wenn dies Ihr Problem ist:
Originalprojekt
http://www.codeplex.com/svg
Gabel mit Korrekturen und mehr Aktivität: (hinzugefügt 7/2013)
https://github.com/vvvv/SVG
image
Element wurde nicht implementiert - ich habe den Quellcode überprüft. @FrankHale Ich musste eine XML-Datei aus dem SVG entfernen, da Raphael sie zweimal hinzugefügt hat.
Es gibt eine viel einfachere Möglichkeit, die Bibliothek http://svg.codeplex.com/ (neuere Version @ GIT , @ NuGet ) zu verwenden. Hier ist mein 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
Element nicht unterstützt .
object not set to an instance of an object
wenn er ausgeführt werden soll var bitmap = svgDocument.Draw();
. was ist das Problem?
Als ich svgs auf dem Server rastern musste, habe ich P / Invoke verwendet, um librsvg-Funktionen aufzurufen (Sie können die DLLs von einer Windows-Version des GIMP-Bildbearbeitungsprogramms erhalten).
[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());
}
}
Ich benutze Batik dafür. Der vollständige Delphi-Code:
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
es sich um eine Java-Bibliothek handelt, die Sie aus C # oder einer anderen Sprache aufrufen können (in diesem Fall haben Sie gezeigt, wie man sie in Delphi
Um der Antwort von @Anish hinzuzufügen, können Sie eine rekursive Funktion erstellen, um die untergeordneten Elemente des SVGDocument zu durchlaufen, und versuchen, sie in einen SvgText umzuwandeln, wenn Sie Probleme haben, den Text beim Exportieren des SVG in ein Bild nicht zu sehen möglich (fügen Sie Ihre eigene Fehlerprüfung hinzu) und legen Sie die Schriftfamilie und den Schriftstil fest.
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
{
}
}
Lassen Sie mich wissen, wenn es Fragen gibt.
Sie können hierfür die altsoft xml2pdf lib verwenden