Comment convertir un SVG en PNG avec ImageMagick?

389

J'ai un fichier SVG qui a une taille définie de 16x16. Lorsque j'utilise le programme de conversion d'ImageMagick pour le convertir en PNG, j'obtiens un PNG 16x16 pixels qui est beaucoup trop petit:

convert test.svg test.png

Je dois spécifier la taille de pixel du PNG de sortie. -sizesemble être ignoré, le -scaleparamètre met à l'échelle le PNG après sa conversion en PNG. Le meilleur résultat obtenu jusqu'à présent en utilisant le -densityparamètre:

convert -density 1200 test.svg test.png

Mais je ne suis pas satisfait, car je veux spécifier la taille de sortie en pixels sans faire de calcul pour calculer la valeur de densité. Je veux donc faire quelque chose comme ça:

convert -setTheOutputSizeOfThePng 1024x1024 test.svg test.png

Alors, quel est le paramètre magique que je dois utiliser ici?

kayahr
la source
6
par exemple -size 1024x1024fonctionne bien, quelle est votre version imagemagick?
Dejan Marjanovic
2
ImageMagick-6.9.0-Q16. convert -resize 1024x1024 foo.svg foo.png fonctionne très bien.
Jichao
11
@Jichao -resizeétire simplement l'image convertie, avec des résultats de mauvaise qualité.
Elist
5
convert -size 1024x1024 test.svg test.pngfonctionne bien avec ImageMagick 7.0.7-0 Q16 (version actuelle dans Chocolatey repo pour Windows). Assurez-vous simplement qu'il -sizeapparaît avant le nom du fichier d'entrée, sinon une image 16x16 sera mise à l'échelle pour donner un résultat flou.
Futal

Réponses:

502

Je n'ai pas pu obtenir de bons résultats d'ImageMagick dans ce cas, mais Inkscape le fait très bien sous Linux et Windows:

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

Edit (mai 2020): Utilisateurs d'Inkscape 1.0, veuillez noter que les arguments de la ligne de commande ont changé:

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

Voici le résultat de la mise à l'échelle d'un SVG 16x16 en PNG 200x200 à l'aide de cette commande:

entrez la description de l'image ici

entrez la description de l'image ici

Juste pour référence, ma version d'Inkscape (sur Ubuntu 12.04) est:

Inkscape 0.48.3.1 r9886 (Mar 29 2012)

et sur Windows 7, c'est:

Inkscape 0.48.4 r9939 (Dec 17 2012)
808sound
la source
15
+1 en ce qui concerne imagemagick. Il semble y avoir un problème avec le moteur SVG. Dans la plupart des cas, je n'ai pas pu obtenir de résultats précis avec. Inkscape, OTOH, fonctionne parfaitement bien.
Glutanimate
13
Je pense qu'Inkscape est l'exemple le plus impressionnant d'OSS après Linux lui-même. Merci pour le conseil!
kim3er
8
Fonctionne également très bien sur OSX.
Jonas Granvik
12
Sur OSX, avec Inkscape installé pour X11, cela a fonctionné pour moi en utilisant:/Applications/Inkscape.app/Contents/Resources/bin/inkscape -z -e test.png -w 1024 -h 1024 test.svg
chmullig
11
@ Rörd Pour garder l'arrière-plan transparent avec ImageMagick, utilisez l' -background noneoption de ligne de commande.
John
142

Essayez svgexport :

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

svgexport est un simple outil de ligne de commande multiplateforme que j'ai créé pour exporter des fichiers svg en jpg et png, voir ici pour plus d'options. Pour installer svgexport, installez npm , puis exécutez:

npm install svgexport -g

Edit: Si vous rencontrez un problème avec la bibliothèque, veuillez le soumettre sur GitHub, merci!

