使用 C# 将 SVG 转换为 PNG

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/58910/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 10:16:57  来源:igfitidea点击:

Converting SVG to PNG using C#

提问by harriyott

I've been trying to convert SVG images to PNG using C#, without having to write too much code. Can anyone recommend a library or example code for doing this?

我一直在尝试使用 C# 将 SVG 图像转换为 PNG,而无需编写太多代码。任何人都可以推荐一个库或示例代码来执行此操作吗?

采纳答案by Espo

You can call the command-line version of inkscape to do this:

您可以调用inkscape的命令行版本来执行此操作:

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

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

Also there is a C# SVG rendering engine, primarily designed to allow SVG files to be used on the web on codeplex that might suit your needs if that is your problem:

还有一个 C# SVG 渲染引擎,主要用于允许在 web 上使用 SVG 文件在 codeplex 上,如果这是您的问题,它可能适合您的需求:

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

原始项目
http://www.codeplex.com/svg

Fork with fixes and more activity:(added 7/2013)
https://github.com/vvvv/SVG

Fork 修复和更多活动:(添加 7/2013)
https://github.com/vvvv/SVG

回答by stevenvh

I'm using Batikfor this. The complete 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;

回答by stevenvh

you can use altsoft xml2pdf lib for this

您可以为此使用 altsoft xml2pdf lib

回答by nw.

When I had to rasterize svgs on the server, I ended up using P/Invoke to call librsvg functions (you can get the dlls from a windows version of the GIMP image editing program).

当我不得不在服务器上光栅化 svgs 时,我最终使用 P/Invoke 来调用 librsvg 函数(您可以从 GIMP 图像编辑程序的 Windows 版本中获取 dll)。

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

回答by Anish

There is a much easier way using the library http://svg.codeplex.com/(Newer version @GIT, @NuGet). Here is my code

使用库http://svg.codeplex.com/(较新版本 @ GIT,@ NuGet)有一种更简单的方法。这是我的代码

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

回答by Michal Kieloch

To add to the response from @Anish, if you are having issues with not seeing the text when exporting the SVG to an image, you can create a recursive function to loop through the children of the SVGDocument, try to cast it to a SvgText if possible (add your own error checking) and set the font family and style.

要添加到@Anish 的响应中,如果您在将 SVG 导出到图像时没有看到文本的问题,您可以创建一个递归函数来循环遍历 SVGDocument 的子项,如果可能(添加您自己的错误检查)并设置字体系列和样式。

    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
        {

        }
    }

Let me know if there are questions.

如果有问题,请告诉我。