¿Cómo convertir un SVG a un PNG con ImageMagick?

389

Tengo un archivo SVG que tiene un tamaño definido de 16x16. Cuando uso el programa de conversión de ImageMagick para convertirlo en PNG, obtengo un PNG de 16x16 píxeles que es demasiado pequeño:

convert test.svg test.png

Necesito especificar el tamaño de píxel de la salida PNG. -sizeel parámetro parece ignorarse, el -scaleparámetro escala el PNG después de que se haya convertido a PNG. El mejor resultado hasta ahora lo obtuve usando el -densityparámetro:

convert -density 1200 test.svg test.png

Pero no estoy satisfecho, porque quiero especificar el tamaño de salida en píxeles sin hacer cálculos matemáticos para calcular el valor de densidad. Entonces quiero hacer algo como esto:

convert -setTheOutputSizeOfThePng 1024x1024 test.svg test.png

Entonces, ¿cuál es el parámetro mágico que tengo que usar aquí?

kayahr
fuente
66
por ejemplo, -size 1024x1024funciona bien, ¿cuál es su versión de imagemagick?
Dejan Marjanovic
2
ImageMagick-6.9.0-Q16. convertir -resize 1024x1024 foo.svg foo.png funciona bien.
Jichao
11
@Jichao -resizesolo estira la imagen convertida, con resultados de baja calidad.
Elist
55
convert -size 1024x1024 test.svg test.pngfunciona bien con ImageMagick 7.0.7-0 Q16 (versión actual en Chocolatey repo para Windows). Solo asegúrese de que -sizeaparezca antes del nombre de archivo de entrada, de lo contrario, una imagen de 16x16 se escalará para obtener un resultado borroso.
Futal

Respuestas:

502

No he podido obtener buenos resultados de ImageMagick en este caso, pero Inkscape hace un buen trabajo en Linux y Windows:

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

Editar (mayo de 2020): usuarios de Inkscape 1.0, tenga en cuenta que los argumentos de la línea de comando han cambiado:

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

Aquí está el resultado de escalar un SVG de 16x16 a un PNG de 200x200 usando este comando:

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Solo como referencia, mi versión de Inkscape (en Ubuntu 12.04) es:

Inkscape 0.48.3.1 r9886 (Mar 29 2012)

y en Windows 7, es:

Inkscape 0.48.4 r9939 (Dec 17 2012)
808sonido
fuente
15
+1 en lo que respecta a imagemagick. Parece que hay un problema con el motor SVG. En la mayoría de los casos no pude obtener resultados precisos con él. Inkscape, OTOH, funciona perfectamente bien.
Glutanimate
13
Creo que Inkscape es el ejemplo más impresionante de OSS después de Linux en sí. ¡Gracias por el consejo!
kim3er
8
Funciona muy bien en OSX también.
Jonas Granvik
12
En OSX, con Inkscape instalado para X11, funcionó para mí usando:/Applications/Inkscape.app/Contents/Resources/bin/inkscape -z -e test.png -w 1024 -h 1024 test.svg
chmullig
11
@ Rörd Para mantener el fondo transparente con ImageMagick, use la -background noneopción de línea de comando.
John
142

Prueba svgexport :

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

svgexport es una sencilla herramienta de línea de comandos multiplataforma que he creado para exportar archivos svg a jpg y png, consulte aquí para obtener más opciones. Para instalar svgexport, instale npm , luego ejecute:

npm install svgexport -g

Editar: Si encuentra un problema con la biblioteca, envíelo en GitHub, ¡gracias!

Ali Shakiba
fuente
44
svgexport funcionó muy bien para mí. La salida coincide con la representación del navegador mucho más de cerca que ImageMagick.
t9mike
55
La calidad de svgexport es realmente tan alta. Ahora se ha convertido en mi herramienta favorita, gracias shakiba! :)
Alessio Periloso
1
Esto funcionó bien para mí también. Ahorro de tiempo real en comparación con hacerlo manualmente en una herramienta GUI. De todos modos, es bastante difícil encontrar una aplicación GUI en Mac en el rango más barato que maneje bien SVG
Erik Engheim
44
Funciona muy bien, pero produce una gran imagen. Usando optipng, pude comprimir mi logo de texto de 3 megabytes a ~ 20kB.
miek
2
evgexport crea archivos PNG ENORMES dependiendo del tamaño. Recomienda svg2png que también usa PhantomJS para la exportación, pero crea imágenes mucho más pequeñas.
Aaron_H
112

Esto no es perfecto pero hace el trabajo.

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

Básicamente, aumenta el DPI lo suficientemente alto (solo use una suposición educada / segura) de que el cambio de tamaño se realiza con la calidad adecuada. Estaba tratando de encontrar una solución adecuada para esto, pero después de un tiempo decidí que era lo suficientemente bueno para mi necesidad actual.

Nota: ¡ Use 200x200! para forzar la resolución dada

