Jak przekonwertować SVG na PNG za pomocą ImageMagick?

388

Mam plik SVG o zdefiniowanym rozmiarze 16 x 16. Kiedy używam programu do konwersji ImageMagick do konwersji na format PNG, otrzymuję obraz PNG 16 x 16 pikseli, który jest zdecydowanie za mały:

convert test.svg test.png

Muszę określić rozmiar piksela wyjściowego PNG. -sizeparametr wydaje się być ignorowany, -scaleparametr skaluje PNG po przekonwertowaniu na PNG. Najlepszy dotychczasowy wynik uzyskałem za pomocą -densityparametru:

convert -density 1200 test.svg test.png

Ale nie jestem zadowolony, ponieważ chcę określić rozmiar wyjściowy w pikselach bez robienia obliczeń matematycznych w celu obliczenia wartości gęstości. Więc chcę zrobić coś takiego:

convert -setTheOutputSizeOfThePng 1024x1024 test.svg test.png

Jaki jest więc magiczny parametr, którego muszę tutaj użyć?

Kayahr
źródło
6
np. -size 1024x1024czy działa dobrze, jaka jest twoja wersja imagemagick?
Dejan Marjanovic
2
ImageMagick-6.9.0-Q16. konwersja -resize 1024x1024 foo.svg foo.png działa dobrze.
Jichao,
11
@Jichao -resizepo prostu rozciąga przekonwertowany obraz, uzyskując słabej jakości wyniki.
Elist
5
convert -size 1024x1024 test.svg test.pngdziała dobrze z ImageMagick 7.0.7-0 Q16 (aktualna wersja w Chocolatey repo dla Windows). Tylko upewnij się, że -sizepojawia się przed nazwą pliku wejściowego, w przeciwnym razie obraz 16 x 16 zostanie przeskalowany, aby uzyskać rozmazany wynik.
Futal

Odpowiedzi:

502

W tym przypadku nie byłem w stanie uzyskać dobrych wyników z ImageMagick, ale Inkscape robi to dobrze w systemach Linux i Windows:

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

Edycja (maj 2020): użytkownicy Inkscape 1.0, pamiętaj, że zmieniono argumenty wiersza poleceń:

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

Oto wynik skalowania pliku SVG 16 x 16 do pliku PNG 200 x 200 za pomocą tego polecenia:

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

Dla porównania moja wersja Inkscape (na Ubuntu 12.04) to:

Inkscape 0.48.3.1 r9886 (Mar 29 2012)

a w systemie Windows 7 jest to:

Inkscape 0.48.4 r9939 (Dec 17 2012)
808sound
źródło
15
+1, jeśli chodzi o imagemagick. Wygląda na to, że występuje problem z silnikiem SVG. W większości przypadków nie byłem w stanie uzyskać dokładnych wyników. Inkscape, OTOH, działa idealnie dobrze.
Glutanimate,
13
Myślę, że Inkscape jest najbardziej imponującym przykładem OSS po samym Linuksie. Dzięki za wskazówkę!
kim3er,
8
Działa również dobrze na OSX.
Jonas Granvik
12
W OSX, z Inkscape zainstalowanym dla X11, działało dla mnie przy użyciu:/Applications/Inkscape.app/Contents/Resources/bin/inkscape -z -e test.png -w 1024 -h 1024 test.svg
chmullig
11
@ Rörd Aby zachować przezroczystość tła w ImageMagick, użyj -background noneopcji wiersza poleceń.
John
142

Spróbuj svgexport :

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

svgexport to proste wieloplatformowe narzędzie wiersza poleceń, które stworzyłem do eksportowania plików svg do jpg i png, zobacz tutaj więcej opcji. Aby zainstalować svgexport install npm , a następnie uruchom:

npm install svgexport -g

Edytuj: jeśli znajdziesz problem z biblioteką, prześlij go na GitHub, dzięki!