Ali Shakiba
la source
4
svgexport a très bien fonctionné pour moi. La sortie correspond au rendu du navigateur beaucoup plus étroitement que ImageMagick.
t9mike
5
La qualité de svgexport est vraiment aussi élevée. Maintenant, c'est devenu mon outil préféré, merci shakiba! :)
Alessio Periloso
1
cela a bien fonctionné pour moi aussi. Économiseur de temps réel par rapport à le faire manuellement dans un outil GUI. Assez difficile de trouver une application GUI sur mac dans la gamme la moins chère de toute façon qui gère bien SVG
Erik Engheim
4
Fonctionne très bien, mais produit une image énorme. En utilisant optipng, j'ai pu compresser mon logo texte de 3 mégaoctets à environ 20 Ko.
miek
2
evgexport crée d'énormes fichiers png en fonction de la taille. Recommander svg2png qui utilise également PhantomJS pour l'exportation, mais crée des images beaucoup plus petites.
Aaron_H
112

Ce n'est pas parfait mais ça fait l'affaire.

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

Fondamentalement, cela augmente le DPI suffisamment haut (utilisez simplement une supposition éclairée / sûre) pour que le redimensionnement soit effectué avec une qualité adéquate. J'essayais de trouver une solution appropriée à cela, mais après un certain temps, j'ai décidé que c'était assez bon pour mes besoins actuels.

Remarque: utilisez 200x200! pour forcer la résolution donnée

Hardev
la source
4
Opacité et ombres perdues dans mon cas.
jiyinyiyong
2
Je n'ai pas de svg complexe, donc cela a fonctionné pour moi. -resize 200%n'a pas fonctionné et j'ai dû spécifier la taille en pixels.
jozxyqk
18
@jiyinyiyong Pour garder l'arrière-plan transparent avec ImageMagick, utilisez l' -background noneoption de ligne de commande. Pour conserver le rapport d'image, vous pouvez également spécifier une seule dimension comme la -resize 200largeur ou la -resize x200hauteur. Voir: imagemagick.org/script/command-line-processing.php#geometry pour des options de géométrie ImageMagick exhaustives .
John
ne fonctionne pas non plus pour moi. Le résultat est tout flou.
mbonnin
(cela s'applique à linux, peut s'appliquer aux fenêtres) si vous activez -verbose sur IM, il semblerait que IM utilise lui-même inkscape pour créer un fichier eps intermédiaire. donc je suggérerais d'utiliser inkscape directement comme suggéré par @ 808sound
northern-bradley
55

Si vous utilisez MacOS X et rencontrez des problèmes avec la conversion d'Imagemagick, vous pouvez essayer de le réinstaller avec RSVG lib. Utilisation de HomeBrew:

brew remove imagemagick
brew install imagemagick --with-librsvg

Vérifiez qu'il délègue correctement:

$ 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

Il devrait s'afficher rsvg.

Jose Alban
la source
Ça n'a pas marché pour moi. Plus précisément, j'ai couru convert ic_comment_48px.svg -size 30x30 ic_comment_30px.pnget l'image de sortie est de 48 x 48. Assurez-vous que imagemagick délègue à rsvg comme vous l'avez expliqué.
Shane Creighton-Young
1
Fonctionné parfaitement pour moi - la valeur par défaut convertconvertissait svg en png, mais les résultats étaient désespérés; après la réinstallation, ils sont parfaits. De plus, la conversion est nettement plus rapide.
ssc
1
Cela m'a fonctionné sur Mac OSX. Je ne trouve pas la nouvelle conversion plus rapide, mais beaucoup plus précise. Je recommande fortement à tous les utilisateurs de Mac OSX d'essayer.
HelloWorld
1
Ce devrait être la réponse acceptée, eh bien. Merci, travaillé comme un charme, et je n'aurais jamais su prendre ces mesures autrement
sdailey
8
Sur Mojave je reçoisinvalid option: --with-librsvg
Zaitsman
39

Inkscape ne semble pas fonctionner lorsque les unités svg ne le sont pas px(par exemple cm). J'ai une image vierge. Peut-être que cela pourrait être corrigé en tournant le dpi, mais c'était trop gênant.

Svgexport est un programme node.js et n'est donc généralement pas utile.

La conversion d'Imagemagick fonctionne correctement avec:

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

