Làm cách nào để chuyển đổi SVG thành PNG bằng ImageMagick?


388

Tôi có một tệp SVG có kích thước xác định là 16x16. Khi tôi sử dụng chương trình chuyển đổi của ImageMagick để chuyển đổi nó thành PNG, thì tôi nhận được một pixel 16x16 pixel quá nhỏ:

convert test.svg test.png

Tôi cần chỉ định kích thước pixel của PNG đầu ra. -sizetham số dường như bị bỏ qua, -scaletham số chia tỷ lệ PNG sau khi nó được chuyển đổi thành PNG. Kết quả tốt nhất cho đến nay tôi nhận được bằng cách sử dụng -densitytham số:

convert -density 1200 test.svg test.png

Nhưng tôi không hài lòng, vì tôi muốn chỉ định kích thước đầu ra bằng pixel mà không làm toán để tính giá trị mật độ. Vì vậy, tôi muốn làm một cái gì đó như thế này:

convert -setTheOutputSizeOfThePng 1024x1024 test.svg test.png

Vậy thông số ma thuật tôi phải sử dụng ở đây là gì?


6
ví dụ như -size 1024x1024đang hoạt động tốt, phiên bản tưởng tượng của bạn là gì?
Dejan Marjanovic


2
ImageMagick-6.9.0-Q16. chuyển đổi -resize 1024x1024 foo.svg foo.png hoạt động tốt.
Jichao 10/03/2015

11
@Jichao -resizechỉ kéo dài hình ảnh được chuyển đổi, với kết quả chất lượng kém.
Elist

5
convert -size 1024x1024 test.svg test.pnghoạt động tốt với ImageMagick 7.0.7-0 Q16 (phiên bản hiện tại trong Chocolatey repo cho Windows). Chỉ cần đảm bảo rằng -sizexuất hiện trước tên tệp đầu vào, nếu không, ảnh 16x16 sẽ được nâng cấp để cho kết quả mờ.
Futal

Câu trả lời:


502

Tôi đã không thể có được kết quả tốt từ ImageMagick trong trường hợp này, nhưng Inkscape thực hiện công việc tốt trên Linux và Windows:

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

Chỉnh sửa (tháng 5 năm 2020): Người dùng Inkscape 1.0, xin lưu ý rằng các đối số dòng lệnh đã thay đổi:

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

Đây là kết quả của việc nhân rộng 16x16 SVG thành 200x200 PNG bằng lệnh này:

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

Chỉ để tham khảo, phiên bản Inkscape của tôi (trên Ubuntu 12.04) là:

Inkscape 0.48.3.1 r9886 (Mar 29 2012)

và trên Windows 7, đó là:

Inkscape 0.48.4 r9939 (Dec 17 2012)

15
+1 khi có liên quan đến hình ảnh. Dường như có vấn đề với động cơ SVG. Trong hầu hết các trường hợp, tôi không thể có được kết quả chính xác với nó. Inkscape, OTOH, hoạt động hoàn toàn tốt.
Glutimate

13
Tôi nghĩ Inkscape là ví dụ ấn tượng nhất về OSS sau chính Linux. Cảm ơn vì tiền hỗ trợ!
kim3er

8
Hoạt động độc đáo trên OSX.
Jonas Granvik

12
Trên OSX, với Inkscape được cài đặt cho X11, nó hoạt động với tôi bằng cách sử dụng:/Applications/Inkscape.app/Contents/Resources/bin/inkscape -z -e test.png -w 1024 -h 1024 test.svg
chmullig

11
@ Rörd Để giữ nền trong suốt với ImageMagick, hãy sử dụng -background nonetùy chọn dòng lệnh.
Giăng

142

Hãy dùng thử Svgexport :

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

svgexport là một công cụ dòng lệnh đa nền tảng đơn giản mà tôi đã thực hiện để xuất các tệp svg sang jpg và png, xem tại đây để biết thêm tùy chọn. Để cài đặt svgexport cài đặt NPM , sau đó chạy:

npm install svgexport -g

Chỉnh sửa: Nếu bạn thấy có vấn đề với thư viện, vui lòng gửi nó trên GitHub, cảm ơn!


4
svgexport đã làm việc rất tốt cho tôi. Đầu ra khớp với kết xuất trình duyệt chặt chẽ hơn nhiều so với ImageMagick.
t9mike

5
chất lượng svgexport thực sự rất cao. Bây giờ nó đã trở thành công cụ yêu thích của tôi, cảm ơn shakiba! :)
Alessio Periloso

