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

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

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

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

Image.open(urlopen(url))

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

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

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

Ответ 1

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

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

from PIL import Image
import requests
from io import BytesIO

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

Ответ 2

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

import urllib, cStringIO

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

Ответ 3

Я использую библиотеку запросов. Это кажется более надежным.

from PIL import Image
import requests
from StringIO import StringIO

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

Ответ 5

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

from StringIO import StringIO
import urllib

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

Ответ 6

Для тех, кто выполняет некоторую обработку сообщений 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)))

Ответ 7

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!

Ответ 8

выберите изображение в 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()

Ответ 9

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

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

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

Ответ 10

Результаты теста скорости для некоторых из вышеупомянутых методов (Python 3.6):

import timeit
setup = '''import numpy as np
import urllib
from PIL import Image
import requests
from io import BytesIO
from imageio import imread
url = 'YOUR_URL_HERE'
'''

a = '''Image.open(urllib.request.urlopen(url))
'''

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

c = '''Image.open(BytesIO(requests.get(url).content))
'''

d = '''imread(url)
'''

n = 500

times = [timeit.timeit(setup = setup, 
                    stmt = i, 
                    number = n) for i in [a, b, c, d]]

print([i/min(times) for i in times])

Результаты (как факторы самого быстрого метода):

print([i/min(times) for i in times])

# a, b, c, d
> [1.0, 1.0447410207419439, 1.0416206337627958, 1.8141586255592965]