2008-09-12 16 views
84

Tôi đã cố gắng chuyển đổi hình ảnh SVG thành PNG bằng C#, mà không cần phải viết quá nhiều mã. Bất cứ ai có thể giới thiệu một thư viện hoặc mã ví dụ để làm điều này?Chuyển đổi SVG sang PNG bằng C#

Trả lời

61

Bạn có thể gọi các phiên bản dòng lệnh của Inkscape để làm điều này:

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

Cũng có một động cơ C# SVG rendering, chủ yếu được thiết kế để cho phép các file SVG được sử dụng trên các trang web trên CodePlex mà có thể phù hợp với nhu cầu của bạn nếu đó là vấn đề của bạn: Dự án gốc


http://www.codeplex.com/svg

Fork với các bản sửa lỗi và hoạt động hơn: (thêm 7/2013)
https://github.com/vvvv/SVG

+35

Cảm ơn Espo. Tôi thực sự đã viết bài đăng trên blog inkscape đó! Mặc dù nó "hoạt động", nó không phải là một giải pháp đặc biệt mạnh mẽ. Mặc dù tôi thích dự án codeplex - tôi sẽ cho nó một cái nhìn. Cảm ơn. – harriyott

+7

Làm thế nào đáng xấu hổ :) Điều tốt có thể động cơ SVG rendering có thể giúp bạn ra ngoài mặc dù. – Espo

+17

Tôi coi đó là một lời khen. Tôi đã không được trích dẫn cho bản thân mình trước đây! – harriyott

7

Tôi đang sử dụng Batik cho việc này. Mã Delphi hoàn chỉnh:

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 - Vui lòng giải thích lý do bạn downvote. Một downvote mà không có một lời giải thích có giá trị bằng không. – stevenvh

+2

tôi đoán downvotes đến từ các văn bản câu hỏi có chứa "C#" trong đó. và đề xuất của bạn là delphi – Denis

-1

bạn có thể sử dụng altsoft lib xml2pdf cho điều này

11

Khi tôi đã phải rasterize svgs trên máy chủ, tôi đã kết thúc sử dụng P/Invoke để gọi librsvg chức năng (bạn có thể lấy dlls từ phiên bản cửa sổ của chương trình chỉnh sửa hình ảnh 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

Có một cách dễ dàng hơn nhiều bằng cách sử dụng thư viện http://svg.codeplex.com/ (phiên bản mới hơn @GIT, @NuGet). Đây là mã của tôi

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

Tôi đã phải sử dụng phiên bản github vì nó cập nhật hơn và thậm chí không hỗ trợ phần tử 'image'. – fireydude

+0

Tôi đang sử dụng từ mã này, nó ném 'đối tượng không được thiết lập để một thể hiện của một đối tượng' khi muốn thực hiện' var bitmap = svgDocument.Draw(); '. vấn đề là gì –

+0

@RasoolGhafari đảm bảo svgDocument của bạn không phải là rỗng. – Anish

3

Để thêm vào các phản hồi từ @Anish, nếu bạn đang gặp vấn đề với không nhìn thấy những văn bản khi xuất khẩu SVG tới một hình ảnh, bạn có thể tạo một hàm đệ quy để lặp qua con cái SVGDocument, cố gắng đưa nó vào một SvgText nếu có thể (thêm kiểm tra lỗi của riêng bạn) và thiết lập họ phông chữ và kiểu dáng.

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 
     { 

     } 
    } 

Hãy cho tôi biết nếu có câu hỏi.