1
điều này làm việc tốt cho tôi là tốt. Trình tiết kiệm thời gian thực so với thực hiện thủ công trong công cụ GUI. Khá khó để tìm thấy một ứng dụng GUI trên mac trong phạm vi rẻ hơn dù xử lý tốt SVG
Erik Engheim

4
Hoạt động tuyệt vời, nhưng tạo ra một hình ảnh lớn. Sử dụng optipng, tôi có thể nén logo văn bản của mình xuống từ 3 megabyte xuống ~ 20kB.
miek

2
evgexport tạo các tệp png HUGE tùy thuộc vào kích thước. Đề xuất svg2png cũng sử dụng PhantomJS để xuất, nhưng tạo ra hình ảnh nhỏ hơn nhiều.
Aaron_H

112

Điều này không hoàn hảo nhưng nó thực hiện công việc.

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

Về cơ bản, nó làm tăng DPI đủ cao (chỉ cần sử dụng dự đoán có giáo dục / an toàn) rằng thay đổi kích thước được thực hiện với chất lượng đầy đủ. Tôi đã cố gắng tìm một giải pháp thích hợp cho vấn đề này nhưng sau một thời gian quyết định nó đã đủ tốt cho nhu cầu hiện tại của tôi.

Lưu ý: Sử dụng 200x200! để buộc độ phân giải nhất định


4
Độ mờ và bóng mất trong trường hợp của tôi.
jiyinyiyong

2
Tôi không có Svg phức tạp vì vậy điều này làm việc cho tôi. -resize 200%không hoạt động và tôi phải chỉ định kích thước bằng pixel.
jozxyqk

18
@jiyinyiyong Để giữ nền trong suốt với ImageMagick, hãy sử dụng -background nonetùy chọn dòng lệnh. Để giữ tỷ lệ hình ảnh, bạn cũng có thể chỉ định một chiều như -resize 200chiều rộng hoặc -resize x200chiều cao. Xem: fantemagick.org/script/command-line- Processing.php# geometry để biết các tùy chọn hình học ImageMagick đầy đủ .
Giăng

tôi cũng không làm việc Kết quả là tất cả mờ.
mbonnin 7/07/2015

(điều này áp dụng cho linux, có thể áp dụng cho windows) nếu bạn bật -verbose trên IM thì có vẻ như chính IM sử dụng inkscape để tạo tệp eps trung gian. do đó tôi sẽ đề xuất sử dụng inkscape trực tiếp theo đề xuất của @ 808sound
phía bắc-bradley

55

Nếu bạn đang sử dụng MacOS X và gặp sự cố với chuyển đổi của Imagemagick, bạn có thể thử cài đặt lại nó với RSVG lib. Sử dụng HomeBrew:

brew remove imagemagick
brew install imagemagick --with-librsvg

Xác minh rằng nó ủy nhiệm chính xác:

$ 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

Nó sẽ hiển thị rsvg.


Không làm việc cho tôi. Cụ thể tôi đã chạy convert ic_comment_48px.svg -size 30x30 ic_comment_30px.pngvà hình ảnh đầu ra là 48 x 48. Hãy chắc chắn rằng hình ảnh được ủy quyền cho rsvg như bạn đã giải thích.
Shane Creighton-Young

1
Làm việc hoàn hảo với tôi - mặc định convertđã chuyển đổi Svg sang png, nhưng kết quả là vô vọng; Sau khi cài đặt lại, chúng hoàn hảo. Ngoài ra, chuyển đổi là nhanh hơn đáng kể.
ssc

1
Điều này làm việc với tôi trên Mac OSX. Tôi không tìm thấy chuyển đổi mới nhanh hơn, nhưng chính xác hơn nhiều. Tôi đặc biệt khuyên tất cả người dùng Mac OSX hãy dùng thử.
HelloWorld

1
Đây phải là câu trả lời được chấp nhận, oh tốt. Cảm ơn bạn, đã làm việc như một cơ duyên và tôi sẽ không bao giờ biết thực hiện các bước này nếu không
sdailey

8
Trên mojave tôi nhận đượcinvalid option: --with-librsvg
zaitsman

39

Inkscape dường như không hoạt động khi các đơn vị svg không px(ví dụ cm). Tôi có một hình ảnh trống. Có lẽ, nó có thể được sửa bằng cách xoay dpi, nhưng nó quá rắc rối.

Svgexport là một chương trình node.js và do đó thường không hữu ích.

Chuyển đổi của Imagemagick hoạt động tốt với:

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

