Як перетворити SVG в PNG за допомогою ImageMagick?


388

У мене є файл 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. перетворити -розмір 1024x1024 foo.svg foo.png працює чудово.
Jichao

11
@Jichao -resizeпросто розтягує перетворене зображення з низькою якістю результатів.
Еліст

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

Відповіді:


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 install npm , запустіть:

npm install svgexport -g

Редагувати: Якщо ви знайшли проблему з бібліотекою, надішліть її на GitHub, дякую!


4
svgexport чудово працював для мене. Вихід відповідає рендерингу браузера набагато ближче, ніж ImageMagick.
t9mike

5
Якість svgexport насправді така висока. Тепер це стало моїм улюбленим інструментом, дякую шакіба! :)
Алессіо Перилосо,

1
це добре працювало і для мене. Заставка в режимі реального часу порівняно з тим, як це робити вручну в інструменті GUI. Досить важко знайти додаток GUI на 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 на чат, то, здається, чат сам використовує Inkscape для створення проміжного файлу eps. Тому я запропонував би використовувати Inkscape безпосередньо як це було запропоновано @ 808sound
північна-Bradley

55

Якщо ви перебуваєте на MacOS X і маєте проблеми з перетворенням Imagemagick, ви можете спробувати перевстановити його за допомогою lib RSVG. Використання 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 х 48. Переконайтесь, що imagemagick делегується до rsvg, як ви пояснили.
Шейн Крейтон-Янг

1
Для мене прекрасно працював - за замовчуванням convertконвертував svg в png, але результати були безнадійними; після перевстановлення вони ідеальні. Також конверсія значно швидша.
ssc

1
Це працювало мені на Mac OSX. Я не знаходжу нову конверсію швидше, але набагато точніше. Я настійно рекомендую всім користувачам Mac OSX спробувати це.
HelloWorld

1
Це має бути прийнята відповідь, ну добре. Дякую, працював як шарм, і я ніколи не знав би зробити ці кроки інакше
sdailey

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
Це легко найкраща відповідь (я не знаю, чому двадцять різних відповідей дають ту саму відповідь imagemagick); він зберігає кольори і тіні і нічого не манить. Однак, щоб відповідати поведінці зміни розміру Imagemagick (зокрема, WxH означає масштабне зображення, яке вміщується у вікні такого розміру, зберігаючи співвідношення сторін), -aпараметр слід використовувати з rsvg.
Махмуд Аль-Кудсі

1
Це зіпсувало мої зображення, всілякі дивні артефакти. Inkscape зробив кращу роботу.
елегантні кубики

1
Будьте попереджені: brew install rsvgна OSX встановлюється мільйон речей - GDK, OpenSSL, Python тощо.
Timmmm

4
FYI, поточна команда встановлення - brew install librsvgце команда перетворення rsvg-convert.
waldyrious

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

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зображення не змінити масштаб.
Skippy le Grand Gourou

Насправді стандартна щільність, здається, дорівнює 90. Так було бconvert -density 180 source.svg target.png
adius

7

чому б вам не спробувати команду командного рядка Inkscape, це мій файл bat, щоб перетворити весь svg у цьому dir у png:

ДЛЯ %% x IN (* .svg) DO C: \ Ink \ App \ Inkscape \ inkscape.exe %% x -z --export-dpi = 500 - малюнок-експорт-області --export-png = "% % ~ nx.png "


4

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

rsvg drawing.svg drawing.png

Для мене вимоги були, мабуть, трохи простішими, ніж для оригінального автора. (Хотіли використовувати SVG в MS PowerPoint, але це не дозволяє)


1
Для довідки, на macOS це встановлено з brew install librsvgкомандою перетворення rsvg-convert.
waldyrious

в Ubutni він також перетворює rsvg, пакет - librsvg2-bin, а вихід потрібен -o
малюнок.png

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ПІСЛЯ назви вхідного файлу. Це не спрацювало. Переміщення його до першого варіанту в перетворенні (перш ніж все інше) змусило його працювати (для мене, 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: \ програмні файли (x86) \ python35-32 \ lib \ site-пакети \ cairocffi_ init_ .py", рядок 39, в <module> cairo = dlopen (ffi , 'cairo', 'cairo-2', 'cairo-gobject-2', 'cairo.so.2') Файл "c: \ програмні файли (x86) \ python35-32 \ lib \ site-пакети \ cairocffi_ init_ .py ", рядок 36, в dlopen підвищити OSError (" dlopen () не вдалося завантажити бібліотеку:% s "% '/' .join (імена)) OSError: dlopen () не вдалося завантажити бібліотеку: cairo / cairo- 2 / cairo-gobject-2 / cairo.so.2
Піт Ломакс

Приємно, що cairosvgUbuntu-19.04 зробив роботу за мене.
fhgd

2

Без librsvg ви можете отримати чорне зображення png / jpeg. Ми повинні встановити librsvgвconvert SVG файл з 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

і отримав Пакет інтерфейсу Кенні заплутався

Тому замість цього я відкрив 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.