C # kullanarak SVG'yi PNG'ye dönüştürme [kapalı]


102

Çok fazla kod yazmak zorunda kalmadan SVG görüntülerini C # kullanarak PNG'ye dönüştürmeye çalışıyorum. Herkes bunu yapmak için bir kitaplık veya örnek kod önerebilir mi?


i iyi ve c # kullanabileceği basit kütüphaneyi bulundu github.com/ElinamLLC/SharpVectors , bu bmp, jpeg veya png için svg birçok türü dönüştürebilirsiniz
Mehdi

2
Şunu söyleyebilir miyim: wkhtml2pdf / wkhtml2image vb. Dahil olmak üzere bu çözümler kötüdür. SVG spesifikasyonu karmaşık ve gelişmekte, CSS stilleri de öyle ve bunun da ötesinde, tarayıcıdakiyle aynı görünmelidir. Örneğin, wkhtml2X yazı tipleriyle ilgili büyük sorunlar yaşıyor ve içindeki webkit motoru çok eski. Neyse ki, bir çözüm var: Chrome'un başsız modu var ve Hata Ayıklama API'si ile, Başsız Chrome'un kendisinden PNG görüntüleri ve PDF'leri, MasterDevs / ChromeDevTools ile C #: Örnek: github.com/ststeiger/ChromeDevTools / blob / master / source /…
Stefan Steiger

Yanıtlar:


68

Bunu yapmak için inkscape'in komut satırı sürümünü çağırabilirsiniz:

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

Ayrıca, öncelikle SVG dosyalarının web'de kodepleks üzerinde kullanılmasına izin vermek için tasarlanmış bir C # SVG oluşturma motoru vardır, eğer sorununuz buysa ihtiyaçlarınızı karşılayabilir:

Orijinal Proje
http://www.codeplex.com/svg

Düzeltmeler ve daha fazla etkinlik içeren çatal: (7/2013 eklendi)
https://github.com/vvvv/SVG


39
Teşekkürler Espo. Aslında o inkscape blog gönderisini yazdım! "Çalışmasına" rağmen, özellikle sağlam bir çözüm değildir. Yine de codeplex projesini beğendim - bir göz atacağım. Teşekkürler.
harriyott

9
Ne kadar utanç verici :) İyi bir şey belki SVG oluşturma motoru size yardımcı olabilir.
Espo

20
Bunu bir iltifat olarak alıyorum. Daha önce kendime alıntı yapmadım!
harriyott

svg oluşturma motorunu denediniz mi? çözümünü paylaşabilir misin lütfen? Çalışmasını sağlamaya çalışıyorum ama sorunlarım var, buraya bakın
Armance

1
Github.com/vvvv/SVG'yi denedim ve çalışıyor ancak belirli sınırlamalarla. imageEleman uygulamaya konmamıştır - Ben kaynak kodunu kontrol etti. @FrankHale raphael iki kez eklediğinden bir xmlns'yi svg'den kaldırmak zorunda kaldım.
fireydude

74

Http://svg.codeplex.com/ (Yeni sürüm @ GIT , @ NuGet ) kitaplığını kullanmanın çok daha kolay bir yolu var . İşte kodum

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
Github sürümünü kullanmak zorunda kaldım çünkü daha güncel ve bu bile imageöğeyi desteklemiyor .
fireydude

Ben bu koddan alışkınım, object not set to an instance of an objectçalıştırmak istediğinde fırlatıyor var bitmap = svgDocument.Draw();. sorun ne?
Rasool Ghafari

@RasoolGhafari svgDocument'inizin boş olmadığından emin olun.
Anish

svgDocument boş değil. Bu, kütüphanede bir tür iç problemdir.
Jonathan Allen

@JonathanAllen, Rasool'un yorumunu yanıtlıyordum.
Anish

12

Sunucuda svgs'i rasterleştirmem gerektiğinde, librsvg işlevlerini çağırmak için P / Invoke'u kullandım (dll'leri GIMP resim düzenleme programının bir Windows sürümünden alabilirsiniz).

[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 fena değil, ancak yazı tipleri / metin, onları doğru şekilde işlemez. Bunun yerine, krom hata ayıklama API'sı için başsız krom, krom hata ayıklama API'sı ve bir C # API'sına bakın: github.com/ststeiger/ChromeDevTools/blob/master/source/…
Stefan Steiger

8

Bunun için Batik kullanıyorum . Tam Delphi kodu:

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 - Lütfen neden olumsuz oy verdiğinizi açıklayın. Açıklama içermeyen bir olumsuz oy sıfır değerine sahiptir.
stevenvh

4
sanırım olumsuz oylar, içinde "c #" bulunan soru metninden geliyor. ve teklifin delphi
Denis

olumsuz oy vermediniz, ancak cevabınızı düzenleyebilir ve bunun BatikC # veya herhangi bir dilden arayabileceğiniz bir Java kitaplığı olduğunu netleştirebilirsiniz (bu durumda Delphi'de nasıl arayacağınızı gösterdiniz)
ErrCode

Yeni bir işlemin başlatılması yavaştır. Ayrıca, batik rasterleştirmesi ne kadar doğru? En son ikili dosyaları bulmak zordur. Bu saçmalığa katlanmak yerine, başsız krom, krom hata ayıklama API'si ve krom hata ayıklama API'si için bir C # API'sına bir göz atın: github.com/ststeiger/ChromeDevTools/blob/master/source/… - Herkes için Java kullanıcıları, eminim Chrome'un hata ayıklama API'sı etrafında Java API'leri de vardır.
Stefan Steiger

4

@Anish'ten gelen yanıta eklemek için, SVG'yi bir görüntüye aktarırken metni görmemekle ilgili sorunlar yaşıyorsanız, SVGDocument'in alt öğeleri arasında döngü yapmak için özyinelemeli bir işlev oluşturabilirsiniz, eğer bunu bir SvgText'e dönüştürmeyi deneyin. mümkün (kendi hata kontrolünüzü ekleyin) ve yazı tipi ailesini ve stilini ayarlayın.

    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
        {

        }
    }

Sorularınız varsa bana bildirin.


ebeveyn SetFont'ta tanımlanmadı, öğe olmalı veya işlev imzasında öğe değişkenini ebeveyn olarak yeniden adlandırmalı
Norbert Kardos

Ayrıca Font artık bir dizge gibi görünüyor. Ancak bu bir cankurtarandı, teşekkürler!
Norbert Kardos

-3

bunun için altsoft xml2pdf lib kullanabilirsiniz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.