Làm cách nào để đọc dữ liệu hình ảnh từ một URL trong Python?


182

Những gì tôi đang cố gắng thực hiện khá đơn giản khi chúng tôi xử lý một tệp cục bộ, nhưng vấn đề xảy ra khi tôi cố gắng làm điều này với một URL từ xa.

Về cơ bản, tôi đang cố gắng tạo một đối tượng hình ảnh PIL từ một tệp được lấy từ một URL. Chắc chắn, tôi luôn có thể tìm nạp URL và lưu trữ nó trong một tệp tạm thời, sau đó mở nó vào một đối tượng hình ảnh, nhưng điều đó cảm thấy rất không hiệu quả.

Đây là những gì tôi có:

Image.open(urlopen(url))

Nó phàn nàn rằng seek()không có sẵn, vì vậy tôi đã thử điều này:

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

Nhưng điều đó cũng không hiệu quả. Có cách nào tốt hơn để làm điều này không, hay viết vào một tập tin tạm thời là cách được chấp nhận để làm việc này?


Câu trả lời:


281

Trong Python3, các mô-đun StringIO và cStringIO đã biến mất.

Trong Python3 bạn nên sử dụng:

from PIL import Image
import requests
from io import BytesIO

response = requests.get(url)
img = Image.open(BytesIO(response.content))

Làm thế nào để lấy lại hình ảnh từ answer.content?
Amresh Giri

requestsgói ném mã 503 trạng thái trong khi tìm nạp hình ảnh từ một URL. Thay vào đó, tôi đã phải dùng đến http.clientđể có được hình ảnh.
Manishankar Singh

Khi tôi thử điều này, tôi nhận được: AttributionError: module 'request' không có thuộc tính 'get'.
apiljic

2
Việc gói thủ công bằng BytesIO không còn cần thiết vì PIL> = 2.8.0. Chỉ cần sử dụng Image.open(response.raw). PIL tự động kiểm tra ngay bây giờ và thực hiện gói BytesIO dưới mui xe. Từ: gối.readthedocs.io/en/3.0.x/releasenotes/2.8.0.html
Vinícius M

CẢM ƠN YOUUUUUUUUUUUU, OP.
Sharl Sherif

166

bạn có thể thử sử dụng StringIO

import urllib, cStringIO

file = cStringIO.StringIO(urllib.urlopen(URL).read())
img = Image.open(file)

Cảm ơn, chỉ muốn thêm rằng cùng một mã chính xác sẽ hoạt động với urllib2 (với Python2)
nhẹ nhàng

17
trong python 3, nó sẽ là từ url url nhập vào urllib.request và io.io.BytesIO thay vì StringIO
matyas

2
TRỢ GIÚP, IOError: không thể xác định tệp hình ảnh <_io.BytesIO đối tượng tại 0x7fb91b6a29b0> url của tôi là: ... model = sản phẩm.template & id = 16 & field = image_medium
С. Trả lời

56

Tôi sử dụng thư viện yêu cầu. Nó dường như mạnh mẽ hơn.

from PIL import Image
import requests
from StringIO import StringIO

response = requests.get(url)
img = Image.open(StringIO(response.content))

3
Vì một số lý do, urllib không hoạt động đối với một số URL, nhưng các yêu cầu hoạt động ở nơi không thành công
mirri66

Tôi không thể tìm thấy gói PIL, nhưng có vẻ như gối đã chiếm hết nỗ lực của PIL và bạn có thể cài đặt cho python3 với pip3.4 install pillow.
gây rối

3
Lưu ý rằng các yêu cầu sẽ tải toàn bộ phản hồi vào bộ nhớ và sau đó PIL sẽ tải lại toàn bộ nội dung dưới dạng hình ảnh, do đó bạn có hai bản sao đầy đủ trong bộ nhớ. Câu trả lời trước đó sử dụng phương thức urllib truyền dữ liệu, vì vậy bạn chỉ kết thúc với một bản sao cộng với kích thước bộ đệm phát trực tuyến. Bạn cũng có thể truyền dữ liệu với các yêu cầu, nhưng vì phản hồi không hỗ trợ ngữ nghĩa read (), nên bạn sẽ phải xây dựng bộ điều hợp.
sirdodger 2/2/2016

@sirdodger Bạn đang đề cập đến urllib2 hay urllib?
CMCDragonkai

@CMCDragonkai Tôi đang đề cập đến câu trả lời urllib được chấp nhận. Nếu chi phí bộ nhớ là một mối quan tâm, tốt hơn là sử dụng câu trả lời yêu cầu này. (Tuy nhiên, như tôi đã đề cập, một giải pháp khác sử dụng các yêu cầu có thể đạt được hiệu quả tương tự.)
sirdodger


27

Sử dụng StringIOđể biến chuỗi đọc thành một đối tượng giống như tệp:

from StringIO import StringIO
import urllib

Image.open(StringIO(urllib.requests.urlopen(url).read()))

21

Đối với những người thực hiện một số xử lý bài sklearn / numpy (tức là Deep learning), bạn có thể bọc đối tượng PIL bằng np.array (). Điều này có thể giúp bạn không phải truy cập Google giống như tôi đã làm:

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

Con trăn 3

from urllib.request import urlopen
from PIL import Image

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

Jupyter Notebook và IPython

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

Không giống như các phương thức khác, phương thức này cũng hoạt động theo vòng lặp for!


12

Các coi là đề nghị cách để làm hình ảnh đầu vào / đầu ra những ngày này là sử dụng các gói chuyên dụng ImageIO . Dữ liệu hình ảnh có thể được đọc trực tiếp từ một URL với một dòng mã đơn giản:

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

Nhiều câu trả lời trên trang này có trước khi phát hành gói đó và do đó không đề cập đến nó. ImageIO khởi đầu là một thành phần của bộ công cụ Scikit-Image . Nó hỗ trợ một số định dạng khoa học trên đầu trang được cung cấp bởi thư viện xử lý hình ảnh phổ biến PILlow . Nó bao bọc tất cả trong một API sạch chỉ tập trung vào đầu vào / đầu ra hình ảnh. Trên thực tế, SciPy đã loại bỏ trình đọc / ghi hình ảnh của riêng mình để ủng hộ ImageIO .


3

chọn hình ảnh trong chrome, nhấp chuột phải vào nó, nhấp vào Copy image address, dán nó vào một strbiến ( my_url) để đọc hình ảnh:

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

mở nó ra;

from PIL import Image

img = Image.open('my_image.png')
img.show()
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.