Ali Shakiba
źródło
4
svgexport działał dla mnie świetnie. Wyjście odpowiada renderowaniu w przeglądarce znacznie bardziej niż ImageMagick.
t9mike
5
Jakość svgexport jest naprawdę tak wysoka. Teraz stało się moim ulubionym narzędziem, dzięki shakiba! :)
Alessio Periloso
1
to również działało dobrze dla mnie. Oszczędność czasu rzeczywistego w porównaniu do robienia tego ręcznie w narzędziu GUI. Trudno jest znaleźć aplikację GUI na Maca w tańszym asortymencie, która dobrze radzi sobie z SVG
Erik Engheim
4
Działa świetnie, ale daje ogromny obraz. Korzystając z optipng, byłem w stanie skompresować moje logo tekstowe z 3 megabajtów do ~ 20kB.
miek
2
evgexport tworzy OGROMNE pliki png w zależności od rozmiaru. Polecam svg2png, który wykorzystuje również PhantomJS do eksportu, ale tworzy znacznie mniejsze obrazy.
Aaron_H
112

To nie jest idealne, ale działa.

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

Zasadniczo zwiększa ono wystarczająco wysoką DPI (wystarczy wyszkolić / bezpiecznie zgadnąć), że zmiana rozmiaru odbywa się z odpowiednią jakością. Próbowałem znaleźć właściwe rozwiązanie tego problemu, ale po chwili zdecydowałem, że jest to wystarczające na moją obecną potrzebę.

Uwaga: użyj 200 x 200! wymusić podaną rozdzielczość

Hardev
źródło
4
Krycie i cienie utracone w moim przypadku.
jiyinyiyong
2
Nie mam złożonego pliku SVG, więc zadziałało to dla mnie. -resize 200%nie działało i musiałem określić rozmiar w pikselach.
jozxyqk
18
@jiyinyiyong Aby zachować przezroczystość tła w ImageMagick, użyj -background noneopcji wiersza poleceń. Aby zachować proporcje obrazu, możesz również określić tylko jeden wymiar, np. -resize 200Dla szerokości lub -resize x200wysokości. Zobacz: imagemagick.org/script/command-line-processing.php#geometry, aby uzyskać wyczerpujące opcje geometrii ImageMagick .
John
dla mnie też nie działa. Rezultat jest rozmazany.
mbonnin
(dotyczy to Linuksa, może dotyczyć systemu Windows), jeśli włączysz opcję -verbose w komunikatorach internetowych, wtedy wydaje się, że sam komunikator używa programu inkscape do utworzenia pośredniego pliku eps. dlatego sugerowałbym użycie Inkscape bezpośrednio, jak sugeruje @ 808sound
Northern-
55

Jeśli korzystasz z MacOS X i masz problemy z konwersją Imagemagick, możesz spróbować zainstalować go ponownie z RSVG lib. Korzystanie z HomeBrew:

brew remove imagemagick
brew install imagemagick --with-librsvg

Sprawdź, czy deleguje poprawnie:

$ 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

Powinien zostać wyświetlony rsvg.

Jose Alban
źródło
Nie działało dla mnie. W szczególności uruchomiłem, convert ic_comment_48px.svg -size 30x30 ic_comment_30px.pnga obraz wyjściowy to 48 x 48. Upewnij się, że imagemagick deleguje się do rsvg, jak już wyjaśniłeś.
Shane Creighton-Young
1
Działa idealnie dla mnie - domyślnie convertkonwersja SVG do PNG, ale wyniki były beznadziejne; po ponownej instalacji są idealne. Ponadto konwersja jest znacznie szybsza.
ssc
1
To działało mi na Mac OSX. Nie znajduję nowej konwersji szybciej, ale o wiele dokładniej. Gorąco polecam wszystkim użytkownikom Mac OSX.
HelloWorld,
1
To powinna być zaakceptowana odpowiedź, no cóż. Dziękuję, działałam jak urok i nigdy bym nie wiedziała, aby podjąć te kroki inaczej
sdailey
8
Na invalid option: --with-librsvg
mojejve
39

Wydaje się, że Inkscape nie działa, gdy jednostki SVG nie są px(np. Cm). Mam pusty obraz. Być może można to naprawić, zmieniając rozdzielczość, ale było to zbyt kłopotliwe.

Svgexport to program node.js, więc ogólnie nie jest użyteczny.

Konwersja Imagemagick działa dobrze z:

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

Jeśli używasz -resize, obraz jest rozmyty, a plik jest znacznie większy.

NAJLEPSZA

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

Jest najszybszy, ma najmniej zależności, a wynik jest o około 30% mniejszy niż konwersja. Zainstaluj librsvg2-bin, aby go zdobyć. Wygląda na to, że nie ma strony podręcznika, ale możesz wpisać:

~$ rsvg --help

uzyskać pomoc. Proste jest dobre.

wrzesień_konwerter
źródło
2
Jest to z pewnością najlepsza odpowiedź (nie wiem, dlaczego dwadzieścia różnych odpowiedzi daje tę samą odpowiedź imagemagick); zachowuje kolory i cienie i niczego nie psuje. Jednak, aby dopasować zachowanie zmiany rozmiaru imagemagick (w szczególności WxH oznacza przeskalowanie obrazu, aby zmieściło się w pudełku o tym rozmiarze, zachowując proporcje), -aparametr ten należy stosować z rsvg.
Mahmoud Al-Qudsi
1
To zepsuło moje obrazy, wszelkiego rodzaju dziwne artefakty. Inkscape wykonał lepszą pracę.
eleganckie kostki
1
Ostrzegam, brew install rsvgw OSX instaluje milion rzeczy - GDK, OpenSSL, Python itp.
Timmmm
4
Do Twojej wiadomości, bieżące polecenie instalacji to, brew install librsvga polecenie konwersji to rsvg-convert.
waldyrious
Zauważyłem, że librsvg (lub rsvg-convertw przypadku Arch) daje najlepsze i najbardziej spójne wyniki podczas konwersji skomplikowanych plików svg do png. Kontynuuj za pomocą, optipngaby zmniejszyć rozmiar pliku wyjściowego.
maktel
18

Po wykonaniu kroków z odpowiedzi Jose Albana udało mi się sprawić, by ImageMagick działał dobrze przy użyciu następującego polecenia:

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

Liczba 1536 pochodzi z szacunkowej gęstości boiska, zobacz tę odpowiedź, aby uzyskać więcej informacji.

Ian
źródło
15

Aby przeskalować obraz, -densitynależy użyć opcji. O ile wiem, standardowa gęstość wynosi 72 i odwzorowuje rozmiar 1: 1. Jeśli chcesz, aby wyjściowy png był dwa razy większy niż oryginalny plik SVG, ustaw gęstość na 72 * 2 = 144:

convert -density 144 source.svg target.png
Stanislav Schmidt
źródło
Pamiętaj, że opcje konwersji muszą znajdować się przed plikiem wejściowym. Tj. convert source.svg -density 144 target.pngNie przeskaluje obrazu.
Skippy le Grand Gourou
W rzeczywistości standardowa gęstość wydaje się wynosić 90. Tak więcconvert -density 180 source.svg target.png
adius
7

dlaczego nie spróbujesz wiersza polecenia inkscape, to jest mój plik nietoperza do konwersji wszystkich plików svg w tym katalogu do png:

DLA %% x IN (* .svg) DO C: \ Ink \ App \ Inkscape \ inkscape.exe %% x -z --export-dpi = 500 - rysunek obszaru eksportu --export-png = "% % ~ nx.png "

wzmacniacze
źródło
4

Przyszedłem do tego postu - ale chciałem tylko przeprowadzić konwersję wsadowo i szybko bez użycia jakichkolwiek parametrów (ze względu na kilka plików o różnych rozmiarach).

rsvg drawing.svg drawing.png

Dla mnie wymagania były prawdopodobnie nieco łatwiejsze niż dla oryginalnego autora. (Chciał używać SVG w MS PowerPoint, ale nie pozwala)

Qohelet
źródło
1
Dla porównania, w systemie macOS jest on instalowany przy brew install librsvgpomocy polecenia konwersji rsvg-convert.
waldyrious
w Ubutni jest to również rsvg-convert, pakiet to librsvg2-bin, a wynik wymaga -o drawing.png
teknopaul
4

W ImageMagick można uzyskać lepsze renderowanie SVG, jeśli używa się Inkscape lub RSVG z ImageMagick, niż własnego renderowanego MSVG / XML. RSVG jest delegatem, który musi zostać zainstalowany wraz z ImageMagick. Jeśli Inkscape jest zainstalowany w systemie, ImageMagick użyje go automatycznie. Używam Inkscape w ImageMagick poniżej.

Nie ma parametru „magii”, który spełni Twoje oczekiwania.

Ale można bardzo dokładnie obliczyć dokładną gęstość potrzebną do renderowania wyniku.

Oto mały przycisk 50 x 50, gdy jest renderowany przy domyślnej gęstości 96:

convert button.svg button1.png


