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

У меня есть файл 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

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

Ответ 1

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

inkscape -z -e test.png -w 1024 -h 1024 test.svg

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

enter image description here

enter image description here

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

Inkscape 0.48.3.1 r9886 (Mar 29 2012)

а в Windows 7 это:

Inkscape 0.48.4 r9939 (Dec 17 2012)

Ответ 2

Попробуйте 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, спасибо!

Ответ 3

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

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

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

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

Ответ 4

Если вы находитесь на 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.

Ответ 5

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

Svgexport - это программа node.js и поэтому не рекомендуется.

Imagemagick convert работает нормально:

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

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

BEST

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

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

~$ rsvg --help

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

Ответ 6

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

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

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

Ответ 7

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

convert -density 144 source.svg target.png

Ответ 8

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

FOR %% x IN (*.svg) DO C:\Ink\App\Inkscape\inkscape.exe %% x -z --export-dpi = 500 --экспорт-область-чертеж --export-png = "%% ~ nx.png"

Ответ 9

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

rsvg drawing.svg drawing.png

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

Ответ 10

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

Ответ 11

Я решил эту проблему, изменив атрибуты 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

Ответ 12

Для простого преобразования 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]

Ответ 13

Без librsvg вы можете получить черное изображение в формате png/jpeg. Мы должны установить svg файл librsvg в convert с помощью 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

Ответ 14

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

Не существует "магического" параметра, который будет делать то, что вы хотите.

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

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

convert button.svg button1.png


enter image description here

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

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


convert -density 983 button.svg button2.png


enter image description here

В 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

Ответ 15

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

и получил Kenney UI Pack messed up

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

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

(Это изображение от пакеты активов Kenney.nl кстати)