Как конвертировать SVG в PNG с помощью ImageMagick?


389

У меня есть файл SVG, который имеет определенный размер 16x16. Когда я использую программу преобразования ImageMagick для преобразования ее в PNG, я получаю PNG размером 16x16 пикселей, который слишком мал:

convert test.svg test.png

Мне нужно указать размер пикселя выходного PNG. -sizeПараметр, кажется, игнорируется, -scaleпараметр масштабирует PNG после его преобразования в PNG. Лучший результат до сих пор я получал, используя -densityпараметр:

convert -density 1200 test.svg test.png

Но я не удовлетворен, потому что я хочу указать размер вывода в пикселях без математических вычислений для расчета значения плотности. Поэтому я хочу сделать что-то вроде этого:

convert -setTheOutputSizeOfThePng 1024x1024 test.svg test.png

Так какой магический параметр я должен использовать здесь?


6
например -size 1024x1024, работает нормально, какая у вас версия imagemagick?
Деян Марьянович


2
ImageMagick-6.9.0-Q16. convert -resize 1024x1024 foo.svg foo.png работает отлично.
Jichao

11
@Jichao -resizeпросто растягивает преобразованное изображение с плохим качеством.
Elist

5
convert -size 1024x1024 test.svg test.pngотлично работает с ImageMagick 7.0.7-0 Q16 (текущая версия в Chocolatey repo для Windows). Просто убедитесь, что оно -sizeпоявляется перед входным именем файла, иначе изображение 16x16 будет увеличено, чтобы получить размытый результат.
Futal

Ответы:


502

Мне не удалось получить хорошие результаты от ImageMagick в этом случае, но Inkscape отлично справляется с этой задачей на Linux и Windows:

inkscape -z -w 1024 -h 1024 input.svg -e output.png

Редактирование (май 2020 г.): пользователи Inkscape 1.0, обратите внимание, что аргументы командной строки изменились:

inkscape -w 1024 -h 1024 input.svg --export-filename output.png

Вот результат масштабирования SVG 16x16 до PNG 200x200 с помощью этой команды:

введите описание изображения здесь

введите описание изображения здесь

Просто для справки, моя версия Inkscape (на Ubuntu 12.04):

Inkscape 0.48.3.1 r9886 (Mar 29 2012)

а в Windows 7 это:

Inkscape 0.48.4 r9939 (Dec 17 2012)

15
+1, что касается imagemagick. Кажется, есть проблема с двигателем SVG. В большинстве случаев я не смог получить точные результаты с ним. Inkscape, OTOH, работает отлично.
Glutanimate

13
Я думаю, что Inkscape - самый впечатляющий пример OSS после самого Linux. Спасибо за совет!
kim3er

8
Хорошо работает и на OSX.
Джонас Гранвик

12
На OSX, с установленным Inkscape для X11, он работал для меня, используя:/Applications/Inkscape.app/Contents/Resources/bin/inkscape -z -e test.png -w 1024 -h 1024 test.svg
chmullig

11
@ Rörd Чтобы сохранить фон прозрачным с помощью ImageMagick, используйте параметр -background noneкомандной строки.
Джон

142

Попробуйте svgexport :

svgexport input.svg output.png 64x
svgexport input.svg output.png 1024:1024

svgexport - это простой кроссплатформенный инструмент командной строки, который я создал для экспорта файлов svg в jpg и png. Дополнительные параметры см. здесь . Чтобы установить svgexport, установите npm и запустите:

npm install svgexport -g

Изменить: Если вы обнаружите проблему с библиотекой, пожалуйста, отправьте ее на GitHub, спасибо!


4
svgexport отлично работал для меня. Вывод соответствует рендерингу браузера гораздо ближе, чем ImageMagick.
t9mike

5
Качество svgexport действительно так высоко. Теперь это стало моим любимым инструментом, спасибо Shakiba! :)
Алессио Перилосо

1
это хорошо сработало и для меня. Экономия времени по сравнению с выполнением вручную в инструменте с графическим интерфейсом. В любом случае, довольно сложно найти приложение с графическим интерфейсом для Mac в более дешевом диапазоне, которое хорошо справляется с SVG
Эрик Энгхайм,

4
Прекрасно работает, но выдает огромное изображение. Используя optipng, я смог сжать текстовый логотип с 3 мегабайт до ~ 20 КБ.
miek