Nếu bạn sử dụng -resize, hình ảnh mờ và tập tin lớn hơn nhiều.

TỐT

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

Nó là nhanh nhất, có ít phụ thuộc nhất và sản lượng nhỏ hơn khoảng 30% so với chuyển đổi. Cài đặt librsvg2-bin để có được nó. Có vẻ như không có trang nam nhưng bạn có thể gõ:

~$ rsvg --help

để được giúp đỡ Đơn giản là tốt.


2
Đây dễ dàng là câu trả lời tốt nhất (tôi không biết tại sao hai mươi câu trả lời khác nhau cho cùng một câu trả lời tưởng tượng); nó bảo tồn màu sắc và bóng tối và không mang bất cứ thứ gì. Tuy nhiên, để phù hợp với hành vi thay đổi kích thước của hình ảnh (cụ thể, WxH có nghĩa là hình ảnh tỷ lệ phù hợp với một hộp có kích thước đó, giữ nguyên tỷ lệ khung hình), -anên sử dụng tham số với rsvg.
Mahmoud Al-Qudsi

1
Điều này làm hỏng hình ảnh của tôi, tất cả các loại tạo tác kỳ lạ. inkscape đã làm một công việc tốt hơn.
súc sắc thanh lịch

1
Được cảnh báo, brew install rsvgtrên OSX cài đặt một triệu thứ - GDK, OpenSSL, Python, v.v.
Timmmm

4
FYI, lệnh cài đặt hiện tại là brew install librsvgvà lệnh chuyển đổi là rsvg-convert.
waldyrious

Tôi đã tìm thấy librsvg (hoặc rsvg-converttrong trường hợp của Arch) để đưa ra kết quả tốt nhất và nhất quán nhất khi chuyển đổi các Svss phức tạp sang png. Theo dõi optipngđể giảm kích thước tập tin đầu ra.
maktel

18

Sau khi làm theo các bước trong câu trả lời của Jose Alban , tôi đã có thể khiến ImageMagick hoạt động tốt bằng cách sử dụng lệnh sau:

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

Số 1536 xuất phát từ ước tính mật độ sân bóng, xem câu trả lời này để biết thêm thông tin.


15

Để chỉnh lại hình ảnh, -densitynên sử dụng tùy chọn này. Theo tôi biết mật độ tiêu chuẩn là 72 và ánh xạ kích thước 1: 1. Nếu bạn muốn png đầu ra lớn gấp đôi so với svg ban đầu, hãy đặt mật độ thành 72 * 2 = 144:

convert -density 144 source.svg target.png

Lưu ý rằng các tùy chọn chuyển đổi phải ở trước tệp đầu vào. Tức là convert source.svg -density 144 target.pngsẽ không bán lại hình ảnh.
Skippy le Grand Gourou

Trên thực tế, mật độ tiêu chuẩn dường như là 90. Vì vậy, nó sẽ làconvert -density 180 source.svg target.png
adius

7

Tại sao bạn không thử dòng lệnh inkscape, đây là tệp bat của tôi để chuyển đổi tất cả các Svg trong thư mục này sang png:

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


4

Tôi đã đến bài đăng này - nhưng tôi chỉ muốn thực hiện chuyển đổi theo đợt và nhanh chóng mà không sử dụng bất kỳ tham số nào (do một số tệp có kích thước khác nhau).

rsvg drawing.svg drawing.png

Đối với tôi, các yêu cầu có lẽ dễ hơn một chút so với tác giả gốc. (Muốn sử dụng SVG trong MS PowerPoint, nhưng không cho phép)


1
Để tham khảo, trên macOS, phần này được cài đặt brew install librsvgvà lệnh chuyển đổi là rsvg-convert.
waldyrious

trong Ubutni cũng là rsvg-convert, gói là librsvg2-bin và đầu ra cần -o
vẽ.png

4

Trong ImageMagick, người ta sẽ có kết xuất SVG tốt hơn nếu người ta sử dụng Inkscape hoặc RSVG với ImageMagick so với kết xuất MSVG / XML bên trong của chính nó. RSVG là một đại biểu cần được cài đặt với ImageMagick. Nếu Inkscape được cài đặt trên hệ thống, ImageMagick sẽ tự động sử dụng nó. Tôi sử dụng Inkscape trong ImageMagick bên dưới.

Không có tham số "ma thuật" nào sẽ làm những gì bạn muốn.

Nhưng, người ta có thể tính toán rất đơn giản mật độ chính xác cần thiết để hiển thị đầu ra.

