Bagaimana cara membaca data gambar dari URL dengan Python?

182

Apa yang saya coba lakukan cukup sederhana ketika kita berurusan dengan file lokal, tetapi masalahnya muncul ketika saya mencoba melakukan ini dengan URL jarak jauh.

Pada dasarnya, saya mencoba membuat objek gambar PIL dari file yang ditarik dari URL. Tentu, saya selalu bisa mengambil URL dan menyimpannya dalam file temp, lalu membukanya menjadi objek gambar, tetapi rasanya sangat tidak efisien.

Inilah yang saya miliki:

Image.open(urlopen(url))

Itu mengeluhkan keluhan yang seek()tidak tersedia, jadi saya mencoba ini:

Image.open(urlopen(url).read())

Tapi itu juga tidak berhasil. Apakah ada Cara yang Lebih Baik untuk melakukan ini, atau menulis ke file sementara cara yang diterima untuk melakukan hal semacam ini?

Daniel Quinn
sumber

Jawaban:

281

Dalam Python3 modul StringIO dan cStringIO hilang.

Di Python3 Anda harus menggunakan:

from PIL import Image
import requests
from io import BytesIO

response = requests.get(url)
img = Image.open(BytesIO(response.content))
Andres Kull
sumber
Bagaimana cara mendapatkan kembali gambar dari response.content?
Amresh Giri
requestsPaket melempar 503 kode status sambil mengambil gambar dari URL. Sebagai gantinya, saya harus resor http.clientuntuk mendapatkan gambar.
Manishankar Singh
Ketika saya mencoba ini saya mendapatkan: AttributeError: modul 'permintaan' tidak memiliki atribut 'dapatkan'.
apiljic
2
Membungkus BytesIO secara manual tidak lagi diperlukan karena PIL> = 2.8.0. Gunakan saja Image.open(response.raw). PIL secara otomatis memeriksa itu sekarang dan apakah pembungkus BytesIO di bawah tenda. Dari: pillow.readthedocs.io/en/3.0.x/releasenotes/2.8.0.html
Vinícius M
Terima kasihUUUUUUUUUUUU, OP.
Sharl Sherif
166

Anda bisa mencoba menggunakan StringIO

import urllib, cStringIO

file = cStringIO.StringIO(urllib.urlopen(URL).read())
img = Image.open(file)
Fábio Diniz
sumber
Terima kasih, akan seperti menambahkan bahwa kode yang sama persis akan bekerja dengan urllib2 (dengan python2)
sofly
17
dalam python 3 itu akan dari urllib.request impor urlopen dan io.io.BytesIO alih-alih StringIO
matyas
2
HELP, IOError: tidak dapat mengidentifikasi file gambar <object _io.BytesIO di 0x7fb91b6a29b0> url saya adalah: ... model = product.template & id = 16 & field = image_medium
С. Дэлгэрцэцэг
56

Saya menggunakan perpustakaan permintaan. Tampaknya lebih kuat.

from PIL import Image
import requests
from StringIO import StringIO

response = requests.get(url)
img = Image.open(StringIO(response.content))
Saurav
sumber
3
Untuk beberapa alasan urllib tidak berfungsi untuk beberapa URL, tetapi permintaan berhasil jika gagal
mirri66
Saya tidak dapat menemukan paket PIL, tetapi sepertinya bantal telah mengambil alih upaya PIL dan Anda dapat menginstalnya dengan python3 pip3.4 install pillow.
Mengganggu
3
Perhatikan bahwa permintaan akan memuat seluruh respons ke dalam memori, dan kemudian PIL akan memuat semuanya kembali sebagai gambar, sehingga Anda memiliki dua salinan lengkap yang ada di memori. Jawaban sebelumnya menggunakan metode urllib mengalirkan data, sehingga Anda hanya berakhir dengan satu salinan plus ukuran buffer streaming. Anda dapat mengalirkan data dengan permintaan juga, tetapi karena responsnya tidak mendukung semantik baca (), Anda harus membuat adaptor.
sirdodger
@sirdodger Apakah Anda merujuk ke urllib2 atau urllib?
CMCDragonkai
@ CMCDragonkai saya merujuk pada jawaban urllib yang diterima. Jika overhead memori menjadi masalah, lebih baik daripada menggunakan jawaban permintaan ini. (Namun, seperti yang saya sebutkan, solusi berbeda menggunakan permintaan dapat mencapai efek yang sama.)
sirdodger
27

Gunakan StringIOuntuk mengubah string baca menjadi objek seperti file:

from StringIO import StringIO
import urllib

Image.open(StringIO(urllib.requests.urlopen(url).read()))
Dan D.
sumber
21

Bagi mereka yang melakukan pemrosesan post sklearn / numpy (mis. Deep learning) Anda dapat membungkus objek PIL dengan np.array (). Ini mungkin menyelamatkan Anda dari keharusan ke Google seperti yang saya lakukan:

from PIL import Image
import requests
import numpy as np
from StringIO import StringIO

response = requests.get(url)
img = np.array(Image.open(StringIO(response.content)))
Ben
sumber
19

Python 3

from urllib.request import urlopen
from PIL import Image

img = Image.open(urlopen(url))
img

Jupyter Notebook dan IPython

import IPython
url = 'https://newevolutiondesigns.com/images/freebies/colorful-background-14.jpg'
IPython.display.Image(url, width = 250)

Tidak seperti metode lain, metode ini juga berfungsi dalam for for!

Miladiouss
sumber
12

Cara yang disarankan untuk melakukan input / output gambar hari ini adalah dengan menggunakan paket khusus ImageIO . Data gambar dapat dibaca langsung dari URL dengan satu baris kode sederhana:

from imageio import imread
image = imread('https://cdn.sstatic.net/Sites/stackoverflow/img/logo.png')

Banyak jawaban di halaman ini sebelum rilis paket itu dan karenanya tidak menyebutkannya. ImageIO dimulai sebagai komponen dari toolkit Scikit-Image . Ini mendukung sejumlah format ilmiah di atas yang disediakan oleh perpustakaan pemrosesan gambar PILlow yang populer . Itu membungkus semuanya dalam API bersih hanya berfokus pada input / output gambar. Faktanya, SciPy menghapus image reader / writer-nya sendiri demi ImageIO .

segera
sumber
3

pilih gambar dalam chrome, klik kanan padanya, klik Copy image address, tempel ke strvariabel ( my_url) untuk membaca gambar:

import shutil
import requests

my_url = 'https://www.washingtonian.com/wp-content/uploads/2017/06/6-30-17-goat-yoga-congressional-cemetery-1-994x559.jpg'
response = requests.get(my_url, stream=True)
with open('my_image.png', 'wb') as file:
    shutil.copyfileobj(response.raw, file)
del response

Buka;

from PIL import Image

img = Image.open('my_image.png')
img.show()
Terpisah
sumber