2
evgexport создает огромные png файлы в зависимости от размера. Рекомендуйте svg2png, который также использует PhantomJS для экспорта, но создает намного меньшие изображения.
Aaron_H

112

Это не идеально, но это делает работу.

convert -density 1200 -resize 200x200 source.svg target.png

В основном это увеличивает DPI достаточно высоко (просто используйте обоснованное / безопасное предположение), что изменение размера выполняется с адекватным качеством. Я пытался найти правильное решение для этого, но через некоторое время решил, что это достаточно хорошо для моей текущей потребности.

Примечание: используйте 200x200! заставить данное разрешение


4
Непрозрачность и тени потеряны в моем случае.
Jiyinyiyong

2
У меня нет сложных SVG, так что это сработало для меня. -resize 200%не работал, и мне пришлось указать размер в пикселях.
Jozxyqk

18
@jiyinyiyong Чтобы сохранить фон прозрачным с помощью ImageMagick, используйте параметр -background noneкомандной строки. Чтобы сохранить соотношение изображения, вы также можете указать только одно измерение, например, -resize 200для ширины или -resize x200высоты. См. Imagemagick.org/script/command-line-processing.php#geometry для исчерпывающих параметров геометрии ImageMagick .
Джон

у меня тоже не работает Результат все размыто.
mbonnin

(это относится к linux, может относиться к windows), если вы включите -verbose для IM, тогда может показаться, что для создания промежуточного eps-файла IM использует сам inkscape. поэтому я бы предложил использовать inkscape напрямую, как это было предложено @ 808sound
Northern-Bradley

55

Если вы используете MacOS X и у вас есть проблемы с конвертированием Imagemagick, вы можете попробовать переустановить его с помощью RSVG lib. Использование HomeBrew:

brew remove imagemagick
brew install imagemagick --with-librsvg

Убедитесь, что он делегирует правильно:

$ convert -version
Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-12-17 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules
Delegates: bzlib cairo fontconfig freetype jng jpeg lcms ltdl lzma png rsvg tiff xml zlib

Это должно отобразить rsvg.


Не работал для меня В частности, я запустил, convert ic_comment_48px.svg -size 30x30 ic_comment_30px.pngи выходное изображение было 48 x 48. Убедитесь, что imagemagick делегирует rsvg, как вы объяснили.
Шейн Крейтон-Янг,

1
У меня отлично сработало - по умолчанию convertконвертировал svg в png, но результаты были безнадежными; после переустановки они идеальны. Кроме того, преобразование значительно быстрее.
ССК

1
Это сработало у меня на Mac OSX. Я не нахожу новое преобразование быстрее, но гораздо более точным. Я настоятельно рекомендую всем пользователям Mac OSX попробовать.
HelloWorld

1
Это должен быть принятый ответ, да ладно. Спасибо, сработало как шарм, и я никогда бы не
узнал, что

8
На мохаве я получаюinvalid option: --with-librsvg
Зайцман

39

Кажется, что Inkscape не работает, если svg не работает px(например, см). Я получил пустое изображение. Может быть, это можно исправить, повернув dpi, но это было слишком хлопотно.

Svgexport - это программа node.js, поэтому она обычно не используется.

Преобразование Imagemagick работает нормально с:

 ~$ convert -background none -size 1024x1024 infile.svg outfile.png

Если вы используете -resize, изображение нечеткое и файл намного больше.

ЛУЧШИЙ

~$ rsvg  -w 1024 -h 1024 infile.svg  outfile.png

Он самый быстрый, имеет наименьшее количество зависимостей, а вывод примерно на 30% меньше, чем конвертирование. Установите librsvg2-bin, чтобы получить его. Похоже, что это не страница руководства, но вы можете ввести:

~$ rsvg --help

чтобы получить некоторую помощь. Простое это хорошо.


2
Это просто лучший ответ (я не знаю, почему двадцать разных ответов дают один и тот же ответ на изображение); он сохраняет цвета и тени и ничего не портит. Однако, чтобы соответствовать поведению изменения размера изображения (в частности, WxH означает масштабированное изображение, чтобы поместиться в блок такого размера, сохраняя соотношение сторон), -aпараметр должен использоваться с rsvg.
Махмуд Аль-Кудси

1
Это исказило мои изображения, всевозможные странные артефакты. Inkscape сделал лучшую работу.
элегантные кости

1
Будьте внимательны, brew install rsvgна OSX устанавливается миллион вещей - GDK, OpenSSL, Python и т. Д.
Timmmm

