Bagaimana saya mengkonversi svgke png, di Python? Saya menyimpan svgdalam sebuah contoh StringIO. Haruskah saya menggunakan pustaka pyCairo? Bagaimana cara menulis kode itu?
Utas itu membuat masalah tidak terpecahkan. Jawaban yang diterima datang dari penanya yang membagikan percobaan kode yang gagal. Jawaban lain menyarankan ImageMagick tetapi seorang komentator mengatakan ImageMagick melakukan "pekerjaan yang mengerikan dalam menafsirkan SVG." Saya tidak ingin gambar png saya terlihat mengerikan, jadi saya mengajukan pertanyaan kembali.
Contoh di tautan itu khusus untuk Win32. Saya menjalankan linux.
ram1
Lihatlah posting blog ini , sepertinya itu yang Anda butuhkan.
giodamelio
Jawaban:
60
Jawabannya adalah " pyrsvg " - pengikatan Python untuk librsvg .
Ada paket Ubuntu python-rsvg yang menyediakannya. Mencari namanya di Google buruk karena kode sumbernya tampaknya terdapat di dalam repositori GIT proyek Gnome "gnome-python-desktop".
Saya membuat "hello world" minimalis yang merender SVG ke permukaan Kairo dan menulisnya ke disk:
Update : sebagai 2014 paket yang diperlukan untuk distribusi Fedora Linux adalah: gnome-python2-rsvg. Daftar potongan di atas masih berfungsi apa adanya.
Bagus, berfungsi dengan baik. Tetapi apakah ada cara untuk cairomenentukan TINGGI dan LEBAR gambar itu sendiri? Saya telah melihat ke dalam *.svgfile tersebut, untuk mengekstrak HEIGHT dan WIDTH dari sana, tetapi keduanya diatur ke 100%. Tentu saja, saya dapat melihat properti gambar, tetapi karena ini hanya satu langkah dalam pemrosesan gambar, ini bukan yang saya inginkan.
quapka
1
Jika "lebar" dan "tinggi" file Anda disetel ke 100%, tidak ada keajaiban yang dapat dilakukan Kairo atau rsvg untuk menebak ukurannya: file SVG seperti itu dibiarkan berukuran independen oleh perangkat lunak pembuat (/ orang). Kode HTML di sekitarnya untuk mengimpor file SVG akan memberikan ukuran fisik. Namun, objek "Handle" dari rsvg memiliki .get_dimension_data()metode yang bekerja untuk file contoh saya (SVG yang berperilaku baik) - cobalah.
jsbueno
1
per 2014, untuk ubuntu, Anda dapat menggunakan: apt-get install python-rsvg
t1m0
1
Apakah ada perintah cepat untuk menambahkan latar belakang putih ke gambar jika latar belakangnya sekarang transparan?
fiatjaf
@jsbueno Saya menggunakan Windows 8.1 dan python 2.7.11 Bagaimana cara menginstal cairo dan rsvg dan membuatnya bekerja. Saya berjuang untuk membuat ini berhasil. BTW +1 untuk penjelasan rinci Anda.
Hai. Tahukah Anda bagaimana saya bisa melakukan hal yang sama tetapi tanpa menulis ke file? Saya perlu mendorong konten png ke browser dari server web, sehingga pengguna dapat mengunduh gambar. Menyimpan file png bukanlah opsi yang valid dalam proyek kami, itulah mengapa saya membutuhkannya seperti itu. Terima kasih
estemendoza
4
Saya telah melakukan ini sendiri. Ini pada dasarnya tergantung pada alat atau kerangka kerja apa yang Anda miliki saat menangani permintaan web Anda, tetapi tidak peduli apa itu, ide dasarnya adalah svg2pngmengambil streamobjek di write_toparameter, dan ini bisa menjadi objek Respons HTTP Anda (yang kebanyakan kerangka kerja adalah objek seperti file) atau aliran lain, yang kemudian Anda tayangkan ke browser menggunakan Content-Dispositiontajuk. lihat di sini: stackoverflow.com/questions/1012437/…
nemesisfixx
4
Bagi mereka yang mengalami masalah dengan kode itu, seperti saya: 1). bytestringmenerima byte, jadi konversikan string terlebih dahulu dengan bytestring=bytes(svg,'UTF-8') 2). mode file harus biner, jadiopen('output.png','wb')
Serj Zaharchenko
3
cairosvg hanya mendukung Python 3.4+. Mereka telah menghentikan dukungan Python 2
Marlon Abeykoon
1
Tidak ada svg2pnguntuk saya, saya harus menggunakan cairosvg.surface.PNGSurface.convert(svg_str, write_to='output.png').
Anda juga dapat mengambil area persegi panjang tertentu hanya menggunakan parameter -j, misalnya koordinat "0: 125: 451: 217"
${INKSCAPE_PATH}-z -f ${source_svg}-w ${width}-j -a ${coordinates}-e ${dest_png}
Jika Anda hanya ingin menampilkan satu objek di file SVG, Anda dapat menentukan parameter -idengan id objek yang telah Anda siapkan di SVG. Itu menyembunyikan yang lainnya.
${INKSCAPE_PATH}-z -f ${source_svg}-w ${width}-i ${object}-j -a ${coordinates}-e ${dest_png}
1 karena ini juga sangat berguna untuk skrip shell. Lihat inkscape.org/doc/inkscape-man.html untuk dokumen lengkap tentang baris perintah Inkscape.
Perdana
Terima kasih, ini adalah cara termudah yang saya temukan untuk melakukan ini. Di Windows, agar Anda tidak perlu mengetikkan path lengkap ke Inkscape setiap saat, Anda bisa menambahkannya ke Path di Variabel Lingkungan .
Alex S
3
Ini bukanlah jawaban. Ini solusinya. OP meminta solusi Python.
lamino
31
Saya menggunakan Wand-py (implementasi pembungkus Wand di sekitar ImageMagick) untuk mengimpor beberapa SVG yang cukup canggih dan sejauh ini telah melihat hasil yang bagus! Ini semua kode yang dibutuhkan:
with wand.image.Image( blob=svg_file.read(), format="svg")as image:
png_image = image.make_blob("png")
Saya baru saja menemukan ini hari ini, dan merasa layak untuk dibagikan kepada siapa pun yang mungkin kesulitan menemukan jawaban ini karena sudah lama sejak sebagian besar pertanyaan ini dijawab.
CATATAN: Secara teknis dalam pengujian saya menemukan Anda bahkan tidak benar-benar harus mengirimkan parameter format untuk ImageMagick, jadi with wand.image.Image( blob=svg_file.read() ) as image:hanya itu yang benar-benar dibutuhkan.
EDIT: Dari percobaan pengeditan oleh qris, berikut beberapa kode berguna yang memungkinkan Anda menggunakan ImageMagick dengan SVG yang memiliki latar belakang transparan:
Wand bekerja jauh lebih baik daripada Kairo untuk PNG saya.
qris
3
Saya mendapatkan kesalahan image.read(blob=svg_file.read(), format="svg") NameError: name 'svg_file' is not defined
adrienlucca.wordpress.com
2
svg_filediasumsikan sebagai objek "file" dalam contoh ini, pengaturan svg_fileakan terlihat seperti:svg_file = File.open(file_name, "r")
streetlogics
2
Terima kasih, cairodan rsvgmetode 'diterima' tidak berfungsi untuk PDF saya. pip install wanddan cuplikan Anda berhasil;)
nmz787
5
Jika Anda memiliki svg strmaka Anda harus terlebih dahulu encode ke biner seperti ini: svg_blob = svg_str.encode('utf-8'). Sekarang Anda dapat menggunakan metode di atas dengan mengganti blob=svg_file.read()dengan blob=svg_blob.
@Simon, Bisakah kamu melakukannya? Saya terlalu sibuk dan saya akan berada dalam 1-2 bulan ke depan.
Ray
2
@Ray, sebenarnya opsi -d / --dpi telah ada untuk beberapa waktu sekarang, dan saya diberitahu bahwa dukungan untuk <clippath> telah ditambahkan beberapa minggu yang lalu dalam versi git.
Saya menggunakan ekstraksi lebar dan tinggi svg. Saya tidak yakin tentang standar svg tetapi di beberapa file svg saya lebar atau tinggi diikuti oleh string non numerik seperti 'mm' atau 'px' (misal: '250mm'). Int ('250mm') memberikan pengecualian dan saya harus membuat beberapa penyesuaian tambahan.
WigglyWorld
3
Saya tidak menemukan jawaban yang memuaskan. Semua pustaka yang disebutkan memiliki beberapa masalah atau yang lainnya seperti Kairo yang menjatuhkan dukungan untuk python 3.6 (mereka menjatuhkan dukungan Python 2 sekitar 3 tahun yang lalu!). Juga, menginstal pustaka yang disebutkan di Mac sangat menyebalkan.
Akhirnya, saya menemukan solusi terbaik adalah svglib + reportlab . Keduanya diinstal tanpa hambatan menggunakan pip dan panggilan pertama untuk mengonversi dari svg ke png bekerja dengan baik! Sangat senang dengan solusinya.
Hanya 2 perintah yang melakukan trik:
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPM
drawing = svg2rlg("my.svg")
renderPM.drawToFile(drawing,"my.png", fmt="PNG")
Apakah ada batasan dengan ini yang harus saya waspadai?
Menggunakan pycairo dan librsvg saya bisa mencapai penskalaan SVG dan rendering ke bitmap. Dengan asumsi SVG Anda tidak persis 256x256 piksel, keluaran yang diinginkan, Anda dapat membaca dalam konteks SVG ke Kairo menggunakan rsvg dan kemudian menskalakannya dan menulis ke PNG.
Terima kasih untuk ini, ini terbukti sangat berguna dalam proyek saya. Meskipun Handle.get_dimension_datatidak berhasil untuk saya. Saya harus menggantinya dengan pengambilan sederhana dari self.props.widthdan self.props.height. Saya pertama kali mencoba mendefinisikan RsvgDimensionDataStruktur seperti yang dijelaskan di situs web Kairo, tetapi tidak berhasil.
JeanOlivier
Saya mencoba menggunakan ini dalam proyek saya. Bagaimana cara mendapatkan file dll yang diperlukan?
Andoo
0
Berikut adalah pendekatan dimana Inkscape dipanggil oleh Python.
Perhatikan bahwa ini menekan output crufty tertentu yang ditulis Inkscape ke konsol (khususnya, stderr dan stdout) selama operasi normal bebas kesalahan. Outputnya ditangkap dalam dua variabel string, outdan err.
import subprocess # May want to use subprocess32 instead
cmd_list =['/full/path/to/inkscape','-z','--export-png','/path/to/output.png','--export-width',100,'--export-height',100,'/path/to/input.svg']# Invoke the command. Divert output that normally goes to stdout or stderr.
p = subprocess.Popen( cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE )# Below, < out > and < err > are strings or < None >, derived from stdout and stderr.
out, err = p.communicate()# Waits for process to terminate# Maybe do something with stdout output that is in < out ># Maybe do something with stderr output that is in < err >if p.returncode:raiseException('Inkscape error: '+(err or'?'))
Misalnya, saat menjalankan pekerjaan tertentu di sistem Mac OS saya, outakhirnya menjadi:
Background RRGGBBAA: ffffff00
Area0:0:339:339 exported to 100 x 100 pixels (72.4584 dpi)Bitmap saved as:/path/to/output.png
Ini bukan Python ujung ke ujung jika Anda mengandalkan Inkscape.
Joel
1
@ Joel: Baris pertama telah dimodifikasi untuk mengatasi keberatan Anda. Tetapi tentu saja, bahkan solusi Python "murni" bergantung pada elemen di luar bahasa inti, dan pada akhirnya dijalankan dengan bahasa mesin, jadi mungkin tidak ada yang namanya end-to-end!
Bantal Besi
0
Sebenarnya, saya tidak ingin bergantung pada apa pun selain Python (Kairo, Ink .., dll.) Persyaratan saya adalah sesederhana mungkin, paling-paling, yang sederhana pip install "savior"sudah cukup, itulah mengapa yang di atas tidak ' t cocok untukku.
Jawaban:
Jawabannya adalah " pyrsvg " - pengikatan Python untuk librsvg .
Ada paket Ubuntu python-rsvg yang menyediakannya. Mencari namanya di Google buruk karena kode sumbernya tampaknya terdapat di dalam repositori GIT proyek Gnome "gnome-python-desktop".
Saya membuat "hello world" minimalis yang merender SVG ke permukaan Kairo dan menulisnya ke disk:
Update : sebagai 2014 paket yang diperlukan untuk distribusi Fedora Linux adalah:
gnome-python2-rsvg
. Daftar potongan di atas masih berfungsi apa adanya.sumber
cairo
menentukan TINGGI dan LEBAR gambar itu sendiri? Saya telah melihat ke dalam*.svg
file tersebut, untuk mengekstrak HEIGHT dan WIDTH dari sana, tetapi keduanya diatur ke100%
. Tentu saja, saya dapat melihat properti gambar, tetapi karena ini hanya satu langkah dalam pemrosesan gambar, ini bukan yang saya inginkan..get_dimension_data()
metode yang bekerja untuk file contoh saya (SVG yang berperilaku baik) - cobalah.Inilah yang saya lakukan menggunakan cairosvg :
Dan itu bekerja seperti pesona!
Lihat lebih lanjut: dokumen cairosvg
sumber
svg2png
mengambilstream
objek diwrite_to
parameter, dan ini bisa menjadi objek Respons HTTP Anda (yang kebanyakan kerangka kerja adalah objek seperti file) atau aliran lain, yang kemudian Anda tayangkan ke browser menggunakanContent-Disposition
tajuk. lihat di sini: stackoverflow.com/questions/1012437/…bytestring
menerima byte, jadi konversikan string terlebih dahulu denganbytestring=bytes(svg,'UTF-8')
2). mode file harus biner, jadiopen('output.png','wb')
svg2png
untuk saya, saya harus menggunakancairosvg.surface.PNGSurface.convert(svg_str, write_to='output.png')
.Instal Inkscape dan sebut sebagai baris perintah:
Anda juga dapat mengambil area persegi panjang tertentu hanya menggunakan parameter
-j
, misalnya koordinat "0: 125: 451: 217"Jika Anda hanya ingin menampilkan satu objek di file SVG, Anda dapat menentukan parameter
-i
dengan id objek yang telah Anda siapkan di SVG. Itu menyembunyikan yang lainnya.sumber
Saya menggunakan Wand-py (implementasi pembungkus Wand di sekitar ImageMagick) untuk mengimpor beberapa SVG yang cukup canggih dan sejauh ini telah melihat hasil yang bagus! Ini semua kode yang dibutuhkan:
Saya baru saja menemukan ini hari ini, dan merasa layak untuk dibagikan kepada siapa pun yang mungkin kesulitan menemukan jawaban ini karena sudah lama sejak sebagian besar pertanyaan ini dijawab.
CATATAN: Secara teknis dalam pengujian saya menemukan Anda bahkan tidak benar-benar harus mengirimkan parameter format untuk ImageMagick, jadi
with wand.image.Image( blob=svg_file.read() ) as image:
hanya itu yang benar-benar dibutuhkan.EDIT: Dari percobaan pengeditan oleh qris, berikut beberapa kode berguna yang memungkinkan Anda menggunakan ImageMagick dengan SVG yang memiliki latar belakang transparan:
sumber
image.read(blob=svg_file.read(), format="svg") NameError: name 'svg_file' is not defined
svg_file
diasumsikan sebagai objek "file" dalam contoh ini, pengaturansvg_file
akan terlihat seperti:svg_file = File.open(file_name, "r")
cairo
danrsvg
metode 'diterima' tidak berfungsi untuk PDF saya.pip install wand
dan cuplikan Anda berhasil;)str
maka Anda harus terlebih dahulu encode ke biner seperti ini:svg_blob = svg_str.encode('utf-8')
. Sekarang Anda dapat menggunakan metode di atas dengan menggantiblob=svg_file.read()
denganblob=svg_blob
.Coba ini: http://cairosvg.org/
Situs itu mengatakan:
Pembaruan 25 November 2016 :
sumber
<clipPath><rect ... /></clipPath>
. Kedua, itu tidak mengambil opsi -d (DPI).Solusi lain yang baru saya temukan di sini Bagaimana cara merender SVG skala ke QImage?
PySide mudah diinstal dari paket biner di Windows (dan saya menggunakannya untuk hal lain, jadi mudah bagi saya).
Namun, saya melihat beberapa masalah saat mengonversi bendera negara dari Wikimedia, jadi mungkin bukan pengurai / penyaji svg yang paling kuat.
sumber
Sedikit tambahan untuk jawaban jsbueno:
sumber
Saya tidak menemukan jawaban yang memuaskan. Semua pustaka yang disebutkan memiliki beberapa masalah atau yang lainnya seperti Kairo yang menjatuhkan dukungan untuk python 3.6 (mereka menjatuhkan dukungan Python 2 sekitar 3 tahun yang lalu!). Juga, menginstal pustaka yang disebutkan di Mac sangat menyebalkan.
Akhirnya, saya menemukan solusi terbaik adalah svglib + reportlab . Keduanya diinstal tanpa hambatan menggunakan pip dan panggilan pertama untuk mengonversi dari svg ke png bekerja dengan baik! Sangat senang dengan solusinya.
Hanya 2 perintah yang melakukan trik:
Apakah ada batasan dengan ini yang harus saya waspadai?
sumber
Penskalaan SVG dan rendering PNG
Menggunakan pycairo dan librsvg saya bisa mencapai penskalaan SVG dan rendering ke bitmap. Dengan asumsi SVG Anda tidak persis 256x256 piksel, keluaran yang diinginkan, Anda dapat membaca dalam konteks SVG ke Kairo menggunakan rsvg dan kemudian menskalakannya dan menulis ke PNG.
main.py
Pengikatan RSVG C.
Dari situs Cario dengan sedikit modifikasi. Juga contoh yang baik tentang bagaimana memanggil pustaka-C dari Python
sumber
Handle.get_dimension_data
tidak berhasil untuk saya. Saya harus menggantinya dengan pengambilan sederhana dariself.props.width
danself.props.height
. Saya pertama kali mencoba mendefinisikanRsvgDimensionData
Struktur seperti yang dijelaskan di situs web Kairo, tetapi tidak berhasil.Berikut adalah pendekatan dimana Inkscape dipanggil oleh Python.
Perhatikan bahwa ini menekan output crufty tertentu yang ditulis Inkscape ke konsol (khususnya, stderr dan stdout) selama operasi normal bebas kesalahan. Outputnya ditangkap dalam dua variabel string,
out
danerr
.Misalnya, saat menjalankan pekerjaan tertentu di sistem Mac OS saya,
out
akhirnya menjadi:(File svg masukan berukuran 339 kali 339 piksel.)
sumber
Sebenarnya, saya tidak ingin bergantung pada apa pun selain Python (Kairo, Ink .., dll.) Persyaratan saya adalah sesederhana mungkin, paling-paling, yang sederhana
pip install "savior"
sudah cukup, itulah mengapa yang di atas tidak ' t cocok untukku.Saya berhasil melewati ini (melangkah lebih jauh dari Stackoverflow dalam penelitian). https://www.tutorialexample.com/best-practice-to-python-convert-svg-to-png-with-svglib-python-tutorial/
Tampak bagus, sejauh ini. Jadi saya membagikannya jika ada yang berada dalam situasi yang sama.
sumber