Đây là một nút 50x50 nhỏ khi được hiển thị ở mật độ mặc định là 96:

convert button.svg button1.png


nhập mô tả hình ảnh ở đây

Giả sử chúng ta muốn đầu ra là 500. Đầu vào là 50 với mật độ mặc định là 96 (các phiên bản cũ hơn của Inkscape có thể đang sử dụng 92). Vì vậy, bạn có thể tính mật độ cần thiết theo tỷ lệ với tỷ lệ kích thước và mật độ.

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


convert -density 983 button.svg button2.png


nhập mô tả hình ảnh ở đây

Trong ImageMagick 7, bạn có thể thực hiện tính toán nội tuyến như sau:

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

phương trình trong DSL ảo rất hữu ích!
cyrf

2

Một điều mà chỉ cần bit tôi là thiết lập -densitySAU tên tệp đầu vào. Điều đó đã không làm việc. Chuyển nó sang tùy chọn đầu tiên trong convert (trước bất cứ thứ gì khác) làm cho nó hoạt động (đối với tôi, YMMV, v.v.).


2

Để chuyển đổi SVG sang PNG đơn giản, tôi thấy cairosvg ( https://cairosvg.org/ ) hoạt động tốt hơn ImageMagick. Các bước để cài đặt và chạy trên tất cả các tệp SVG trong thư mục của bạn.

pip3 install cairosvg

Mở shell python trong thư mục chứa các tệp .svg của bạn và chạy:

import os

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

Điều này cũng sẽ đảm bảo bạn không ghi đè lên các tệp .svg ban đầu của mình, nhưng sẽ giữ nguyên tên. Sau đó, bạn có thể di chuyển tất cả các tệp .png của mình sang thư mục khác với:

$ mv *.png [new directory]

gặp sự cố với tôi trên windows 10: nhập cairocffi dưới dạng cairo Tệp "c: \ chương trình (x86) \ python35-32 \ lib \ site-gói \ cairocffi_ init_ .py", dòng 39, trong <module> cairo = dlopen (ffi , 'cairo', 'cairo-2', 'cairo-gobject-2', 'cairo.so.2') Tệp "c: \ chương trình tệp (x86) \ python35-32 \ lib \ site-gói \ cairocffi_ init_ .py ", dòng 36, trong dlopen nâng OSError (" dlopen () không tải được thư viện:% s "% '/' .join (tên)) OSError: dlopen () không tải được thư viện: cairo / cairo- 2 / cairo-gobject-2 / cairo.so.2
Pete Lomax

Thật tuyệt, cairosvgtrên Ubuntu-19.04 đã làm việc đó cho tôi.
fhgd

2

Nếu không có librsvg, bạn có thể có được hình ảnh png / jpeg màu đen. Chúng tôi phải cài đặt librsvgvào converttập tin svg với fantemagick.

Ubuntu

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

Hệ điều hành Mac

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

Tôi không cài đặt thư viện này và tôi cũng không nhận được hình ảnh màu đen.
Aaron Franke

1

Tôi đã giải quyết vấn đề này thông qua việc thay đổi các thuộc tính widthvà thẻ của thẻ để phù hợp với kích thước đầu ra dự định của tôi và sau đó chuyển đổi nó bằng ImageMagick. Hoạt động như một lá bùa.height<svg>

Đây là mã Python của tôi, một hàm sẽ trả về nội dung của tệp 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
tại sao bạn lại trả lại hình ảnh được tạo từ máy tính dưới dạng jpeg :(?
Willi Mentzel

1

Câu trả lời hàng đầu của @ 808sound không phù hợp với tôi. Tôi muốn thay đổi kích thước Gói giao diện người dùng của Kenney.nl

và có Gói UI của Kenney bị rối

Vì vậy, thay vào đó tôi mở ra Inkscape, sau đó đi đến File, Export as PNG filevà một hộp GUI hiện lên cho phép tôi để thiết lập kích thước chính xác tôi cần.

Phiên bản trên Ubuntu 16.04 Linux: Inkscape 0.91 (September 2016)

(Nhân tiện, hình ảnh này là từ gói tài sản của Kenney.nl )


1

Trên macOS sử dụng brew, sử dụng librsvg trực tiếp hoạt động tốt

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

Nhiều tùy chọn có sẵn thông qua rsvg-convert --help


0

Trên Linux với Inkscape 1.0 để chuyển đổi từ svg sang png cần sử dụng

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

không phải

inkscape -w 1024 -h 1024 input.svg --export-filename output.png
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.