Chuyển đổi SVG sang PNG bằng C # [đã đóng]


102

Tôi đã cố gắng chuyển đổi ảnh SVG sang 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?


Tôi đã tìm thấy một thư viện tốt và đơn giản mà bạn có thể sử dụng trong c # github.com/ElinamLLC/SharpVectors , nó có thể chuyển đổi nhiều loại svg sang bmp, jpeg hoặc png
Mahdi

2
Tôi có thể nói: những giải pháp đó không tốt, bao gồm wkhtml2pdf / wkhtml2image, v.v. Đặc điểm kỹ thuật SVG rất phức tạp và đang phát triển, kiểu CSS cũng vậy, và trên hết, nó phải trông giống như trong trình duyệt. Ví dụ: wkhtml2X gặp vấn đề lớn với phông chữ và công cụ webkit bên trong quá cũ. May mắn thay, có một giải pháp: Chrome có chế độ không đầu và với API gỡ lỗi của nó, bạn có thể lấy hình ảnh PNG và PDF từ chính Chrome không có đầu, với MasterDevs / ChromeDevTools trong C #: Ví dụ: github.com/ststeiger/ChromeDevTools / blob / master / source /…
Stefan Steiger

Câu trả lời:


68

Bạn có thể gọi phiên bản dòng lệnh của inkscape để thực hiện việc này:

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

Ngoài ra, có một công cụ kết xuất C # SVG, được thiết kế chủ yếu để cho phép các tệp SVG được sử dụng trên web trên codeplex 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 khác: (thêm 7/2013)
https://github.com/vvvv/SVG


39
Cảm ơn Espo. Tôi thực sự đã viết bài đăng 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ù vậy, tôi thích dự án codeplex - Tôi sẽ cho nó một cái nhìn. Cảm ơn.
harriyott 12/09/08

9
Thật đáng xấu hổ :) Tuy nhiên, điều tốt có lẽ công cụ kết xuất SVG có thể giúp bạn.
Espo

20
Tôi coi đó là một lời khen. Tôi đã không được trích dẫn cho chính mình trước đây!
harriyott 12/09/08

bạn đã thử công cụ kết xuất svg chưa? u có thể chia sẻ giải pháp ur plz. Tôi đang cố gắng làm cho nó hoạt động nhưng gặp sự cố, hãy xem ở đây
Armance

1
Tôi đã thử github.com/vvvv/SVG và nó hoạt động nhưng có một số hạn chế nhất định. Phần imagetử chưa được triển khai - Tôi đã kiểm tra mã nguồn. @FrankHale Tôi đã phải xóa xmlns khỏi svg vì raphael đã thêm nó hai lần.
fireydude

74

Có một cách dễ dàng hơn nhiều là 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);
}

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

Tôi được sử dụng từ mã này, nó ném object not set to an instance of an objectkhi muốn thực thi var bitmap = svgDocument.Draw();. có vấn đề gì
Rasool Ghafari

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

svgDocument không rỗng. Đây là một số loại vấn đề nội bộ trong thư viện.
Jonathan Allen

@JonathanAllen, tôi đang trả lời bình luận của Rasool.
Anish

12

Khi tôi phải sắp xếp lại các svgs trên máy chủ, tôi đã kết thúc bằng cách sử dụng P / Invoke để gọi các hàm librsvg (bạn có thể lấy dlls từ phiên bản windows 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());
    }
}

1
librSVG không tệ, nhưng phông chữ / văn bản, nó không xử lý chúng một cách chính xác. Thay vào đó, hãy nhìn vào không đầu-chrome, API chrome-gỡ lỗi, và C # API cho các API chrome-gỡ lỗi: github.com/ststeiger/ChromeDevTools/blob/master/source/...
Stefan Steiger

8

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;

@downvoters - Vui lòng giải thích lý do bạn phản đối. Phiếu phản đối không có lời giải thích có giá trị bằng không.
stevenvh

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

không downvote, nhưng bạn có thể chỉnh sửa câu trả lời của bạn và làm cho nó rõ ràng rằng Batiklà một thư viện Java mà bạn có thể gọi từ C # hay bất cứ ngôn ngữ (trong trường hợp này, bạn thấy làm thế nào để gọi nó trong Delphi)
ErrCode

Bắt đầu một quá trình mới là chậm. Ngoài ra, làm thế nào một cách chính xác batik rasterize? Các mã nhị phân mới nhất rất khó lấy. Thay vì chịu đựng thứ tào lao đó, hãy xem qua headless-chrome, chrome-debugging API và C # API cho chrome-debugging API: github.com/ststeiger/ChromeDevTools/blob/master/source/… - Tất cả Người dùng Java, tôi chắc chắn rằng cũng có Java-API xung quanh API gỡ lỗi của chrome.
Stefan Steiger

4

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

    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.


Phụ huynh không được định nghĩa trong SetFont, nên yếu tố hoặc đổi tên biến yếu tố để phụ huynh tại các chức năng chữ ký
Norbert Kardos

Ngoài ra Font bây giờ dường như là một chuỗi. Tuy nhiên đây là một chiếc phao cứu sinh, cảm ơn!
Norbert Kardos

-3

bạn có thể sử dụng altsoft xml2pdf lib cho việc này

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.