Как мне прочитать данные изображения с URL в Python?

182

То, что я пытаюсь сделать, довольно просто, когда мы имеем дело с локальным файлом, но проблема возникает, когда я пытаюсь сделать это с помощью удаленного URL.

По сути, я пытаюсь создать объект изображения PIL из файла, извлеченного из URL. Конечно, я всегда мог просто извлечь URL-адрес и сохранить его во временном файле, а затем открыть его в объект изображения, но это кажется очень неэффективным.

Вот что у меня есть:

Image.open(urlopen(url))

Он жалуется, что seek()не доступен, поэтому я попробовал это:

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

Но это тоже не сработало. Есть ли лучший способ сделать это, или запись во временный файл является приемлемым способом сделать это?

Дэниел Куинн
источник

Ответы:

282

В Python3 модули StringIO и cStringIO исчезли.

В Python3 вы должны использовать:

from PIL import Image
import requests
from io import BytesIO

response = requests.get(url)
img = Image.open(BytesIO(response.content))
Андрес Кулл
источник
Как вернуть изображение из response.content?
Амреш Гири
requestsПакет генерирует 503 код состояния при получении изображения с URL. Вместо этого мне пришлось прибегнуть http.clientк получению изображения.
Манишанкар Сингх,
Когда я пытаюсь это сделать, я получаю: AttributeError: модуль «запросы» не имеет атрибута «получить».
Апрель
2
Ручная упаковка в BytesIO больше не требуется, поскольку PIL> = 2.8.0. Просто используйте Image.open(response.raw). Теперь PIL автоматически проверяет это и выполняет упаковку BytesIO под капотом. От: pillow.readthedocs.io/en/3.0.x/releasenotes/2.8.0.html
Виниций М
СПАСИБО, спасибо.
Шарл Шериф
166

Вы можете попробовать использовать StringIO

import urllib, cStringIO

file = cStringIO.StringIO(urllib.urlopen(URL).read())
img = Image.open(file)
Фабио Диниз
источник
Спасибо, просто хотел бы добавить, что тот же самый точный код будет работать с urllib2 (с Python2)
мягко
17
в Python 3 это будет из импорта urllib.request urlopen и io.io.BytesIO вместо StringIO
matyas
2
HELP, IOError: не удается идентифицировать файл изображения <_io.BytesIO объект в 0x7fb91b6a29b0> мой URL-адрес: ... model = product.template & id = 16 & field = image_medium
С. Дэлгэрцэцэг
56

Я использую библиотеку запросов. Кажется, это более надежно.

from PIL import Image
import requests
from StringIO import StringIO

response = requests.get(url)
img = Image.open(StringIO(response.content))
Saurav
источник
3
По некоторым причинам urllib не работал для некоторых URL, но запросы работали там, где это не удавалось
mirri66
Я не смог найти пакет PIL, но похоже, что подушка взяла на себя усилия PIL, и вы можете установить для python3 с pip3.4 install pillow.
разрушительный
3
Обратите внимание, что запросы загрузят весь ответ в память, а затем PIL снова загрузит все это как изображение, поэтому у вас в памяти будет две полные копии. Предыдущий ответ с использованием метода urllib выполняет потоковую передачу данных, поэтому в итоге получается только одна копия плюс размер буфера потоковой передачи. Вы также можете передавать данные с запросами, но поскольку ответ не поддерживает семантику read (), вам придется создать адаптер.
sirdodger
@sirdodger Вы имеете в виду urllib2 или urllib?
CMCDragonkai
@CMCDragonkai Я имел в виду принятый ответ urllib. Если проблема связана с нехваткой памяти, лучше использовать ответ на этот запрос. (Однако, как я уже говорил, другое решение, использующее запросы, могло бы достичь того же эффекта.)
sirdodger
42

Для тех из вас, кто использует подушку, начиная с версии 2.8.0, вы можете:

from PIL import Image
import urllib2

im = Image.open(urllib2.urlopen(url))

или если вы используете requests:

from PIL import Image
import requests

im = Image.open(requests.get(url, stream=True).raw)

Ссылки:

Джованни Каппеллотто
источник
27

Используйте, StringIOчтобы превратить прочитанную строку в подобный файлу объект:

from StringIO import StringIO
import urllib

Image.open(StringIO(urllib.requests.urlopen(url).read()))
Дэн Д.
источник
21

Для тех, кто делает некоторую пост-обработку sklearn / numpy (т.е. глубокое обучение), вы можете обернуть объект PIL с помощью np.array (). Это может избавить вас от необходимости заходить в Google, как я:

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 и IPython

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

В отличие от других методов, этот метод также работает в цикле for!

Miladiouss
источник
12

Возможно, рекомендуемый способ ввода / вывода изображения в эти дни - использовать специальный пакет ImageIO . Данные изображения могут быть прочитаны непосредственно с URL с помощью одной простой строки кода:

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

Многие ответы на этой странице предшествуют выпуску этого пакета и поэтому не упоминают его. ImageIO начинался как компонент набора инструментов Scikit-Image . Он поддерживает ряд научных форматов помимо тех, которые предоставляет популярная библиотека обработки изображений PILlow . Он оборачивает все это в чистый API исключительно для ввода / вывода изображения. Фактически, SciPy удалила свою собственную программу чтения / записи изображений в пользу ImageIO .

скоро
источник
3

выберите изображение в Chrome, щелкните правой кнопкой мыши на нем, нажмите Copy image address, вставьте его в strпеременную ( my_url), чтобы прочитать изображение:

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

Открой это;

from PIL import Image

img = Image.open('my_image.png')
img.show()
Shivid
источник