2008-09-12 214 views
84

我一直在嘗試使用C#將SVG圖像轉換爲PNG,而不必編寫太多的代碼。任何人都可以推薦一個庫或示例代碼來做到這一點?使用C將SVG轉換爲PNG#

回答

61

可以調用Inkscape中的命令行版本要做到這一點:

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

也有一個C#SVG渲染引擎,主要目的是讓SVG文件能夠在CodePlex網站上使用這可能滿足您的需求,如果這是你的問題:

原項目
http://www.codeplex.com/svg

叉修復和更多的活動:(加二千零十三分之七)
https://github.com/vvvv/SVG

+35

謝謝埃斯波。我其實寫了那個inkscape博客文章!雖然它「有效」,但它不是一個特別強大的解決方案。我喜歡codeplex項目 - 我會看看它。謝謝。 – harriyott 2008-09-12 13:16:49

+7

好尷尬:)好東西也許SVG渲染引擎可以幫助你。 – Espo 2008-09-12 13:19:56

+17

我把它當作恭維。我以前沒有被引用過自己! – harriyott 2008-09-12 13:36:27

7

我使用Batik這一點。完整的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; 
-1

可以使用altsoft xml2pdf LIB此

11

當我有柵格化服務器上​​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()); 
    } 
} 
46

有使用庫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); 
} 
3

爲了增加從@Anish響應,如果您有沒有看到導出到SVG圖像時文字的問題,您可以通過孩子創建一個遞歸函數循環SVGDocument,儘可能將其轉換爲SvgText(添加自己的錯誤檢查)並設置字體系列和樣式。

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 
     { 

     } 
    } 

讓我知道是否有問題。