Перетворення SVG в PNG за допомогою C # [закрито]


102

Я намагався перетворити SVG-зображення в PNG за допомогою C #, не записуючи занадто багато коду. Хтось може порекомендувати для цього бібліотеку чи приклад коду?


Я знайшов хорошу і просту бібліотеку, яку ви можете використовувати в c # github.com/ElinamLLC/SharpVectors , вона може конвертувати багато типів svg в bmp, jpeg або png
Махді,

2
Чи можу я сказати: ці рішення погані, включаючи wkhtml2pdf / wkhtml2image тощо. Специфікація SVG є складною і розвивається, тому це і CSS-стилі, і поверх цього вона повинна виглядати так само, як у браузері. Наприклад, wkhtml2X має великі проблеми з шрифтами, а двигун webkit всередині занадто старий. На щастя, є рішення: Chrome має безголовий режим, і за допомогою програми Debugging API можна отримувати PNG-зображення та PDF-файли із самих Headless-Chrome, за допомогою MasterDevs / ChromeDevTools у C #: Приклад: github.com/ststeiger/ChromeDevTools / blob / master / source /…
Стефан Штайгер

Відповіді:


68

Ви можете викликати версію командного рядка inkscape, щоб зробити це:

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

Також є механізм візуалізації C # SVG, розроблений головним чином, щоб дозволити використання файлів SVG в Інтернеті в кодеплексі, що може відповідати вашим потребам, якщо це ваша проблема:

Оригінальний проект
http://www.codeplex.com/svg

Вилка з виправленнями та більшою активністю: (додано 7/2013)
https://github.com/vvvv/SVG


39
Дякую Еспо. Я фактично написав цю публікацію в блозі Inkscape! Хоча це "працює", це не особливо надійне рішення. Мені подобається проект кодеплексу - я його погляну. Дякую.
harriyott

9
Як ніяково :) Хороша річ, можливо, двигун візуалізації SVG може вам допомогти.
Еспо

20
Я приймаю це як комплімент. Я раніше не цитував себе!
harriyott

Ви спробували движок візуалізації svg? Ви можете поділитися ур рішення PLZ. Я намагаюся змусити його працювати, але маючи проблеми, дивіться тут
Armance

1
Я спробував github.com/vvvv/SVG, і він працює, але з певними обмеженнями. imageЕлемент не був реалізований - я перевірив вихідний код. @FrankHale Мені довелося видалити xmlns з svg, тому що raphael додав його двічі.
fireydude

74

Є набагато простіший спосіб використання бібліотеки http://svg.codeplex.com/ ( новіша версія @ GIT , @ NuGet ). Ось мій код

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, оскільки вона є більш сучасною і навіть не підтримує imageелемент.
fireydude

Я використовую цей код, він кидає, object not set to an instance of an objectколи хочеться виконати var bitmap = svgDocument.Draw();. в чому проблема?
Rasool Ghafari

@RasoolGhafari переконайтеся, що ваш svgDocument не є нульовим.
Аніш

svgDocument не є нульовим. Це якась внутрішня проблема в бібліотеці.
Джонатан Аллен

@JonathanAllen, я відповідав на коментар Rasool.
Аніш

12

Коли мені довелося розгортати svgs на сервері, я в кінцевому підсумку використовував P / Invoke для виклику функцій librsvg (ви можете отримати dll з версії Windows програми редагування зображень 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 - це непогано, але шрифти / текст, вони неправильно обробляють їх. Натомість погляньте на API безголового хрому, хром-налагодження API та API API # для хромування налагодження: github.com/ststeiger/ChromeDevTools/blob/master/source/…
Стефан Штайгер

8

Я використовую для цього Batik . Повний код 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 - Будь ласка, поясніть, чому ви порушили. Потік без пояснення має нульове значення.
stevenvh

4
Я здогадуюсь, що голосування походять з тексту питання, який містить "c #" в ньому. і ваша пропозиція - дельфі
Денис

не сказав, але ви можете відредагувати свою відповідь і дати зрозуміти, що Batikце бібліотека Java, яку ви можете дзвонити з C # або будь-якої іншої мови (у цьому випадку ви показали, як її зателефонувати в Delphi)
ErrCode

Починати новий процес відбувається повільно. Крім того, наскільки правильно розбризується батик? Останні бінарні файли важко отримати. Замість того, щоб змиритися з цим лаєм, погляньте на API без хроніки, API налагодження хрому та API C # для API хромування налагодження: github.com/ststeiger/ChromeDevTools/blob/master/source/… - для всіх Користувачі Java, я впевнений, що існує також Java-API навколо хромового API налагодження.
Стефан Штайгер

4

Щоб додати відповідь від @Anish, якщо у вас виникають проблеми з тим, що не експортується текст під час експорту SVG до зображення, ви можете створити рекурсивну функцію, щоб провести цикл через дітей SVGDocument, спробуйте передати його на SvgText, якщо можливо (додайте власну перевірку помилок) та встановіть сімейство та стиль шрифту.

    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
        {

        }
    }

Повідомте мене, якщо є питання.


батьківський параметр не визначений у SetFont, має бути елементом або перейменувати змінну елемента на батьківський під підписом функції
Норберт

Також шрифт, здається, зараз є рядком. Однак це було рятівником, спасибі!
Норберт

-3

ви можете використовувати для цього altsoft xml2pdf lib

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.