Come convertire un SVG in un PNG con ImageMagick?


389

Ho un file SVG che ha una dimensione definita di 16x16. Quando uso il programma di conversione di ImageMagick per convertirlo in un PNG, ottengo un PNG di 16x16 pixel che è troppo piccolo:

convert test.svg test.png

Devo specificare la dimensione in pixel del PNG di output. -sizeil parametro sembra essere ignorato, il -scaleparametro ridimensiona il PNG dopo che è stato convertito in PNG. Il miglior risultato finora ottenuto usando il -densityparametro:

convert -density 1200 test.svg test.png

Ma non sono soddisfatto, perché voglio specificare la dimensione dell'output in pixel senza fare matematica per calcolare il valore della densità. Quindi voglio fare qualcosa del genere:

convert -setTheOutputSizeOfThePng 1024x1024 test.svg test.png

Quindi qual è il parametro magico che devo usare qui?


6
ad esempio -size 1024x1024funziona bene, qual è la tua versione di imagemagick?
Dejan Marjanovic il


2
ImageMagick-6.9.0-Q16. convert -resize 1024x1024 foo.svg foo.png funziona bene.
Jichao,

11
@Jichao -resizeallunga l'immagine convertita, con risultati di scarsa qualità.
Elist,

5
convert -size 1024x1024 test.svg test.pngfunziona bene con ImageMagick 7.0.7-0 Q16 (versione corrente nel repository Chocolatey per Windows). Assicurati solo che -sizeappaia prima del nome del file di input, altrimenti un'immagine 16x16 verrà ingrandita per dare un risultato sfocato.
Futal,

Risposte:


502

In questo caso non sono stato in grado di ottenere buoni risultati da ImageMagick, ma Inkscape fa un buon lavoro su Linux e Windows:

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

Modifica (maggio 2020): utenti di Inkscape 1.0, si noti che gli argomenti della riga di comando sono cambiati:

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

Ecco il risultato del ridimensionamento di un SVG 16x16 in un PNG 200x200 usando questo comando:

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

Solo per riferimento, la mia versione di Inkscape (su Ubuntu 12.04) è:

Inkscape 0.48.3.1 r9886 (Mar 29 2012)

e su Windows 7, è:

Inkscape 0.48.4 r9939 (Dec 17 2012)

15
+1 per quanto riguarda imagemagick. Sembra che ci siano problemi con il motore SVG. Nella maggior parte dei casi non sono stato in grado di ottenere risultati accurati con esso. Inkscape, OTOH, funziona perfettamente.
Glutanimate,

13
Penso che Inkscape sia l'esempio più impressionante di OSS dopo Linux stesso. Grazie per il consiglio!
kim3er,

8
Funziona bene anche su OSX.
Jonas Granvik,

12
Su OSX, con Inkscape installato per X11, ha funzionato per me usando:/Applications/Inkscape.app/Contents/Resources/bin/inkscape -z -e test.png -w 1024 -h 1024 test.svg
chmullig

11
@ Rörd Per mantenere lo sfondo trasparente con ImageMagick, utilizzare l' -background noneopzione della riga di comando.
Giovanni

142

Prova svgexport :

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

svgexport è un semplice strumento da riga di comando multipiattaforma che ho creato per esportare file svg in jpg e png, vedi qui per ulteriori opzioni. Per installare svgexport install npm , quindi eseguire:

npm install svgexport -g

Modifica: se trovi un problema con la libreria, ti preghiamo di inviarlo su GitHub, grazie!


4
svgexport ha funzionato benissimo per me. L'output corrisponde al rendering del browser molto più da vicino di ImageMagick.
t9mike

5
la qualità di svgexport è davvero così alta. Ora è diventato il mio strumento preferito, grazie shakiba! :)
Alessio Periloso,

1
questo ha funzionato bene anche per me. Risparmio in tempo reale rispetto a farlo manualmente in uno strumento GUI. Abbastanza difficile trovare un'app GUI su Mac nella gamma più economica che comunque gestisca bene SVG
Erik Engheim,

4
Funziona alla grande, ma produce un'immagine enorme. Usando optipng, sono stato in grado di comprimere il mio logo di testo da 3 megabyte a ~ 20kB.
miek,

2
evgexport crea file PNG ENORMI in base alla dimensione. Consiglia svg2png che utilizza anche PhantomJS per l'esportazione, ma crea immagini molto più piccole.
Aaron_H il

112

Questo non è perfetto ma fa il lavoro.

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

