Konwersja SVG do PNG przy użyciu C # [zamknięte]


102

Próbowałem przekonwertować obrazy SVG na PNG przy użyciu C # bez konieczności pisania zbyt dużej ilości kodu. Czy ktoś może polecić bibliotekę lub przykładowy kod do tego?


znalazłem dobrą i prostą bibliotekę, której możesz użyć w c # github.com/ElinamLLC/SharpVectors , może konwertować wiele typów svg do bmp, jpeg lub png
— Mahdi

2
Mogę powiedzieć: te rozwiązania są złe, w tym wkhtml2pdf / wkhtml2image itp. Specyfikacja SVG jest złożona i ewoluuje, podobnie jak style CSS, a do tego powinna wyglądać tak samo jak w przeglądarce. Na przykład wkhtml2X ma ogromne problemy z czcionkami, a silnik webkita jest po prostu za stary. Na szczęście istnieje rozwiązanie: Chrome ma tryb bezgłowy, a dzięki Debugging-API możesz pobierać obrazy PNG i pliki PDF z samego Headless-Chrome, z MasterDevs / ChromeDevTools w C #: Przykład: github.com/ststeiger/ChromeDevTools / blob / master / source /…
— Stefan Steiger

Odpowiedzi:


68

Aby to zrobić, możesz wywołać wersję inkscape wiersza poleceń:

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

Istnieje również silnik renderujący C # SVG, zaprojektowany głównie w celu umożliwienia używania plików SVG w Internecie na codeplex, który może odpowiadać Twoim potrzebom, jeśli to jest twój problem:

Oryginalny projekt
http://www.codeplex.com/svg

Widelec z poprawkami i większą aktywnością: (dodano 7/2013)
https://github.com/vvvv/SVG


39
Dzięki Espo. Właściwie napisałem ten post na blogu inkscape! Chociaż to „działa”, nie jest to szczególnie solidne rozwiązanie. Podoba mi się jednak projekt codeplex - przyjrzę mu się. Dzięki.
— harriyott,

9
Jakie żenujące :) Dobrze, że może silnik renderujący SVG mógłby ci w tym pomóc.
— Espo

20
Traktuję to jako komplement. Nie byłam wcześniej cytowana!
— harriyott,

Czy wypróbowałeś silnik renderujący svg? czy możesz udostępnić plz rozwiązanie ur. staram się, aby to działało, ale mam kłopoty, zobacz tutaj
— Armance,

1
Wypróbowałem github.com/vvvv/SVG i działa, ale z pewnymi ograniczeniami. imageElement nie został wdrożony - Sprawdziłem kod źródłowy. @FrankHale Musiałem usunąć xmlns z svg, ponieważ Rafael dodał go dwukrotnie.
— fireydude

74

Istnieje znacznie łatwiejszy sposób korzystania z biblioteki http://svg.codeplex.com/ (nowsza wersja @ GIT , @ NuGet ). Oto mój kod

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
Musiałem skorzystać z wersji github, ponieważ jest bardziej aktualna, a nawet nie obsługuje tego imageelementu.
— fireydude

Jestem używany z tego kodu, wyrzuca, object not set to an instance of an objectgdy chce się wykonać var bitmap = svgDocument.Draw();. jaki jest problem?
— Rasool Ghafari

@RasoolGhafari upewnij się, że twój svgDocument nie ma wartości null.
— Anish

svgDocument nie jest null. To jakiś wewnętrzny problem w bibliotece.
— Jonathan Allen

@JonathanAllen, odpowiadałem na komentarz Rasool.
— Anish

12

Kiedy musiałem rasteryzować pliki SVG na serwerze, skończyło się na tym, że użyłem P / Invoke do wywołania funkcji librsvg (pliki dll można pobrać z wersji programu do edycji obrazów GIMP dla systemu Windows).

[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 nie jest zły, ale czcionki / tekst nie obsługują ich poprawnie. Zamiast tego spójrz na bezgłowy chrome, chrome-debugging API i C # API dla chrome-debugging API: github.com/ststeiger/ChromeDevTools/blob/master/source/ ...
— Stefan Steiger

8

Używam do tego Batika . Pełny kod 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;

@downvoters - Wyjaśnij, dlaczego głosujesz przeciw. Głos przeciw bez wyjaśnienia ma zerową wartość.
— stevenvh

4
Myślę, że głosy przeciwne pochodzą z tekstu pytania, które zawiera „c #”. a twoja propozycja to delphi
— Denis

nie przegłosowałeś, ale możesz edytować swoją odpowiedź i wyjaśnić, że Batikjest to biblioteka Java, którą możesz wywołać z C # lub dowolnego innego języka (w tym przypadku pokazałeś, jak to wywołać w Delphi)
— ErrCode

Rozpoczynanie nowego procesu jest powolne. Jak poprawnie rasteryzuje się batik? Najnowsze pliki binarne są trudne do zdobycia. Zamiast znosić te bzdury, spójrz na bezgłowy chrome, chrome-debugging API i C # API dla chrome-debugging API: github.com/ststeiger/ChromeDevTools/blob/master/source/… - For all Użytkownicy Javy, jestem pewien, że wokół API debugowania Chrome jest również API Java.
— Stefan Steiger,

4

Aby dodać do odpowiedzi z @Anish, jeśli masz problemy z niewidocznością tekstu podczas eksportowania SVG do obrazu, możesz utworzyć funkcję rekurencyjną, aby zapętlić elementy podrzędne SVGDocument, spróbuj rzutować ją na SvgText, jeśli możliwe (dodaj własne sprawdzanie błędów) i ustaw rodzinę czcionek i styl.

    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
        {

        }
    }

Daj mi znać, jeśli są jakieś pytania.


rodzic nie jest zdefiniowane w setFont, powinny być elementem lub zmienić nazwę elementu zmienną podpisu rodzica na funkcji
— Norbert Kardos

Również Font wydaje się być teraz ciągiem. Jednak to było uratowanie życia, dzięki!
— Norbert Kardos

-3

możesz do tego użyć altsoft xml2pdf lib

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.