Conversione da SVG a PNG utilizzando C # [chiuso]


102

Ho provato a convertire immagini SVG in PNG usando C #, senza dover scrivere troppo codice. Qualcuno può consigliare una libreria o un codice di esempio per farlo?


ho trovato una libreria buona e semplice che puoi usare in c # github.com/ElinamLLC/SharpVectors , può convertire molti tipi di svg in bmp, jpeg o png
Mahdi

2
Posso dire: quelle soluzioni sono pessime, incluse wkhtml2pdf / wkhtml2image ecc. La specifica SVG è complessa e in evoluzione, così come lo sono gli stili CSS e, soprattutto, dovrebbe avere lo stesso aspetto del browser. wkhtml2X, ad esempio, ha enormi problemi con i caratteri e il motore webkit al suo interno è troppo vecchio. Fortunatamente, c'è una soluzione: Chrome ha la modalità headless e con la sua API di debug, puoi ottenere immagini PNG e PDF dallo stesso Headless-Chrome, con MasterDevs / ChromeDevTools in C #: Esempio: github.com/ststeiger/ChromeDevTools / blob / master / source /…
Stefan Steiger,

Risposte:


68

Puoi chiamare la versione a riga di comando di inkscape per fare questo:

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

Inoltre è disponibile un motore di rendering SVG C #, progettato principalmente per consentire l'utilizzo di file SVG sul Web su codeplex che potrebbe soddisfare le tue esigenze se questo è il tuo problema:

Progetto originale
http://www.codeplex.com/svg

Fork con correzioni e più attività: (aggiunto 7/2013)
https://github.com/vvvv/SVG


39
Grazie Espo. In realtà ho scritto quel post sul blog di Inkscape! Sebbene "funzioni", non è una soluzione particolarmente robusta. Però mi piace il progetto codeplex - lo darò un'occhiata. Grazie.
harriyott

9
Che imbarazzo :) Meno male che forse il motore di rendering SVG potrebbe aiutarti.
Espo

20
Lo prendo come un complimento. Non sono mai stato citato da me stesso prima!
harriyott

hai provato il motore di rendering SVG? puoi condividere la tua soluzione per favore. Sto cercando di farlo funzionare ma ho problemi, vedi qui
Armance

1
Ho provato github.com/vvvv/SVG e funziona ma con alcune limitazioni. L' imageelemento non è stato implementato: ho controllato il codice sorgente. @FrankHale ho dovuto rimuovere un xmlns dal svg perché Raphael lo ha aggiunto due volte.
fireydude

74

Esiste un modo molto più semplice utilizzando la libreria http://svg.codeplex.com/ (versione più recente @ GIT , @ NuGet ). Ecco il mio codice

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

1
Ho dovuto usare la versione GitHub perché è più aggiornata e anche quella non supporta l' imageelemento.
fireydude

sono usato da questo codice, viene lanciato object not set to an instance of an objectquando si desidera eseguire var bitmap = svgDocument.Draw();. qual è il problema?
Rasool Ghafari

@RasoolGhafari assicurati che il tuo svgDocument non sia nullo.
Anish

svgDocument non è nullo. Questo è un qualche tipo di problema interno nella libreria.
Jonathan Allen

@ JonathanAllen, stavo rispondendo al commento di Rasool.
Anish

12

Quando ho dovuto rasterizzare svgs sul server, ho finito per usare P / Invoke per chiamare le funzioni librsvg (puoi ottenere le dll da una versione Windows del programma di modifica delle immagini 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());
    }
}

1
librSVG non è male, ma caratteri / testo non li gestisce correttamente. Invece, dai un'occhiata a headless-chrome, API di debug di chrome e un'API C # per l'API di debug di chrome: github.com/ststeiger/ChromeDevTools/blob/master/source/…
Stefan Steiger

8

Sto usando Batik per questo. Il codice Delphi completo:

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;

@downvoters - Spiega perché hai un voto negativo. Un voto negativo senza una spiegazione ha valore zero.
Stevenvh

4
Immagino che i voti negativi provengano dal testo della domanda che contiene "c #". e la tua proposta è delphi
Denis

non hai votato in basso, ma potresti modificare la tua risposta e chiarire che Batikè una libreria Java che potresti chiamare da C # o qualsiasi linguaggio (in questo caso hai mostrato come chiamarlo in Delphi)
ErrCode

L'avvio di un nuovo processo è lento. Inoltre, quanto correttamente rasterizza il batik? Gli ultimi binari sono difficili da ottenere. Invece di sopportare quella merda, dai un'occhiata a headless-chrome, API di debug di chrome e un'API C # per l'API di debug di chrome: github.com/ststeiger/ChromeDevTools/blob/master/source/… - Per tutti Utenti Java, sono sicuro che ci siano anche API Java attorno all'API di debug di Chrome.
Stefan Steiger

4

Per aggiungere alla risposta di @Anish, se hai problemi con la mancata visualizzazione del testo durante l'esportazione dell'SVG in un'immagine, puoi creare una funzione ricorsiva per scorrere i figli dell'SVGDocument, provare a trasmetterlo a un SvgText se possibile (aggiungi il tuo controllo degli errori) e imposta la famiglia e lo stile dei caratteri.

    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
        {

        }
    }

Fammi sapere se ci sono domande.


parent non è definito in SetFont, dovrebbe essere elemento o rinominare la variabile dell'elemento in parent nella firma della funzione
Norbert Kardos

Anche il carattere ora sembra essere una stringa. Comunque questo è stato un vero toccasana, grazie!
Norbert Kardos

-3

puoi usare altsoft xml2pdf lib per questo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.