Como converter um SVG para PNG com ImageMagick?


388

Eu tenho um arquivo SVG que tem um tamanho definido de 16x16. Quando uso o programa de conversão do ImageMagick para convertê-lo em PNG, recebo um PNG de 16x16 pixels muito pequeno:

convert test.svg test.png

Preciso especificar o tamanho do pixel do PNG de saída. -sizeparâmetro parece ser ignorado, ele -scaledimensiona o PNG depois que ele foi convertido em PNG. O melhor resultado que obtive até agora usando o -densityparâmetro:

convert -density 1200 test.svg test.png

Mas não estou satisfeito, porque quero especificar o tamanho da saída em pixels sem fazer contas para calcular o valor da densidade. Então, eu quero fazer algo assim:

convert -setTheOutputSizeOfThePng 1024x1024 test.svg test.png

Então, qual é o parâmetro mágico que eu tenho que usar aqui?


6
por exemplo, -size 1024x1024está funcionando bem, qual é a sua versão do imagemagick?
Dejan Marjanovic


2
ImageMagick-6.9.0-Q16. converter -resize 1024x1024 foo.svg foo.png funciona bem.
21415 Jichao

11
@Jichao -resizeapenas estica a imagem convertida, com resultados de baixa qualidade.
Elist

5
convert -size 1024x1024 test.svg test.pngfunciona bem com o ImageMagick 7.0.7-0 Q16 (versão atual no repositório Chocolatey para Windows). Apenas certifique-se de que -sizeapareça antes do nome do arquivo de entrada, caso contrário, uma imagem 16x16 será aumentada para dar um resultado desfocado.
Futal 08/09

Respostas:


502

Não consegui obter bons resultados com o ImageMagick nesse caso, mas o Inkscape faz um bom trabalho no Linux e no Windows:

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

Editar (maio de 2020): usuários do Inkscape 1.0, observe que os argumentos da linha de comando foram alterados:

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

Aqui está o resultado do dimensionamento de um SVG de 16x16 para um PNG de 200x200 usando este comando:

insira a descrição da imagem aqui

insira a descrição da imagem aqui

Apenas para referência, minha versão do Inkscape (no Ubuntu 12.04) é:

Inkscape 0.48.3.1 r9886 (Mar 29 2012)

e no Windows 7, é:

Inkscape 0.48.4 r9939 (Dec 17 2012)

15
+1 no que diz respeito ao imagemagick. Parece haver um problema com o mecanismo SVG. Na maioria dos casos, não consegui obter resultados precisos com ele. O Inkscape, OTOH, funciona perfeitamente bem.
Glutanimate

13
Eu acho que o Inkscape é o exemplo mais impressionante do OSS depois do próprio Linux. Obrigado pela dica!
Kim3er

8
Também funciona bem no OSX.
Jonas Granvik

12
No OSX, com o Inkscape instalado para o X11, funcionou para mim usando:/Applications/Inkscape.app/Contents/Resources/bin/inkscape -z -e test.png -w 1024 -h 1024 test.svg
chmullig

11
@ Rörd Para manter o plano de fundo transparente com o ImageMagick, use a -background noneopção de linha de comando.
John

142

Tente svgexport :

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

svgexport é uma ferramenta simples de linha de comando de plataforma cruzada que criei para exportar arquivos svg para jpg e png, veja aqui para mais opções. Para instalar o svgexport, instale o npm e execute:

npm install svgexport -g

Edit: Se você encontrar um problema com a biblioteca, envie-o no GitHub, obrigado!


4
svgexport funcionou muito bem para mim. A saída corresponde à renderização do navegador muito mais próxima do que o ImageMagick.
T9mike 25/03

5
A qualidade svgexport é realmente tão alta. Agora tornou-se minha ferramenta favorita, obrigado shakiba! :)
Alessio Periloso

11
isso funcionou bem para mim também. Economia de tempo real em comparação com fazê-lo manualmente em uma ferramenta GUI. Muito difícil encontrar um aplicativo GUI no mac na faixa mais barato de qualquer maneira que alças SVG bem
Erik Engheim

4
Funciona muito bem, mas produz uma imagem enorme. Usando o optipng, consegui compactar meu logotipo de texto de 3 megabytes para ~ 20kB.
Mk8 7/08

2
O evgexport cria arquivos PNG ENORMES, dependendo do tamanho. Recomende svg2png, que também usa o PhantomJS para exportação, mas cria imagens muito menores.
Aaron_H

112

Isso não é perfeito, mas faz o trabalho.

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

Basicamente, aumenta o DPI alto o suficiente (basta usar um palpite seguro / educado) para que o redimensionamento seja feito com qualidade adequada. Eu estava tentando encontrar uma solução adequada para isso, mas depois de um tempo decidi que isso era bom o suficiente para a minha necessidade atual.

Nota: Use 200x200! para forçar a resolução dada


4
Opacidade e sombras perdidas no meu caso.
precisa saber é o seguinte

