Эта ветка оставила проблему нерешенной. Принятый ответ пришел от спрашивающего, который поделился своей неудачной попыткой кода. Другой ответ предлагал ImageMagick, но один из комментаторов сказал, что ImageMagick выполняет «ужасную работу по интерпретации SVG». Я не хочу, чтобы мои png выглядели ужасно, поэтому я снова задаю вопрос.
Его предоставляет пакет Ubuntu python-rsvg . Поиск в Google по его названию неэффективен, потому что его исходный код, кажется, содержится в репозитории GIT проекта Gnome "gnome-python-desktop".
Я сделал минималистичный "привет мир", который отображает SVG на поверхности cairo и записывает его на диск:
Обновление : в 2014 Нужные пакет для распространения Fedora Linux является: gnome-python2-rsvg. Приведенный выше список фрагментов по-прежнему работает как есть.
Отлично, отлично работает. Но есть ли способ дать возможность самостоятельно cairoопределять ВЫСОТУ и ШИРИНУ изображения? Я просмотрел *.svgфайл, чтобы извлечь оттуда ВЫСОТУ и ШИРИНУ, но они оба установлены на 100%. Конечно, я могу изучить свойства изображения, но поскольку это всего лишь один шаг в обработке изображения, это не то, что мне нужно.
quapka 09
1
Если для "ширины" и "высоты" ваших файлов установлено значение 100%, Cairo или rsvg не могут сделать ничего волшебного, чтобы угадать размер: такие файлы SVG были оставлены независимо от размера программным обеспечением-создателем (/ person). Окружающий HTML-код для импорта файла SVG предоставит физический размер. Однако у объекта «Handle» в rsvg есть .get_dimension_data()метод, который работал с моим файлом примера (хорошо управляемый SVG) - попробуйте.
jsbueno
1
по состоянию на 2014 год для ubuntu вы можете использовать: apt-get install python-rsvg
t1m0
1
Есть ли быстрая команда для добавления белого фона к изображению, если его текущий фон прозрачный?
fiatjaf 07
@jsbueno Я использую Windows 8.1 и python 2.7.11 Как мне установить cairo и rsvg и заставить их работать. Я изо всех сил пытался заставить эту работу работать. BTW +1 для вашего подробного объяснения.
Здравствуй. Вы знаете, как я могу сделать то же самое, но без записи в файл? Мне нужно отправить содержимое png в браузер с веб-сервера, чтобы пользователь мог загрузить изображение. Сохранение файла png не является допустимым вариантом в нашем проекте, поэтому он мне и нужен. Спасибо
estemendoza
4
Я сам этим занимался. Это в основном зависит от того, какие инструменты или фреймворки у вас есть под рукой при обработке ваших веб-запросов, но независимо от того, что это такое, основная идея заключается в том, что он svg2pngпринимает streamобъект в write_toпараметре, и это может быть ваш объект HTTP-ответа (который в большинство фреймворков представляет собой файловый объект) или какой-либо другой поток, который вы затем передаете браузеру с помощью Content-Dispositionзаголовка. см. здесь: stackoverflow.com/questions/1012437/…
nemesisfixx
4
Для тех, кто испытывает проблемы с этим кодом, как и я: 1). bytestringпринимает байты, поэтому сначала преобразуйте строку с помощью bytestring=bytes(svg,'UTF-8') 2). файловый режим должен быть двоичным, поэтомуopen('output.png','wb')
Серж Захарченко
3
cairosvg поддерживает только Python 3.4+. Они отказались от поддержки Python 2
Марлон Абейкун,
1
Для svg2pngменя не было, мне пришлось использовать cairosvg.surface.PNGSurface.convert(svg_str, write_to='output.png').
tobltobs
39
Установите Inkscape и вызовите его как командную строку:
Вы также можете привязать конкретную прямоугольную область только с помощью параметра -j, например, координаты "0: 125: 451: 217"
${INKSCAPE_PATH}-z -f ${source_svg}-w ${width}-j -a ${coordinates}-e ${dest_png}
Если вы хотите показать только один объект в файле SVG, вы можете указать параметр -iс идентификатором объекта, который вы установили в SVG. Он скрывает все остальное.
${INKSCAPE_PATH}-z -f ${source_svg}-w ${width}-i ${object}-j -a ${coordinates}-e ${dest_png}
+1, потому что это также очень удобно для написания сценариев оболочки. См inkscape.org/doc/inkscape-man.html полных документаций по командной строке в Inkscape.
Prime
Спасибо, это был самый простой способ сделать это. В Windows, чтобы вам не приходилось каждый раз вводить полный путь к Inkscape, вы можете добавить его в свой путь в переменных среды .
Alex S
3
Это не ответ. Это обходной путь. OP запросил решение Python.
lamino
31
Я использую Wand-py (реализацию оболочки Wand вокруг ImageMagick) для импорта некоторых довольно продвинутых SVG-файлов и пока что добился отличных результатов! Это весь код, который требуется:
with wand.image.Image( blob=svg_file.read(), format="svg")as image:
png_image = image.make_blob("png")
Я только что обнаружил это сегодня и почувствовал, что стоит поделиться этим для всех, кто может запутаться в этом ответе, поскольку прошло некоторое время с тех пор, как на большинство этих вопросов были даны ответы.
ПРИМЕЧАНИЕ. Технически при тестировании я обнаружил, что вам даже не нужно передавать параметр формата для ImageMagick, так что with wand.image.Image( blob=svg_file.read() ) as image:это все, что действительно нужно.
РЕДАКТИРОВАТЬ: из попытки редактирования qris, вот полезный код, который позволяет вам использовать ImageMagick с SVG с прозрачным фоном:
Wand работал с моими PNG намного лучше, чем Cairo.
qris
3
Я получаю сообщение об ошибке image.read(blob=svg_file.read(), format="svg") NameError: name 'svg_file' is not defined
adrienlucca.wordpress.com
2
svg_fileв этом примере предполагается, что это объект "файл", настройка svg_fileбудет выглядеть примерно так:svg_file = File.open(file_name, "r")
streetlogics
2
Спасибо, метод cairoи rsvg"принято" не сработали для моего PDF-файла. pip install wandи ваш сниппет сделал свое дело;)
nmz787
5
Если у вас есть SVG , strто вам сначала нужно закодировать в двоичном , как это: svg_blob = svg_str.encode('utf-8'). Теперь вы можете использовать описанный выше метод, заменив его blob=svg_file.read()на blob=svg_blob.
К сожалению, здесь есть две проблемы. Во-первых, он не обрабатывает файлы <clipPath><rect ... /></clipPath>. Во-вторых, он не принимает параметр -d (DPI).
Ray
2
@Ray, пожалуйста, отправляйте отчеты об ошибках / запросы функций на трекере CairoSVG !
Саймон Сапин
@Simon, сделай, пожалуйста? Я слишком занят и буду в ближайшие 1-2 месяца.
Ray
2
@Ray, на самом деле параметр -d / --dpi присутствует уже некоторое время, и мне сказали, что поддержка <clippath> была добавлена несколько недель назад в версии git.
Я использовал извлечение ширины и высоты svg. Я не уверен в стандарте svg, но в некоторых моих файлах svg за шириной или высотой следовала нечисловая строка, такая как «мм» или «px» (например, «250 мм»). Int ('250mm') выдает исключение, и мне пришлось внести некоторые дополнительные настройки.
WigglyWorld
5
Я не нашел удовлетворительного ответа. Все упомянутые библиотеки имеют ту или иную проблему, например, отказ Каира от поддержки python 3.6 (они отказались от поддержки Python 2 около 3 лет назад!). Кроме того, установка упомянутых библиотек на Mac была проблемой.
Наконец, я нашел лучшее решение - svglib + reportlab . Оба были установлены без проблем с использованием pip, и первый вызов для преобразования из svg в png работал прекрасно! Очень доволен решением.
Всего две команды делают свое дело:
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPM
drawing = svg2rlg("my.svg")
renderPM.drawToFile(drawing,"my.png", fmt="PNG")
Есть ли какие-то ограничения, о которых я должен знать?
Используя pycairo и librsvg, я смог добиться масштабирования SVG и рендеринга в растровое изображение. Предполагая, что ваш SVG не совсем 256x256 пикселей, желаемый результат вы можете прочитать в SVG в контексте Cairo с помощью rsvg, а затем масштабировать его и записать в PNG.
Спасибо за это, он оказался очень полезным в моем проекте. Хотя Handle.get_dimension_dataу меня не получилось. Мне пришлось заменить его простой загрузкой self.props.widthи self.props.height. Сначала я попытался определить RsvgDimensionDataструктуру, как описано на веб-сайте cairo, но безуспешно.
JeanOlivier 01
Я пытаюсь использовать это в своем проекте. Как мне получить необходимые файлы DLL?
Andoo
0
Вот подход, при котором Inkscape вызывается Python.
Обратите внимание, что он подавляет некоторые неаккуратные выходные данные, которые Inkscape записывает в консоль (в частности, stderr и stdout) во время нормальной безошибочной работы. Вывод фиксируется в двух строковых переменных outи err.
import subprocess # May want to use subprocess32 instead
cmd_list =['/full/path/to/inkscape','-z','--export-png','/path/to/output.png','--export-width',100,'--export-height',100,'/path/to/input.svg']# Invoke the command. Divert output that normally goes to stdout or stderr.
p = subprocess.Popen( cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE )# Below, < out > and < err > are strings or < None >, derived from stdout and stderr.
out, err = p.communicate()# Waits for process to terminate# Maybe do something with stdout output that is in < out ># Maybe do something with stderr output that is in < err >if p.returncode:raiseException('Inkscape error: '+(err or'?'))
Например, при выполнении определенного задания в моей системе Mac OS outполучилось:
Background RRGGBBAA: ffffff00
Area0:0:339:339 exported to 100 x 100 pixels (72.4584 dpi)Bitmap saved as:/path/to/output.png
(Размер входного файла SVG составлял 339 на 339 пикселей.)
Это не сквозной Python, если вы полагаетесь на Inkscape.
Joel
1
@Joel: Первая строка была изменена, чтобы преодолеть ваше возражение. Но, конечно, даже «чистое» решение Python основано на элементах за пределами основного языка и, в конечном итоге, работает на машинном языке, так что, возможно, нет такой вещи, как сквозной процесс!
Iron Pillow
0
На самом деле, я не хотел зависеть ни от чего другого, кроме Python (Cairo, Ink ... и т. Д.). Мои требования должны были быть как можно более простыми pip install "savior", в лучшем случае достаточно простого , поэтому ни одно из вышеперечисленных не выполнялось. t подходит для меня.
Ответы:
Ответ - pyrsvg - привязка Python к librsvg .
Его предоставляет пакет Ubuntu python-rsvg . Поиск в Google по его названию неэффективен, потому что его исходный код, кажется, содержится в репозитории GIT проекта Gnome "gnome-python-desktop".
Я сделал минималистичный "привет мир", который отображает SVG на поверхности cairo и записывает его на диск:
Обновление : в 2014 Нужные пакет для распространения Fedora Linux является:
gnome-python2-rsvg
. Приведенный выше список фрагментов по-прежнему работает как есть.источник
cairo
определять ВЫСОТУ и ШИРИНУ изображения? Я просмотрел*.svg
файл, чтобы извлечь оттуда ВЫСОТУ и ШИРИНУ, но они оба установлены на100%
. Конечно, я могу изучить свойства изображения, но поскольку это всего лишь один шаг в обработке изображения, это не то, что мне нужно..get_dimension_data()
метод, который работал с моим файлом примера (хорошо управляемый SVG) - попробуйте.Вот что я сделал с помощью cairosvg :
И это работает как шарм!
Подробнее: cairosvg document
источник
svg2png
принимаетstream
объект вwrite_to
параметре, и это может быть ваш объект HTTP-ответа (который в большинство фреймворков представляет собой файловый объект) или какой-либо другой поток, который вы затем передаете браузеру с помощьюContent-Disposition
заголовка. см. здесь: stackoverflow.com/questions/1012437/…bytestring
принимает байты, поэтому сначала преобразуйте строку с помощьюbytestring=bytes(svg,'UTF-8')
2). файловый режим должен быть двоичным, поэтомуopen('output.png','wb')
svg2png
меня не было, мне пришлось использоватьcairosvg.surface.PNGSurface.convert(svg_str, write_to='output.png')
.Установите Inkscape и вызовите его как командную строку:
Вы также можете привязать конкретную прямоугольную область только с помощью параметра
-j
, например, координаты "0: 125: 451: 217"Если вы хотите показать только один объект в файле SVG, вы можете указать параметр
-i
с идентификатором объекта, который вы установили в SVG. Он скрывает все остальное.источник
Я использую Wand-py (реализацию оболочки Wand вокруг ImageMagick) для импорта некоторых довольно продвинутых SVG-файлов и пока что добился отличных результатов! Это весь код, который требуется:
Я только что обнаружил это сегодня и почувствовал, что стоит поделиться этим для всех, кто может запутаться в этом ответе, поскольку прошло некоторое время с тех пор, как на большинство этих вопросов были даны ответы.
ПРИМЕЧАНИЕ. Технически при тестировании я обнаружил, что вам даже не нужно передавать параметр формата для ImageMagick, так что
with wand.image.Image( blob=svg_file.read() ) as image:
это все, что действительно нужно.РЕДАКТИРОВАТЬ: из попытки редактирования qris, вот полезный код, который позволяет вам использовать ImageMagick с SVG с прозрачным фоном:
источник
image.read(blob=svg_file.read(), format="svg") NameError: name 'svg_file' is not defined
svg_file
в этом примере предполагается, что это объект "файл", настройкаsvg_file
будет выглядеть примерно так:svg_file = File.open(file_name, "r")
cairo
иrsvg
"принято" не сработали для моего PDF-файла.pip install wand
и ваш сниппет сделал свое дело;)str
то вам сначала нужно закодировать в двоичном , как это:svg_blob = svg_str.encode('utf-8')
. Теперь вы можете использовать описанный выше метод, заменив егоblob=svg_file.read()
наblob=svg_blob
.Попробуйте это: http://cairosvg.org/
На сайте написано:
Обновление 25 ноября 2016 г . :
источник
<clipPath><rect ... /></clipPath>
. Во-вторых, он не принимает параметр -d (DPI).Другое решение, которое я только что нашел здесь. Как визуализировать масштабированный SVG в QImage?
PySide легко устанавливается из бинарного пакета в Windows (и я использую его для других целей, поэтому мне это легко).
Однако я заметил несколько проблем при преобразовании флагов стран из Викимедиа, так что, возможно, это не самый надежный парсер / рендерер svg.
источник
Небольшое расширение ответа jsbueno:
источник
Я не нашел удовлетворительного ответа. Все упомянутые библиотеки имеют ту или иную проблему, например, отказ Каира от поддержки python 3.6 (они отказались от поддержки Python 2 около 3 лет назад!). Кроме того, установка упомянутых библиотек на Mac была проблемой.
Наконец, я нашел лучшее решение - svglib + reportlab . Оба были установлены без проблем с использованием pip, и первый вызов для преобразования из svg в png работал прекрасно! Очень доволен решением.
Всего две команды делают свое дело:
Есть ли какие-то ограничения, о которых я должен знать?
источник
Масштабирование SVG и рендеринг PNG
Используя pycairo и librsvg, я смог добиться масштабирования SVG и рендеринга в растровое изображение. Предполагая, что ваш SVG не совсем 256x256 пикселей, желаемый результат вы можете прочитать в SVG в контексте Cairo с помощью rsvg, а затем масштабировать его и записать в PNG.
main.py
Привязка RSVG C
С веб-сайта Cario с небольшими изменениями. Также хороший пример того, как вызвать C-библиотеку из Python
источник
Handle.get_dimension_data
у меня не получилось. Мне пришлось заменить его простой загрузкойself.props.width
иself.props.height
. Сначала я попытался определитьRsvgDimensionData
структуру, как описано на веб-сайте cairo, но безуспешно.Вот подход, при котором Inkscape вызывается Python.
Обратите внимание, что он подавляет некоторые неаккуратные выходные данные, которые Inkscape записывает в консоль (в частности, stderr и stdout) во время нормальной безошибочной работы. Вывод фиксируется в двух строковых переменных
out
иerr
.Например, при выполнении определенного задания в моей системе Mac OS
out
получилось:(Размер входного файла SVG составлял 339 на 339 пикселей.)
источник
На самом деле, я не хотел зависеть ни от чего другого, кроме Python (Cairo, Ink ... и т. Д.). Мои требования должны были быть как можно более простыми
pip install "savior"
, в лучшем случае достаточно простого , поэтому ни одно из вышеперечисленных не выполнялось. t подходит для меня.Я прошел через это (идя дальше, чем Stackoverflow в исследовании). https://www.tutorialexample.com/best-practice-to-python-convert-svg-to-png-with-svglib-python-tutorial/
Пока все выглядит хорошо. Так что я разделяю это на случай, если кто-то окажется в такой же ситуации.
источник