4
К вашему сведению, текущая команда установки brew install librsvgи команда преобразования rsvg-convert.
Вальдериус

Я обнаружил, что librsvg (или rsvg-convertв случае с Arch) дает лучшие и наиболее согласованные результаты при преобразовании сложных svgs в png. Выполните, optipngчтобы уменьшить размер выходного файла.
Мактел

18

После выполнения шагов, описанных в ответе Хосе Албана , я смог заставить ImageMagick работать нормально, используя следующую команду:

convert -density 1536 -background none -resize 100x100 input.svg output-100.png

Число 1536 исходит из приблизительной оценки плотности, см. Этот ответ для получения дополнительной информации.


15

Чтобы изменить масштаб изображения, -densityследует использовать эту опцию . Насколько я знаю, стандартная плотность составляет 72, а карты размером 1: 1. Если вы хотите, чтобы выходной png был вдвое больше исходного svg, установите плотность 72 * 2 = 144:

convert -density 144 source.svg target.png

Обратите внимание, что параметры преобразования должны быть перед входным файлом. Т.е. convert source.svg -density 144 target.pngне будет масштабировать изображение.
Скиппи ле Гран Гуру

На самом деле стандартная плотность, кажется, составляет 90. Так что это будетconvert -density 180 source.svg target.png
Adius

7

почему бы вам не попробовать в командной строке inkscape, это мой bat файл для преобразования всех svg в этом dir в png:

FOR %% x IN (* .svg) DO C: \ Ink \ App \ Inkscape \ inkscape.exe %% x -z --export-dpi = 500 --export-area-drawing --export-png = "% % ~ nx.png»


4

Я пришел к этому сообщению - но я просто хотел сделать преобразование пакетным и быстрым без использования каких-либо параметров (из-за нескольких файлов с разными размерами).

rsvg drawing.svg drawing.png

Для меня требования были, вероятно, немного проще, чем для первоначального автора. (Хотел использовать SVG в MS PowerPoint, но это не позволяет)


1
Для справки, в macOS это устанавливается с brew install librsvgпомощью команды преобразования rsvg-convert.
Вальдериус

в Убутни это тоже rsvg-convert, пакет - librsvg2-bin, и вывод требует -o drawing.png
teknopaul

4

В ImageMagick лучше получить SVG-рендеринг, если он использует Inkscape или RSVG с ImageMagick, чем его собственный внутренний рендеринг MSVG / XML. RSVG - это делегат, который должен быть установлен с ImageMagick. Если Inkscape установлен в системе, ImageMagick будет использовать его автоматически. Я использую Inkscape в ImageMagick ниже.

Нет «волшебного» параметра, который будет делать то, что вы хотите.

Но можно очень просто вычислить точную плотность, необходимую для визуализации вывода.

Вот небольшая кнопка 50x50 при рендеринге с плотностью 96 по умолчанию:

convert button.svg button1.png


введите описание изображения здесь

Предположим, мы хотим, чтобы на выходе было 500. На входе 50 при плотности по умолчанию 96 (более старые версии Inkscape могут использовать 92). Таким образом, вы можете вычислить необходимую плотность пропорционально отношениям размеров и плотностей.

512/50 = X/96
X = 96*512/50 = 983


convert -density 983 button.svg button2.png


введите описание изображения здесь

В ImageMagick 7 вы можете выполнять вычисления в строке следующим образом:

magick -density "%[fx:96*512/50]" button.svg button3.png

or

in_size=50
in_density=96
out_size=512

magick -density "%[fx:$in_density*$out_size/$in_size]" button.svg button3.png

уравнение в магии DSL было очень полезно!
cyrf

2

Одна вещь, которая только что укусила меня, была установка -densityПОСЛЕ имени входного файла. Это не сработало. Перемещение его к первому параметру в convert (прежде всего) заставило его работать (для меня, YMMV и т. Д.).


2