Si vous utilisez -resize, l'image est floue et le fichier est beaucoup plus volumineux.

MEILLEUR

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

Il est le plus rapide, a le moins de dépendances et la sortie est environ 30% plus petite que convertie. Installez librsvg2-bin pour l'obtenir. Il ne semble pas y avoir de page de manuel mais vous pouvez taper:

~$ rsvg --help

pour obtenir de l'aide. C'est simple c'est bien.

septembre_converter
la source
2
C'est facilement la meilleure réponse (je ne sais pas pourquoi vingt réponses différentes donnent la même réponse imagemagick); il préserve les couleurs et les ombres et ne gâche rien. Cependant, pour correspondre au comportement de redimensionnement imagemagick (en particulier, WxH signifie que l'image est mise à l'échelle pour tenir dans une boîte de cette taille, en préservant le rapport hauteur / largeur), le -aparamètre doit être utilisé avec rsvg.
Mahmoud Al-Qudsi
1
Cela a mutilé mes images, toutes sortes d'artefacts étranges. inkscape a fait un meilleur travail.
dés élégants
1
Soyez averti, brew install rsvgsur OSX installe un million de choses - GDK, OpenSSL, Python, etc.
Timmmm
4
Pour info, la commande d'installation actuelle est brew install librsvget la commande de conversion l'est rsvg-convert.
waldyrious
J'ai trouvé que librsvg (ou rsvg-convertdans le cas d'Arch) donnait les meilleurs résultats et les plus cohérents lors de la conversion de svgs compliqués en png. Suivi avec optipngpour réduire la taille du fichier de sortie.
maktel
18

Après avoir suivi les étapes de la réponse de Jose Alban , j'ai réussi à faire fonctionner correctement ImageMagick en utilisant la commande suivante:

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

Le nombre 1536 provient d'une estimation approximative de la densité, voir cette réponse pour plus d'informations.

Ian
la source
15

Afin de redimensionner l'image, l'option -densitydoit être utilisée. Pour autant que je sache, la densité standard est de 72 et correspond à la taille 1: 1. Si vous souhaitez que le png de sortie soit deux fois plus grand que le svg d'origine, définissez la densité sur 72 * 2 = 144:

convert -density 144 source.svg target.png
Stanislav Schmidt
la source
Notez que les options de conversion doivent être antérieures au fichier d'entrée. Ie convert source.svg -density 144 target.pngne redimensionnera pas l'image.
Skippy le Grand Gourou
En fait, la densité standard semble être de 90. Il en serait ainsiconvert -density 180 source.svg target.png
adius
7

pourquoi ne pas essayer la ligne de commande inkscape, voici mon fichier bat pour convertir tous les svg de ce dir en png:

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

ampecs
la source
4

Je suis venu à ce poste - mais je voulais juste faire la conversion par lot et rapidement sans utiliser de paramètres (en raison de plusieurs fichiers de tailles différentes).

rsvg drawing.svg drawing.png

Pour moi, les exigences étaient probablement un peu plus faciles que pour l'auteur d'origine. (Je voulais utiliser des SVG dans MS PowerPoint, mais cela ne le permet pas)

Qohelet
la source
1
Pour référence, sur macOS, cela est installé avec brew install librsvget la commande de conversion est rsvg-convert.
waldyrious
dans Ubutni, il est également converti en rsvg, le paquet est librsvg2-bin et la sortie a besoin de -o
drawing.png
4

Dans ImageMagick, on obtient un meilleur rendu SVG si on utilise Inkscape ou RSVG avec ImageMagick que son propre rendu interne MSVG / XML. RSVG est un délégué qui doit être installé avec ImageMagick. Si Inkscape est installé sur le système, ImageMagick l'utilisera automatiquement. J'utilise Inkscape dans ImageMagick ci-dessous.

Il n'y a pas de paramètre "magique" qui fera ce que vous voulez.

Mais, on peut calculer très simplement la densité exacte nécessaire pour rendre la sortie.

Voici un petit bouton 50x50 lorsqu'il est rendu à la densité par défaut de 96:

convert button.svg button1.png


entrez la description de l'image ici

Supposons que nous voulons que la sortie soit de 500. L'entrée est de 50 à une densité par défaut de 96 (les anciennes versions d'Inkscape peuvent utiliser 92). Vous pouvez donc calculer la densité nécessaire en proportion des rapports des dimensions et des densités.

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


convert -density 983 button.svg button2.png


entrez la description de l'image ici

Dans ImageMagick 7, vous pouvez effectuer le calcul en ligne comme suit:

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
fmw42
la source
l'équation dans magick DSL a été très utile!
cyrf
2

Une chose qui m'a tout simplement mordu était la définition de -densityAPRÈS le nom du fichier d'entrée. Ça n'a pas marché. Le déplacer vers la première option de conversion (avant toute autre chose) l'a fait fonctionner (pour moi, YMMV, etc.).

pseudo
la source
2

Pour une conversion SVG en PNG simple, j'ai trouvé que cairosvg ( https://cairosvg.org/ ) fonctionne mieux qu'ImageMagick. Étapes d'installation et d'exécution sur tous les fichiers SVG de votre répertoire.

pip3 install cairosvg

Ouvrez un shell python dans le répertoire qui contient vos fichiers .svg et exécutez:

import os

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

Cela vous permettra également de ne pas écraser vos fichiers .svg d'origine, mais de conserver le même nom. Vous pouvez ensuite déplacer tous vos fichiers .png vers un autre répertoire avec:

$ mv *.png [new directory]
edank
la source
s'est écrasé pour moi sur Windows 10: importer cairocffi en tant que fichier cairo "c: \ program files (x86) \ python35-32 \ lib \ site-packages \ cairocffi_ init_ .py", ligne 39, dans <module> cairo = dlopen (ffi , 'cairo', 'cairo-2', 'cairo-gobject-2', 'cairo.so.2') Fichier "c: \ program files (x86) \ python35-32 \ lib \ site-packages \ cairocffi_ init_ .py ", ligne 36, dans dlopen lever OSError (" dlopen () n'a pas réussi à charger une bibliothèque:% s "% '/' .join (names)) OSError: dlopen () n'a pas réussi à charger une bibliothèque: cairo / cairo- 2 / cairo-gobject-2 / cairo.so.2
Pete Lomax
Nice, cairosvgsur Ubuntu-19.04 a fait le travail pour moi.
fhgd
2

Sans librsvg, vous pouvez obtenir une image png / jpeg noire. Nous devons installer librsvgde convertfichier svg avec 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
TLbiz
la source
Je n'ai pas cette bibliothèque installée et je n'ai pas non plus d'images noires.
Aaron Franke
1

J'ai résolu ce problème en modifiant les attributs widthet heightde la <svg>balise pour qu'elle corresponde à la taille de sortie souhaitée, puis en la convertissant à l'aide d'ImageMagick. Fonctionne comme un charme.

Voici mon code Python, une fonction qui retournera le contenu du fichier 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
Yanone
la source
2
pourquoi voudriez-vous retourner une image générée par ordinateur au format jpeg :(?
Willi Mentzel
1

La meilleure réponse de @ 808sound n'a pas fonctionné pour moi. Je voulais redimensionner Kenney.nl UI Pack

et j'ai Kenney UI Pack foiré

Au lieu de cela, j'ai ouvert Inkscape, puis je suis allé à File, Export as PNG fileet une boîte GUI est apparue qui m'a permis de définir les dimensions exactes dont j'avais besoin.

Version sur Ubuntu 16.04 Linux: Inkscape 0.91 (September 2016)

(Cette image est d' ailleurs des packs d'actifs de Kenney.nl )

James L.
la source
1

Sur macOS en utilisant brew, utiliser librsvg fonctionne directement bien

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

De nombreuses options sont disponibles via rsvg-convert --help

mloughran
la source
0

Sur Linux avec Inkscape 1.0 pour convertir de svg en png, vous devez utiliser

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

ne pas

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