wprowadź opis zdjęcia tutaj

Załóżmy, że chcemy, aby wyjście wynosiło 500. Dane wejściowe to 50 przy domyślnej gęstości 96 (starsze wersje Inkscape mogą używać 92). Możesz więc obliczyć wymaganą gęstość proporcjonalnie do proporcji wymiarów i gęstości.

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


convert -density 983 button.svg button2.png


wprowadź opis zdjęcia tutaj

W ImageMagick 7 możesz wykonać obliczenia w linii w następujący sposób:

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
źródło
równanie w magicznej DSL było bardzo pomocne!
cyrf
2

Jedną rzeczą, która mnie ugryzła, było ustawienie -densityPO nazwie pliku wejściowego. To nie zadziałało. Przeniesienie go do pierwszej opcji w konwersji (zanim cokolwiek innego) sprawiło, że działał (dla mnie, YMMV itp.).

Nacięcie
źródło
2

Dla prostej konwersji SVG do PNG znalazłem cairosvg ( https://cairosvg.org/ ) działający lepiej niż ImageMagick. Kroki instalacji i uruchamiania wszystkich plików SVG w katalogu.

pip3 install cairosvg

Otwórz powłokę python w katalogu zawierającym pliki .svg i uruchom:

import os

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

Zapewni to również, że nie zastąpisz oryginalnych plików .svg, ale zachowa tę samą nazwę. Następnie możesz przenieść wszystkie pliki .png do innego katalogu za pomocą:

$ mv *.png [new directory]
edank
źródło
zawiesił się dla mnie w systemie Windows 10: zaimportuj cairocffi jako plik Cairo „c: \ program files (x86) \ python35-32 \ lib \ site-packages \ cairocffi_ init_ .py”, wiersz 39, w <module> cairo = dlopen (ffi , „cairo”, „cairo-2”, „cairo-gobject-2”, „cairo.so.2”) Plik „c: \ program files (x86) \ python35-32 \ lib \ site-packages \ cairocffi_ init_ .py ”, wiersz 36, w dlopen podwyższenie OSError („ dlopen () nie załadował biblioteki:% s "% '/' .join (nazwy)) OSError: dlopen () nie załadował biblioteki: cairo / cairo- 2 / cairo-gobject-2 / cairo.so.2
Pete Lomax
Fajnie, cairosvgna Ubuntu-19.04 zrobiło to za mnie.
fhgd
2

Bez librsvg możesz uzyskać czarny obraz png / jpeg. Musimy zainstalować librsvgnaconvert pliku svg za pomocą imagemagick.

Ubuntu

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

System operacyjny Mac

 brew install imagemagick librsvg
 convert -density 1200 test.svg test.png
TLbiz
źródło
Nie mam zainstalowanej tej biblioteki i nie otrzymuję również czarnych obrazów.
Aaron Franke,
1

Rozwiązałem ten problem, zmieniając atrybuty widthiheight<svg> tagu w celu dopasowania do zamierzonego rozmiaru wyjściowego, a następnie konwertując go za pomocą ImageMagick. Działa jak marzenie.

Oto mój kod Python, funkcja, która zwróci zawartość pliku 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
źródło
2
dlaczego miałbyś zwrócić obraz wygenerowany komputerowo jako jpeg :(?
Willi Mentzel,
1

Najlepsza odpowiedź @ 808sound nie działała dla mnie. Chciałem zmienić rozmiar Pakiet interfejsu użytkownika Kenney.nl

i dostał Kenney UI Pack zawiedli

Zamiast więc otworzyłem Inkscape, a następnie udał się File, Export as PNG filea okno GUI pojawił się, że pozwolił mi ustawić dokładne wymiary potrzebne.

Wersja na Ubuntu 16.04 Linux: Inkscape 0.91 (September 2016)

( Nawiasem mówiąc, to zdjęcie pochodzi z pakietów zasobów Kenney.nl )

James L.
źródło
1

W systemie macOS korzystającym z brew, użycie librsvg bezpośrednio działa dobrze

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

Wiele opcji jest dostępnych za pośrednictwem rsvg-convert --help

mloughran
źródło
0

W systemie Linux z Inkscape 1.0 do konwersji z SVG do PNG należy użyć

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

nie

inkscape -w 1024 -h 1024 input.svg --export-filename output.png
sbkm
źródło