Для простого преобразования SVG в PNG я обнаружил, что cairosvg ( https://cairosvg.org/ ) работает лучше, чем ImageMagick. Шаги для установки и запуска всех файлов SVG в вашем каталоге.

pip3 install cairosvg

Откройте оболочку python в каталоге, содержащем ваши файлы .svg и запустите:

import os

for file in os.listdir('.'):
    name = file.split('.svg')[0]
    cairosvg.svg2png(url=name+'.svg',write_to=name+'.png') 

Это также гарантирует, что вы не перезапишите исходные файлы .svg, но сохраните то же имя. Затем вы можете переместить все ваши файлы .png в другой каталог с помощью:

$ mv *.png [new directory]

у меня произошел сбой на windows 10: импорт cairocffi как cairo Файл "c: \ program files (x86) \ python35-32 \ lib \ site-packages \ cairocffi_ init_ .py", строка 39, в <module> cairo = dlopen (ffi) , 'cairo', 'cairo-2', 'cairo-gobject-2', 'cairo.so.2') Файл "c: \ program files (x86) \ python35-32 \ lib \ site-packages \ cairocffi_ init_ .py ", строка 36, в dlopen повышение OSError (" dlopen () не удалось загрузить библиотеку:% s "% '/' .join (names)) OSError: dlopen () не удалось загрузить библиотеку: cairo / cairo- 2 / cairo-gobject-2 / cairo.so.2
Пит Ломакс,

Здорово, cairosvgна Ubuntu-19.04 мне сделали работу.
fhgd

2

Без librsvg вы можете получить черное изображение в формате png / jpeg. Мы должны установить librsvgв convertsvg файл с помощью imagemagick.

Ubuntu

 sudo apt-get install imagemagick librsvg
 convert -density 1200 test.svg test.png

MacOS

 brew install imagemagick librsvg
 convert -density 1200 test.svg test.png

У меня не установлена ​​эта библиотека, и я не получаю черные изображения.
Аарон Франке

1

Я решил эту проблему путем изменения widthи heightатрибутов <svg>тега , чтобы соответствовать моему предназначенному размеру вывода , а затем преобразовать его с помощью ImageMagick. Работает как шарм.

Вот мой код Python, функция, которая будет возвращать содержимое файла JPG:

import gzip, re, os
from ynlib.files import ReadFromFile, WriteToFile
from ynlib.system import Execute
from xml.dom.minidom import parse, parseString


def SVGToJPGInMemory(svgPath, newWidth, backgroundColor):

    tempPath = os.path.join(self.rootFolder, 'data')
    fileNameRoot = 'temp_' + str(image.getID())

    if svgPath.lower().endswith('svgz'):
        svg = gzip.open(svgPath, 'rb').read()
    else:
        svg = ReadFromFile(svgPath)

    xmldoc = parseString(svg)

    width = float(xmldoc.getElementsByTagName("svg")[0].attributes['width'].value.split('px')[0])
    height = float(xmldoc.getElementsByTagName("svg")[0].attributes['height'].value.split('px')[0])

    newHeight = int(newWidth / width * height) 

    xmldoc.getElementsByTagName("svg")[0].attributes['width'].value = '%spx' % newWidth
    xmldoc.getElementsByTagName("svg")[0].attributes['height'].value = '%spx' % newHeight

    WriteToFile(os.path.join(tempPath, fileNameRoot + '.svg'), xmldoc.toxml())
    Execute('convert -background "%s" %s %s' % (backgroundColor, os.path.join(tempPath, fileNameRoot + '.svg'), os.path.join(tempPath, fileNameRoot + '.jpg')))

    jpg = open(os.path.join(tempPath, fileNameRoot + '.jpg'), 'rb').read()

    os.remove(os.path.join(tempPath, fileNameRoot + '.jpg'))
    os.remove(os.path.join(tempPath, fileNameRoot + '.svg'))

    return jpg

2
почему вы возвращаете изображение, сгенерированное компьютером, в формате jpeg :(?
Вилли Ментзел

1

Лучший ответ от @ 808sound не сработал для меня. Я хотел изменить размер Kenney.nl UI Pack

и получил Кенни UI Pack испортил

Поэтому вместо этого я открыл Inkscape, затем пошел File, Export as PNG fileи появилось окно с графическим интерфейсом, которое позволило мне установить точные размеры, которые мне нужны.

Версия на Ubuntu 16.04 Linux: Inkscape 0.91 (September 2016)

( Кстати, это изображение из пакетов ресурсов Kenney.nl )


1

На macOS с использованием brew, использование librsvg напрямую работает

brew install librsvg
rsvg-convert test.svg -o test.png

Многие варианты доступны через rsvg-convert --help


0

В Linux с Inkscape 1.0 для конвертации из SVG в PNG необходимо использовать

inkscape -w 1024 -h 1024 input.svg --export-file output.png

не

inkscape -w 1024 -h 1024 input.svg --export-filename output.png
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.