Hardev
fuente
44
Opacidad y sombras perdidas en mi caso.
jiyinyiyong
2
No tengo svg complejo, así que esto funcionó para mí. -resize 200%no funcionó y tuve que especificar el tamaño en píxeles.
jozxyqk
18
@jiyinyiyong Para mantener el fondo transparente con ImageMagick, use la -background noneopción de línea de comando. Para mantener la relación de imagen, también puede especificar solo una dimensión, como -resize 200ancho o -resize x200alto. Consulte: imagemagick.org/script/command-line-processing.php#geometry para obtener opciones exhaustivas de geometría de ImageMagick .
John
tampoco funciona para mí El resultado es todo borroso.
mbonnin
(esto se aplica a Linux, puede aplicarse a Windows) si activa -verbose en IM, parecería que IM utiliza Inkscape para crear un archivo eps intermedio. por lo tanto, sugeriría usar Inkscape directamente como lo sugiere @ 808sound
northern-bradley
55

Si está en MacOS X y tiene problemas con la conversión de Imagemagick, puede intentar reinstalarla con RSVG lib. Usando HomeBrew:

brew remove imagemagick
brew install imagemagick --with-librsvg

Verifique que esté delegando correctamente:

$ 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

Debería mostrar rsvg.

Jose Alban
fuente
No funciono para mi. Específicamente ejecuté convert ic_comment_48px.svg -size 30x30 ic_comment_30px.pngy la imagen de salida es 48 x 48. Asegúrese de que imagemagick esté delegando a rsvg como lo ha explicado.
Shane Creighton-Young
1
Funcionó perfectamente para mí: el valor predeterminado convertconvirtió svg a png, pero los resultados fueron inútiles; después de reinstalar, son perfectos. Además, la conversión es significativamente más rápida.
ssc
1
Esto me funcionó en Mac OSX. No encuentro la nueva conversión más rápido, pero mucho más precisa. Recomiendo encarecidamente a todos los usuarios de Mac OSX que lo prueben.
HelloWorld
1
Esta debería ser la respuesta aceptada, oh, bueno. Gracias, funcionó de maravilla, y nunca habría conocido a tomar estas medidas de otro modo
sdailey
8
En mojave consigoinvalid option: --with-librsvg
zaitsman
39

Inkscape no parece funcionar cuando las unidades svg no lo son px(por ejemplo, cm). Tengo una imagen en blanco. Tal vez, podría solucionarse girando el dpi, pero era demasiado problemático.

Svgexport es un programa node.js y, por lo tanto, generalmente no es útil.

El convertidor de Imagemagick funciona bien con:

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

Si lo usa -resize, la imagen es borrosa y el archivo es mucho más grande.

MEJOR

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

Es el más rápido, tiene la menor cantidad de dependencias y la salida es aproximadamente un 30% más pequeña que la conversión. Instale librsvg2-bin para obtenerlo. No parece haber una página de manual, pero puede escribir:

~$ rsvg --help

para obtener ayuda Lo simple es bueno.

septiembre_converter
fuente
2
Esta es fácilmente la mejor respuesta (no sé por qué veinte respuestas diferentes dan la misma respuesta imagemagick); conserva colores y sombras y no destruye nada. Sin embargo, para que coincida con el comportamiento de cambio de tamaño de la imagen mágica (en particular, WxH significa escalar la imagen para que quepa en un cuadro de ese tamaño, preservando la relación de aspecto), el -aparámetro debe usarse con rsvg.
Mahmoud Al-Qudsi
1
Esto destrozó mis imágenes, todo tipo de artefactos extraños. Inkscape hizo un mejor trabajo.
dados elegantes
1
Tenga cuidado, brew install rsvgen OSX instala un millón de cosas: GDK, OpenSSL, Python, etc.
Timmmm
44
Para su información, el comando de instalación actual es brew install librsvgy el comando de conversión es rsvg-convert.
waldyrious
Encontré que librsvg (o rsvg-converten el caso de Arch) brinda los mejores y más consistentes resultados al convertir svgs complicados a png. Haga un seguimiento con optipngpara reducir el tamaño del archivo de salida.
maktel
18

Después de seguir los pasos en la respuesta de José Alban , pude hacer que ImageMagick funcionara bien usando el siguiente comando:

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

El número 1536 proviene de una estimación aproximada de densidad, consulte esta respuesta para obtener más información.

Ian
fuente
15

Para reescalar la imagen, se -densitydebe usar la opción . Hasta donde yo sé, la densidad estándar es 72 y asigna el tamaño 1: 1. Si desea que la salida png sea dos veces más grande que la svg original, configure la densidad en 72 * 2 = 144:

convert -density 144 source.svg target.png
Stanislav Schmidt
fuente
Tenga en cuenta que las opciones de conversión deben estar antes del archivo de entrada. Es decir convert source.svg -density 144 target.png, no cambiará la escala de la imagen.
Skippy le Grand Gourou
En realidad, la densidad estándar parece ser 90. Así seríaconvert -density 180 source.svg target.png
adius
7

¿por qué no pruebas la línea de comando de inkscape? Este es mi archivo bat para convertir todos los svg en este directorio a png:

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