2
Eu não tenho svg complexo, então isso funcionou para mim. -resize 200%não funcionou e eu tive que especificar o tamanho em pixels.
21414 johcqqk

18
@jiyinyiyong Para manter o plano de fundo transparente com o ImageMagick, use a -background noneopção de linha de comando. Para manter a proporção da imagem, você também pode especificar apenas uma dimensão, como -resize 200largura ou -resize x200altura. Consulte: imagemagick.org/script/command-line-processing.php#geometry para obter opções exaustivas de geometria do ImageMagick .
John

também não funciona para mim. O resultado está todo embaçado.
Mbonnin

(isso se aplica ao linux, pode ser aplicado ao windows) se você ativar o verbose no IM, parece que o próprio IM usa o inkscape para criar um arquivo eps intermediário. Portanto, eu sugiro usar o Inkscape diretamente como sugerido por @ 808sound
norte-Bradley

55

Se você estiver no MacOS X e tiver problemas com a conversão do Imagemagick, tente reinstalá-lo com a RSVG lib. Usando o HomeBrew:

brew remove imagemagick
brew install imagemagick --with-librsvg

Verifique se está delegando corretamente:

$ 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

Deve aparecer rsvg.


Não funcionou para mim. Especificamente, eu executei convert ic_comment_48px.svg -size 30x30 ic_comment_30px.pnge a imagem de saída é 48 x 48. Verifique se o imagemagick está delegando no rsvg, como você explicou.
Shane Creighton-Young

11
Funcionou perfeitamente para mim - o padrão convertconverteu svg para png, mas os resultados foram inúteis; depois de reinstalar, eles são perfeitos. Além disso, a conversão é significativamente mais rápida.
Ssc #

11
Isso me funcionou no Mac OSX. Não acho a nova conversão mais rápida, mas muito mais precisa. Eu recomendo que todos os usuários do Mac OSX experimentem.
HelloWorld 27/06

11
Essa deve ser a resposta aceita, tudo bem. Obrigado, funcionou como um encanto, e eu nunca teria sabido tomar essas medidas de outra maneira
#

8
Em mojave eu receboinvalid option: --with-librsvg
zaitsman

39

O Inkscape parece não funcionar quando as unidades svg não são px(por exemplo, cm). Eu tenho uma imagem em branco. Talvez pudesse ser corrigido girando o ppp, mas era muito problemático.

Svgexport é um programa node.js e, portanto, geralmente não é útil.

O conversor do Imagemagick funciona bem com:

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

Se você usar -resize, a imagem ficará confusa e o arquivo será muito maior.

MELHOR

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

É o mais rápido, possui o menor número de dependências e a saída é cerca de 30% menor que a conversão. Instale o librsvg2-bin para obtê-lo. Não parece haver uma página de manual, mas você pode digitar:

~$ rsvg --help

para obter ajuda. Simples é bom.


2
Essa é facilmente a melhor resposta (não sei por que vinte respostas diferentes dão a mesma resposta de imagem mágica); preserva cores e sombras e não altera nada. No entanto, para corresponder ao comportamento de redimensionamento do imagemagick (em particular, WxH significa dimensionar a imagem para caber em uma caixa desse tamanho, preservando a proporção), o -aparâmetro deve ser usado com o rsvg.
Mahmoud Al-Qudsi

11
Isso destruiu minhas imagens, todo tipo de artefato estranho. O inkscape fez um trabalho melhor.
elegant dice

11
Esteja avisado, brew install rsvgno OSX instala um milhão de coisas - GDK, OpenSSL, Python etc.
Timmmm 16/17

4
Para sua informação, o comando de instalação atual é brew install librsvge o comando de conversão é rsvg-convert.
23418 waldyrious

Eu encontrei o librsvg (ou rsvg-convertno caso do Arch) para fornecer os melhores e mais consistentes resultados ao converter svgs complicados em png. Siga optipngpara reduzir o tamanho do arquivo de saída.
maktel

18

Depois de seguir as etapas da resposta de Jose Alban , consegui que o ImageMagick funcionasse perfeitamente usando o seguinte comando:

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

O número 1536 vem de uma estimativa aproximada da densidade. Consulte esta resposta para obter mais informações.


15

Para redimensionar a imagem, a opção -densitydeve ser usada. Tanto quanto sei, a densidade padrão é 72 e mapeia o tamanho 1: 1. Se você deseja que o png de saída seja duas vezes maior que o svg original, defina a densidade como 72 * 2 = 144:

convert -density 144 source.svg target.png

Observe que as opções de conversão precisam estar antes do arquivo de entrada. Ou seja convert source.svg -density 144 target.png, não vai redimensionar a imagem.
Skippy le Grand Gourou

Na verdade, a densidade padrão parece ser 90. Assim seriaconvert -density 180 source.svg target.png
adius 5/16

7

por que você não tenta a linha de comando do inkscape, este é o meu arquivo bat para converter todos os svg deste diretório para png:

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


