Mengonversi SVG ke PNG menggunakan C # [closed]

102

Saya sudah mencoba mengonversi gambar SVG ke PNG menggunakan C #, tanpa harus menulis terlalu banyak kode. Adakah yang bisa merekomendasikan perpustakaan atau kode contoh untuk melakukan ini?

harriyott
sumber
saya menemukan perpustakaan yang bagus dan sederhana yang dapat Anda gunakan di c # github.com/ElinamLLC/SharpVectors , itu dapat mengubah banyak jenis svg ke bmp, jpeg atau png
Mahdi
2
Boleh saya katakan: solusi tersebut buruk, termasuk wkhtml2pdf / wkhtml2image dll. Spesifikasi SVG rumit dan berkembang, begitu pula gaya CSS, dan di atas itu, harus terlihat sama seperti di browser. wkhtml2X, misalnya, memiliki masalah besar dengan font, dan mesin webkit di dalamnya sudah terlalu tua. Untungnya, ada solusinya: Chrome memiliki mode tanpa kepala, dan dengan Debugging-API-nya, Anda bisa mendapatkan gambar PNG dan PDF dari Headless-Chrome itu sendiri, dengan MasterDevs / ChromeDevTools di C #: Contoh: github.com/ststeiger/ChromeDevTools / blob / master / source /…
Stefan Steiger

Jawaban:

68

Anda dapat memanggil versi baris perintah inkscape untuk melakukan ini:

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

Juga ada mesin rendering C # SVG, terutama dirancang untuk memungkinkan file SVG digunakan di web pada codeplex yang mungkin sesuai dengan kebutuhan Anda jika itu adalah masalah Anda:

Proyek Asli
http://www.codeplex.com/svg

Bercabang dengan perbaikan dan lebih banyak aktivitas: (ditambahkan 7/2013)
https://github.com/vvvv/SVG

Espo
sumber
39
Terima kasih Espo. Sebenarnya saya menulis postingan blog inkscape itu! Meskipun "berhasil", ini bukanlah solusi yang sangat kuat. Saya suka proyek codeplex - saya akan mencobanya. Terima kasih.
harriyott
9
Sungguh memalukan :) Untung mungkin mesin rendering SVG dapat membantu Anda.
Espo
20
Saya menganggapnya sebagai pujian. Saya belum pernah dikutip untuk diri saya sendiri sebelumnya!
harriyott
Sudahkah kamu mencoba mesin rendering svg? bisakah kamu berbagi solusi ur tlg. Saya mencoba untuk membuatnya bekerja tetapi mengalami masalah, lihat di sini
Armance
1
Saya telah mencoba github.com/vvvv/SVG dan berhasil tetapi dengan batasan tertentu. The imageelemen belum dilaksanakan - aku memeriksa kode sumber. @FrankHale Saya harus menghapus xmlns dari svg karena raphael menambahkannya dua kali.
fireydude
74

Ada cara yang jauh lebih mudah menggunakan perpustakaan http://svg.codeplex.com/ (Versi terbaru @ GIT , @ NuGet ). Ini kode saya

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);
}
Anish
sumber
1
Saya harus menggunakan versi github karena lebih up-to-date dan bahkan tidak mendukung imageelemen tersebut.
fireydude
Saya digunakan dari kode ini, itu melempar object not set to an instance of an objectketika ingin mengeksekusi var bitmap = svgDocument.Draw();. apa masalahnya?
Rasool Ghafari
@RasoolGhafari pastikan svgDocument Anda tidak null.
Anish
svgDocument bukan null. Ini semacam masalah internal di perpustakaan.
Jonathan Allen
@JonathanAllen, saya menjawab komentar Rasool.
Anish
12

Ketika saya harus meraster svgs di server, saya akhirnya menggunakan P / Invoke untuk memanggil fungsi librsvg (Anda bisa mendapatkan dll dari versi windows dari program pengeditan gambar 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());
    }
}
nw.
sumber
1
librSVG tidak buruk, tetapi font / teks tidak menanganinya dengan benar. Alih-alih, lihat headless-chrome, chrome-debugging API, dan C # API untuk chrome-debugging API: github.com/ststeiger/ChromeDevTools/blob/master/source/…
Stefan Steiger
8

Saya menggunakan Batik untuk ini. Kode Delphi lengkap:

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;
stevenvh.dll
sumber
@downvoters - Jelaskan mengapa Anda memilih downvote. Suara negatif tanpa penjelasan memiliki nilai nol.
stevenvh
4
Saya kira suara negatif berasal dari teks pertanyaan yang mengandung "c #" di dalamnya. dan proposal Anda adalah delphi
Denis
tidak downvote, tetapi Anda dapat mengedit jawaban Anda dan memperjelas bahwa itu Batikadalah pustaka Java yang dapat Anda panggil dari C # atau bahasa apa pun (dalam hal ini Anda menunjukkan cara memanggilnya dalam Delphi)
ErrCode
Memulai proses baru itu lambat. Seberapa tepatkah batik melakukan rasterisasi? Biner terbaru sulit didapat. Alih-alih bertahan dengan omong kosong itu, lihat API headless-chrome, chrome-debugging, dan C # API untuk API debugging chrome: github.com/ststeiger/ChromeDevTools/blob/master/source/… - Untuk semua Pengguna Java, saya yakin ada juga Java-API di sekitar API debug chrome.
Stefan Steiger
4

Untuk menambahkan respons dari @Anish, jika Anda mengalami masalah dengan tidak melihat teks saat mengekspor SVG ke gambar, Anda dapat membuat fungsi rekursif untuk mengulang melalui turunan SVGDocument, coba transmisikan ke SvgText jika mungkin (tambahkan pemeriksaan kesalahan Anda sendiri) dan atur keluarga dan gaya font.

    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
        {

        }
    }

Beri tahu saya jika ada pertanyaan.

Michal Kieloch
sumber
parent tidak didefinisikan di SetFont, harus menjadi elemen atau mengganti nama variabel elemen menjadi induk pada tanda tangan fungsi
Norbert Kardos
Juga Font tampaknya menjadi string sekarang. Namun ini adalah penyelamat, terima kasih!
Norbert Kardos
-3

Anda dapat menggunakan lib altsoft xml2pdf untuk ini


sumber