2008-09-12 56 views
84

He intentado convertir imágenes SVG a PNG usando C#, sin tener que escribir demasiado código. ¿Alguien puede recomendar una biblioteca o código de ejemplo para hacer esto?Convirtiendo SVG a PNG usando C#

Respuesta

61

Puede llamar a la versión de línea de comandos de Inkscape para hacer esto:

http://harriyott.com/2008/05/converting-svg-images-to-png-in-c.aspx

También hay un motor de C# SVG renderizado, diseñado principalmente para permitir que los archivos SVG que se utilizarán en la web en CodePlex que puedan satisfacer mejor sus necesidades si ese es su problema:

proyecto original
http://www.codeplex.com/svg

Tenedor con arreglos y una mayor actividad: (añade 7/2013)
https://github.com/vvvv/SVG

+35

Gracias Espo. ¡De hecho, escribí esa publicación en el blog de Inkscape! Aunque "funciona", no es una solución particularmente robusta. Sin embargo, me gusta el proyecto codeplex. Lo echaré un vistazo. Gracias. – harriyott

+7

Qué embarazoso :) Bueno, tal vez el motor de renderizado SVG podría ayudarte. – Espo

+17

Lo tomo como un cumplido. ¡No me han citado antes! – harriyott

7

estoy usando Batik para esto. El funcionamiento completo de código de Delphi:

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

@downvoters - Explique por qué rechaza. Un downvote sin una explicación tiene valor cero. – stevenvh

+2

Supongo que los votos atrasados ​​provienen del texto de la pregunta que contiene "C#". y tu propuesta es Delphi – Denis

-1

puede utilizar Altsoft lib Xml2PDF para este

11

Cuando tuve que rasterizar svgs en el servidor, que terminé usando P/Invoke para llamar librsvg funciones (se puede obtener el dlls de una versión de Windows del programa de edición de imágenes 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()); 
    } 
} 
46

Hay una manera mucho más fácil el uso de la biblioteca http://svg.codeplex.com/ (versión más reciente GIT @, @NuGet). Aquí está mi código

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); 
} 
+0

Tuve que usar la versión de github porque está más actualizada e incluso eso no admite el elemento 'image'. – fireydude

+0

me utilizan desde este código, arroja 'objeto no establecido a una instancia de un objeto' cuando desea ejecutar' var bitmap = svgDocument.Draw(); '. ¿Cuál es el problema? –

+0

@RasoolGhafari asegúrese de que su svgDocument no sea nulo. – Anish

3

a añadir a la respuesta de @Anish, si usted está teniendo problemas con no ver el texto al exportar el SVG a una imagen, puede crear una función recursiva para recorrer los hijos de SVGDocument, intente convertirlo en un SvgText si es posible (agregue su propia comprobación de errores) y configure la familia de fuentes y el estilo.

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 
     { 

     } 
    } 

Deseo saber si hay preguntas.