Как открыть изображение из интернета в 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?

6 ответов


можно использовать 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)

используя тот же пример, просто используйте 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

Использование 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

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

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

...или используя запросы:

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

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

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

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

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

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

открыть

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

изображения.открыть (infile, mode) = > image

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

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

попробуйте использовать 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

этот ответ 4 года назад, но он все еще на вершине в Google.В 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')