Як я читаю дані зображення з URL-адреси в Python?


182

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

В основному я намагаюся створити об’єкт зображення PIL з файлу, витягнутого з URL-адреси. Звичайно, я завжди міг просто отримати URL-адресу та зберегти її у тимчасовому файлі, а потім відкрити її в об’єкт зображення, але це дуже неефективно.

Ось що я маю:

Image.open(urlopen(url))

Він спалахує, скаржившись, що seek()його немає, тож я спробував це:

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

Але і це не спрацювало. Чи є кращий спосіб це зробити, або записується у тимчасовий файл прийнятим способом робити подібні речі?


Відповіді:


281

У Python3 модулі StringIO та cStringIO вже відсутні.

У Python3 слід використовувати:

from PIL import Image
import requests
from io import BytesIO

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

Як повернути зображення з answer.content?
Amresh Giri

requestsпакет викидає 503 код статусу під час отримання зображення з URL-адреси. Натомість мені довелося вдатися, http.clientщоб отримати зображення.
Manishankar Singh

Коли я спробую це, я отримую: AttributeError: модуль 'request' не має атрибута 'get'.
apiljic

2
Ручне обгортання в BytesIO більше не потрібно, оскільки PIL> = 2.8.0. Просто використовуйте Image.open(response.raw). PIL автоматично перевіряє це зараз і чи завершує BytesIO під кришкою. Від: pillow.readthedocs.io/en/3.0.x/releasenotes/2.8.0.html
Vinícius M

ДЯКУЮ ВАМУ, ОП.
Шарль Шериф

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
ДОПОМОГА, 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))

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

Пітон 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!


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

виберіть зображення в хромі, клацніть правою кнопкою миші, натисніть 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()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.