Подтвердить что ты не робот

Как открыть изображение из Интернета в PIL?

Я хотел бы найти размеры изображения в Интернете. Я попытался использовать

from PIL import Image
import urllib2 as urllib
fd = urllib.urlopen("http://a/b/c")
im = Image.open(fd)
im.size

как было предложено в этом ответе, но я получаю сообщение об ошибке

addinfourl instance has no attribute 'seek'

Я проверил, и объекты, возвращенные urllib2.urlopen(url), похоже, не имеют метода поиска в соответствии с dir.

Итак, что мне нужно сделать, чтобы иметь возможность загружать изображение из Интернета в PIL?

4b9b3361

Ответ 1

Вы можете использовать io.BytesIO для передовой совместимости.
Модули StringIO и cStringIO не существуют в Python 3.

from PIL import Image
import urllib2 as urllib
import io

fd = urllib.urlopen("http://a/b/c")
image_file = io.BytesIO(fd.read())
im = Image.open(image_file)

Ответ 2

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

from PIL import Image
import urllib2 as urllib
from StringIO import StringIO

fd = urllib.urlopen("http://a/b/c")
im = Image.open(StringIO(fd.read()))
im.size

Ответ 3

Использование Python requests:

from PIL import Image
from StringIO import StringIO
import requests

r = requests.get("http://a/b/c")
im = Image.open(StringIO(r.content))
im.size

Ответ 4

Этот pull-request добавляет поддержку потоковой обработки, родной для Pillow (дружественная вилка PIL), и должен быть доступен с версии 2.8.0, Это позволяет упростить открытие удаленных файлов с помощью urllib:

from PIL import Image
import urllib2
Image.open(urllib2.urlopen(url))

... или используя requests:

from PIL import Image
import requests
Image.open(requests.get(url, stream=True).raw)

Как упомянутый mjpieters в PR, не автоматически декодирует ответы gzip, поэтому, если вы загружаете изображения, которые были сжатый по какой-либо причине, вы должны установить decode_content=True в объекте ответа до доступа к .raw.

response = requests.get(url, stream=True)
response.raw.decode_content = True
image = Image.open(response.raw)

Ответ 5

urllib documentation упоминает, что объект, возвращаемый urlopen, не поддерживает операцию seek.

Этот модуль обеспечивает высокоуровневый интерфейс для извлечения данных через Всемирная паутина. В частности, функция urlopen() аналогична к встроенной функции open(), но принимает универсальный ресурс Локаторы (URL) вместо имен файлов. Применяются некоторые ограничения - это может только открытые URL-адреса для чтения, а операции поиска не доступны.

Однако функция PIL.open явно требует этого.

Открыть

Изображение .open(infile) = > изображение

Изображение .open(infile, mode) = > изображение

Открывает и идентифицирует данный файл изображения. Это ленивая операция; фактические данные изображения не считываются из файла, пока вы не попытаетесь обрабатывать данные (вызов метода загрузки для принудительной загрузки). Если режим аргумент, он должен быть "r".

Вы можете использовать либо строку (представляющую имя файла), либо файл объект. В последнем случае файловый объект должен реализовать чтение, поиск, и скажите методы и откроются в двоичном режиме.

Попробуйте использовать модуль cStringIO, который преобразует строку в файл-подобный объект.

from PIL import Image
import urllib2 as urllib
import cStringIO

fd = urllib.urlopen("http://a/b/c")
image_file = cStringIO.StringIO(fd.read())
im = Image.open(image_file)
im.size

Ответ 6

Этот ответ 4 года назад, но он все еще на вершине в Google.In Python3, мы имеем простое решение.

from urllib.request import urlopen
img =Image.open(urlopen('http://dl.iplaypython.com/images/banner336x280.jpg'))
new_img =img.resize((300,500),Image.ANTIALIAS)
new_img.save('url.jpg','jpeg')