119 votes

La conversion SVG en PNG à l'aide de C#

J'ai essayé de convertir SVG images au format PNG à l'aide de C#, sans avoir à écrire trop de code. Quelqu'un peut-il recommander une bibliothèque ou un exemple de code pour faire cela?

91voto

Anish Points 715

Il y a un moyen beaucoup plus facile à l'aide de la bibliothèque http://svg.codeplex.com/. 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);
        }

72voto

Espo Points 24318

Vous pouvez appeler la ligne de commande version de inkscape pour ce faire:

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

Il y a aussi un C# SVG moteur de rendu, principalement conçu pour permettre à des fichiers SVG pour être utilisé sur le web sur le site codeplex qui pourraient répondre à vos besoins si c'est votre problème:

Projet Original
http://www.codeplex.com/svg

Fourche avec les corrections et de plus en plus de l'activité: (ajouté 7/2013)
https://github.com/vvvv/SVG

12voto

nw. Points 1166

Lorsque j'ai eu à pixelliser svgs sur le serveur, j'ai fini à l'aide de P/Invoke pour appeler librsvg fonctions (vous pouvez obtenir les dll à partir d'une version windows de GIMP programme de retouche d'image).

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

8voto

stevenvh Points 1284

Je suis l'aide de Batik pour cela. L'compléter le code 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;

4voto

Michal Kieloch Points 36

Pour ajouter à la réponse de @Anish, si vous rencontrez des problèmes avec pas de voir le texte lors de l'exportation au format SVG pour une image, vous pouvez créer une fonction récursive en boucle par les enfants de la SVGDocument, essayer de la convertir en une SvgText si possible (ajouter votre propre vérification des erreurs) et de définir la police de caractères de la famille et de style.

    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
        {

        }
    }

Laissez-moi savoir si il y a des questions.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X