ampecs
fuente
4

Llegué a esta publicación, pero solo quería hacer la conversión por lotes y rápido sin el uso de ningún parámetro (debido a varios archivos con diferentes tamaños).

rsvg drawing.svg drawing.png

Para mí, los requisitos fueron probablemente un poco más fáciles que para el autor original. (Quería usar SVG en MS PowerPoint, pero no permite)

Qohelet
fuente
1
Como referencia, en macOS se instala con brew install librsvgy el comando de conversión es rsvg-convert.
waldyrious
en Ubutni también es rsvg-convert, el paquete es librsvg2-bin y la salida necesita -o
drawing.png
4

En ImageMagick, se obtiene una mejor representación SVG si se usa Inkscape o RSVG con ImageMagick que su propio renderizado interno MSVG / XML. RSVG es un delegado que debe instalarse con ImageMagick. Si Inkscape está instalado en el sistema, ImageMagick lo usará automáticamente. Yo uso Inkscape en ImageMagick a continuación.

No hay un parámetro "mágico" que haga lo que quieras.

Pero, uno puede calcular muy simplemente la densidad exacta necesaria para representar la salida.

Aquí hay un pequeño botón de 50x50 cuando se procesa con la densidad predeterminada de 96:

convert button.svg button1.png


ingrese la descripción de la imagen aquí

Supongamos que queremos que la salida sea 500. La entrada es 50 con una densidad predeterminada de 96 (las versiones anteriores de Inkscape pueden estar usando 92). Por lo tanto, puede calcular la densidad necesaria en proporción a las proporciones de las dimensiones y las densidades.

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


convert -density 983 button.svg button2.png


ingrese la descripción de la imagen aquí

En ImageMagick 7, puede hacer el cálculo en línea de la siguiente manera:

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
fuente
¡La ecuación en Magick DSL fue muy útil!
cyrf
2

Una cosa que me mordió fue configurar -densityDESPUÉS del nombre del archivo de entrada. Eso no funcionó. Moverlo a la primera opción en convertir (antes que nada) lo hizo funcionar (para mí, YMMV, etc.).

Mella
fuente
2

Para la conversión simple de SVG a PNG, encontré que cairosvg ( https://cairosvg.org/ ) funciona mejor que ImageMagick. Pasos para instalar y ejecutar todos los archivos SVG en su directorio.

pip3 install cairosvg

Abra un shell de Python en el directorio que contiene sus archivos .svg y ejecute:

import os

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

Esto también asegurará que no sobrescriba sus archivos .svg originales, pero mantendrá el mismo nombre. Luego puede mover todos sus archivos .png a otro directorio con:

$ mv *.png [new directory]
edank
fuente
se bloqueó para mí en Windows 10: importar cairocffi como cairo Archivo "c: \ archivos de programa (x86) \ python35-32 \ lib \ site-packages \ cairocffi_ init_ .py", línea 39, en <module> cairo = dlopen (ffi , 'cairo', 'cairo-2', 'cairo-gobject-2', 'cairo.so.2') Archivo "c: \ archivos de programa (x86) \ python35-32 \ lib \ site-packages \ cairocffi_ init_ .py ", línea 36, ​​en dlopen raise OSError (" dlopen () no pudo cargar una biblioteca:% s "% '/' .join (nombres)) OSError: dlopen () no pudo cargar una biblioteca: cairo / cairo- 2 / cairo-gobject-2 / cairo.so.2
Pete Lomax
Bien, cairosvgen Ubuntu-19.04 hizo el trabajo por mí.
fhgd
2

Sin librsvg, puede obtener una imagen png / jpeg negra. Tenemos que instalar librsvgaconvert archivo 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
TLbiz
fuente
No tengo esta biblioteca instalada y tampoco obtengo imágenes en negro.
Aaron Franke
1

He resuelto este problema cambiando los atributos widthy heightde<svg> etiqueta para que coincida con el tamaño de salida deseado y luego convirtiéndolo usando ImageMagick. Funciona de maravilla.

Aquí está mi código Python, una función que devolverá el contenido del archivo 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
fuente
2
¿por qué devolverías una imagen generada por computadora como jpeg :(?
Willi Mentzel
1

La respuesta principal de @ 808sound no funcionó para mí. Quería cambiar el tamaño Kenney.nl UI Pack

y consiguió Kenney UI Pack en mal estado

Así que en vez abrí Inkscape, y luego fui a File, Export as PNG filey una caja de interfaz gráfica de usuario aparecido que me ha permitido establecer las dimensiones exactas que necesitaba.

Versión en Ubuntu 16.04 Linux: Inkscape 0.91 (September 2016)

(Por cierto, esta imagen es de los paquetes de activos de Kenney.nl )

James L.
fuente
1

En macOS usando brew, usar librsvg funciona directamente bien

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

Muchas opciones están disponibles a través de rsvg-convert --help

mloughran
fuente
0

En Linux con Inkscape 1.0 para convertir de svg a png necesita usar

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

no

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