4

Eu vim para este post - mas eu só queria fazer a conversão por lote e rapidamente, sem o uso de nenhum parâmetro (devido a vários arquivos com tamanhos diferentes).

rsvg drawing.svg drawing.png

Para mim, os requisitos foram provavelmente um pouco mais fáceis do que para o autor original. (Queria usar SVGs no MS PowerPoint, mas não permite)


11
Para referência, no macOS, ele é instalado brew install librsvge o comando de conversão é rsvg-convert.
waldyrious

em Ubutni também é rsvg-convert, o pacote é librsvg2-bin e a saída precisa -o drawing.png
teknopaul

4

No ImageMagick, obtém-se uma melhor renderização SVG se você usa o Inkscape ou o RSVG com ImageMagick do que o seu próprio MSVG / XML interno renderizado. O RSVG é um delegado que precisa ser instalado com o ImageMagick. Se o Inkscape estiver instalado no sistema, o ImageMagick o utilizará automaticamente. Eu uso o Inkscape no ImageMagick abaixo.

Não há parâmetro "mágico" que faça o que você deseja.

Mas, pode-se calcular muito simplesmente a densidade exata necessária para renderizar a saída.

Aqui está um pequeno botão de 50x50 quando renderizado na densidade padrão de 96:

convert button.svg button1.png


insira a descrição da imagem aqui

Suponha que desejamos que a saída seja 500. A entrada é 50 na densidade padrão de 96 (versões mais antigas do Inkscape podem estar usando 92). Assim, você pode calcular a densidade necessária proporcionalmente às proporções das dimensões e densidades.

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


convert -density 983 button.svg button2.png


insira a descrição da imagem aqui

No ImageMagick 7, você pode fazer o cálculo em linha da seguinte maneira:

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

a equação na magick DSL foi muito útil!
cyrf 21/04

2

Uma coisa que me atrapalhou foi definir -densityDEPOIS do nome do arquivo de entrada. Isso não deu certo. Mover para a primeira opção no convert (antes de mais nada) fez funcionar (para mim, YMMV, etc).


2

Para uma simples conversão de SVG para PNG, descobri que o cairosvg ( https://cairosvg.org/ ) tem um desempenho melhor que o ImageMagick. Etapas para instalar e executar em todos os arquivos SVG no seu diretório.

pip3 install cairosvg

Abra um shell python no diretório que contém os arquivos .svg e execute:

import os

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

Isso também garantirá que você não substitua os arquivos .svg originais, mas manterá o mesmo nome. Você pode mover todos os seus arquivos .png para outro diretório com:

$ mv *.png [new directory]

caiu para mim no Windows 10: importar cairocffi como cairo O arquivo "c: \ arquivos de programas (x86) \ python35-32 \ lib \ pacotes de sites \ cairocffi_ init_ .py", linha 39, em <module> cairo = dlopen (ffi , 'cairo', 'cairo-2', 'cairo-gobject-2', 'cairo.so.2') Arquivo "c: \ arquivos de programas (x86) \ python35-32 \ lib \ pacotes de sites \ cairocffi_ init_ .py ", linha 36, ​​no dlopen raise OSError (" dlopen () falhou ao carregar uma biblioteca:% s "% '/' .join (nomes)) OSError: dlopen () falhou ao carregar uma biblioteca: cairo / cairo- 2 / cairo-gobject-2 / cairo.so.2
Pete Lomax

Bom, cairosvgno Ubuntu-19.04 fiz o trabalho por mim.
fhgd 9/12/19

2

Sem o librsvg, você pode obter uma imagem png / jpeg preta. Temos que instalar librsvgparaconvert arquivo svg com o 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

Não tenho esta biblioteca instalada e também não recebo imagens em preto.
Aaron Franke

1

Resolvi esse problema alterando os atributos widthe heightdo<svg> tag para corresponder ao tamanho de saída pretendido e convertendo-o usando o ImageMagick. Funciona como um encanto.

Aqui está o meu código Python, uma função que retornará o conteúdo do arquivo 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
por que você iria retornar uma imagem gerada por computador como jpeg :(?
Willi Mentzel

1

A resposta do @ 808sound não funcionou para mim. Eu queria redimensionar Kenney.nl UI Pack

e pegou Kenney UI Pack desarrumado

Então, ao invés eu abri Inkscape, em seguida, foi para File, Export as PNG filee uma caixa GUI apareceu que me permitiu definir as dimensões exatas que eu precisava.

Versão em Ubuntu 16.04 Linux: Inkscape 0.91 (September 2016)

(Esta imagem é dos pacotes de recursos de Kenney.nl, por sinal)


1

No macOS usando o brew, o uso do librsvg funciona diretamente bem

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

Muitas opções estão disponíveis via rsvg-convert --help


0

No Linux com Inkscape 1.0 para converter de svg para png, é necessário usar

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

não

inkscape -w 1024 -h 1024 input.svg --export-filename output.png
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.