Fondamentalmente aumenta il DPI abbastanza in alto (basta usare un'ipotesi colta / sicura) che il ridimensionamento sia fatto con una qualità adeguata. Stavo cercando di trovare una soluzione adeguata a questo, ma dopo un po 'ho deciso che era abbastanza buono per il mio attuale bisogno.

Nota: utilizzare 200x200! per forzare la risoluzione data


4
Opacità e ombre perse nel mio caso.
jiyinyiyong

2
Non ho svg complessi quindi questo ha funzionato per me. -resize 200%non ha funzionato e ho dovuto specificare la dimensione in pixel.
jozxyqk,

18
@jiyinyiyong Per mantenere lo sfondo trasparente con ImageMagick, utilizzare l' -background noneopzione della riga di comando. Per mantenere il rapporto dell'immagine, puoi anche specificare solo una dimensione come -resize 200per larghezza o -resize x200altezza. Vedi: imagemagick.org/script/command-line-processing.php#geometry per opzioni esaustive sulla geometria di ImageMagick .
Giovanni

non funziona neanche per me. Il risultato è tutto sfocato.
mbonnin,

(questo vale per Linux, può applicarsi a Windows) se si attiva -verbose su IM, sembrerebbe che IM stesso usi inkscape per creare un file eps intermedio. quindi suggerirei di usare direttamente l'inkscape come suggerito da @ 808sound
Northern-

55

Se sei su MacOS X e hai problemi con la conversione di Imagemagick, potresti provare a reinstallarlo con RSVG lib. Utilizzando HomeBrew:

brew remove imagemagick
brew install imagemagick --with-librsvg

Verifica che stia delegando correttamente:

$ 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

Dovrebbe essere visualizzato rsvg.


Non ha funzionato per me. In particolare ho eseguito convert ic_comment_48px.svg -size 30x30 ic_comment_30px.pnge l'immagine di output è 48 x 48. Assicurati che imagemagick stia delegando a rsvg come hai spiegato.
Shane Creighton-Young,

1
Ha funzionato perfettamente per me - il valore predefinito convertconvertiva svg in png, ma i risultati erano senza speranza; dopo la reinstallazione, sono perfetti. Inoltre, la conversione è significativamente più veloce.
ssc,

1
Questo mi ha funzionato su Mac OSX. Non trovo la nuova conversione più veloce, ma molto più accurata. Consiglio vivamente a tutti gli utenti Mac OSX di provare.
HelloWorld,

1
Questa dovrebbe essere la risposta accettata, vabbè. Grazie, ha funzionato come un incantesimo, e non avrei mai saputo di fare questi altri passi
sdailey

8
Su mojave ottengoinvalid option: --with-librsvg
zaitsman il

39

Inkscape non sembra funzionare quando le unità svg non lo sono px(ad es. Cm). Ho un'immagine vuota. Forse, potrebbe essere risolto modificando il dpi, ma era troppo problematico.

Svgexport è un programma node.js e quindi generalmente non utile.

Il convertito di Imagemagick funziona bene con:

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

Se si utilizza -resize, l'immagine è sfocata e il file è molto più grande.

MIGLIORE

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

È più veloce, ha il minor numero di dipendenze e l'output è circa il 30% più piccolo rispetto alla conversione. Installa librsvg2-bin per ottenerlo. Non sembra esserci una pagina man ma puoi digitare:

~$ rsvg --help

per ottenere assistenza. Semplice è buono.


2
Questa è facilmente la risposta migliore (non so perché venti risposte diverse diano la stessa risposta da immagine); conserva colori e ombre e non manipola nulla. Tuttavia, per abbinare il comportamento di ridimensionamento di imagemagick (in particolare, WxH significa che l'immagine in scala si adatta a una casella di quella dimensione, preservando le proporzioni), il -aparametro dovrebbe essere usato con rsvg.
Mahmoud Al-Qudsi,

1
Ciò ha alterato le mie immagini, ogni sorta di strani manufatti. inkscape ha fatto un lavoro migliore.
dadi eleganti il

1
Attenzione, brew install rsvgsu OSX installa un milione di cose - GDK, OpenSSL, Python, ecc.
Timmmm,

4
Cordiali saluti, il comando di installazione corrente è brew install librsvge il comando di conversione è rsvg-convert.
waldyrious,

Ho trovato librsvg (o rsvg-convertin caso di Arch) per dare i risultati migliori e più coerenti durante la conversione di SVG complicati in PNG. Seguire optipngper ridurre le dimensioni del file di output.
Maktel

18

Dopo aver seguito i passaggi nella risposta di Jose Alban , sono stato in grado di far funzionare ImageMagick perfettamente usando il seguente comando:

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

Il numero 1536 deriva da una stima della densità del ballpark, vedere questa risposta per ulteriori informazioni.


15

Per ridimensionare l'immagine, è -densitynecessario utilizzare l'opzione . Per quanto ne so, la densità standard è 72 e mappa la dimensione 1: 1. Se vuoi che l'output png sia doppio rispetto allo svg originale, imposta la densità su 72 * 2 = 144:

convert -density 144 source.svg target.png

Si noti che le opzioni di conversione devono essere prima del file di input. Vale convert source.svg -density 144 target.pnga dire non ridimensionare l'immagine.
Skippy le Grand Gourou,

In realtà la densità standard sembra essere 90. Quindi sarebbeconvert -density 180 source.svg target.png
adius il

7

perché non provi a usare la riga di comando di inkscape, questo è il mio file bat per convertire tutto png in questa directory in 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

Sono arrivato a questo post, ma volevo solo fare la conversione per batch e veloce senza l'uso di parametri (a causa di diversi file con dimensioni diverse).

rsvg drawing.svg drawing.png

Per me i requisiti erano probabilmente un po 'più semplici rispetto all'autore originale. (Volevo usare SVG in MS PowerPoint, ma non lo consente)


1
Per riferimento, su macOS questo è installato brew install librsvge il comando di conversione è rsvg-convert.
caloroso

in Ubutni è anche rsvg-convert, il pacchetto è librsvg2-bin e l'output necessita di -o drawing.png
teknopaul

4

In ImageMagick, si ottiene un rendering SVG migliore se si utilizza Inkscape o RSVG con ImageMagick rispetto al proprio rendering MSVG / XML interno. RSVG è un delegato che deve essere installato con ImageMagick. Se Inkscape è installato sul sistema, ImageMagick lo utilizzerà automaticamente. Uso Inkscape in ImageMagick di seguito.

Non esiste un parametro "magico" che farà ciò che desideri.

Tuttavia, è possibile calcolare in modo molto semplice l'esatta densità necessaria per il rendering dell'output.

Ecco un piccolo pulsante 50x50 quando viene visualizzato alla densità predefinita di 96:

convert button.svg button1.png


inserisci qui la descrizione dell'immagine

Supponiamo che vogliamo che l'output sia 500. L'ingresso è 50 con densità predefinita di 96 (le versioni precedenti di Inkscape potrebbero utilizzare 92). Quindi è possibile calcolare la densità necessaria in proporzione ai rapporti tra dimensioni e densità.

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


convert -density 983 button.svg button2.png


inserisci qui la descrizione dell'immagine

In ImageMagick 7, puoi eseguire il calcolo in linea come segue:

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

l'equazione in Magick DSL è stata molto utile!
cyrf

2

Una cosa che mi ha appena morso è stata l'impostazione -densityDOPO il nome del file di input. Non ha funzionato. Spostandolo sulla prima opzione in convert (prima di ogni altra cosa) lo ha fatto funzionare (per me, YMMV, ecc.).


2

Per una semplice conversione da SVG a PNG ho scoperto che cairosvg ( https://cairosvg.org/ ) funziona meglio di ImageMagick. Passaggi per l'installazione e l'esecuzione su tutti i file SVG nella directory.

pip3 install cairosvg

Apri una shell python nella directory che contiene i tuoi file .svg ed esegui:

import os

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

Questo assicurerà anche di non sovrascrivere i tuoi file .svg originali, ma manterrà lo stesso nome. Puoi quindi spostare tutti i tuoi file .png in un'altra directory con:

$ mv *.png [new directory]

si è schiantato su Windows 10: importare cairocffi come file cairo "c: \ programmi (x86) \ python35-32 \ lib \ site-pacchetti \ cairocffi_ init_ .py", riga 39, in <module> cairo = dlopen (ffi , 'cairo', 'cairo-2', 'cairo-gobject-2', 'cairo.so.2') File "c: \ programmi (x86) \ python35-32 \ lib \ site-pacchetti \ cairocffi_ init_ .py ", riga 36, ​​in dlopen raise OSError (" dlopen () non è riuscito a caricare una libreria:% s "% '/' .join (names)) OSError: dlopen () non è riuscito a caricare una libreria: cairo / cairo- 2 / cairo-gobject-2 / cairo.so.2
Pete Lomax

Bene, cairosvgsu Ubuntu-19.04 ha fatto il lavoro per me.
fhgd,

2

Senza librsvg, potresti ottenere un'immagine png / jpeg nera. Dobbiamo installare librsvgsuconvert file in formato SVG con ImageMagick.

Ubuntu

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

Mac OS

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

Non ho installato questa libreria e non ho nemmeno immagini nere.
Aaron Franke il

1

Ho risolto questo problema modificando gli attributi widthe heightdel file<svg> tag in modo che corrispondessero alle dimensioni dell'output previsto e poi lo convertissi utilizzando ImageMagick. Funziona come un fascino.

Ecco il mio codice Python, una funzione che restituirà il contenuto del file 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
perché restituiresti un'immagine generata da computer come jpeg :(?
Willi Mentzel,

1

La risposta migliore di @ 808sound non ha funzionato per me. Volevo ridimensionare Pacchetto UI Kenney.nl

e ottenuto Pacchetto dell'interfaccia utente di Kenney incasinato

Così, invece ho aperto Inkscape, poi sono andato a File, Export as PNG filee una scatola GUI spuntato up che mi ha permesso di impostare le dimensioni esatte di cui avevo bisogno.

Versione su Ubuntu 16.04 Linux: Inkscape 0.91 (September 2016)

(A proposito, questa immagine proviene dai pacchetti di risorse di Kenney.nl )


1

Su macOS usando brew, usando librsvg funziona direttamente bene

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

Molte opzioni sono disponibili tramite rsvg-convert --help


0

Su Linux con Inkscape 1.0 per convertire da svg a PNG è necessario utilizzare

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

non

inkscape -w 1024 -h 1024 input.svg --export-filename output.png
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.