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?


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))

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)

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))

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()))

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)))

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!


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 .


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()
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.