如何从Python中的URL读取图像数据?


180

当我们处理本地文件时,我想做的事情很简单,但是当我尝试使用远程URL时,问题就来了。

基本上,我试图从URL提取的文件中创建一个PIL图像对象。当然,我总是可以仅获取URL并将其存储在临时文件中,然后将其打开到图像对象中,但这感觉效率很低。

这是我所拥有的:

Image.open(urlopen(url))

它抱怨seek()说不可用,所以我尝试了这个:

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

但这也不起作用。有没有更好的方法可以执行此操作,还是可以将这种方式写入临时文件?


Answers:


279

在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取回图像?
Amresh Giri

requests程序包从URL提取图像时会抛出503状态代码。相反,我不得不求助于http.client图像。
Manishankar Singh,

当我尝试这个时,我得到:AttributeError:模块'requests'没有属性'get'。
apiljic

2
由于PIL> = 2.8.0,因此不再需要手动包装在BytesIO中。只需使用Image.open(response.raw)。PIL现在会自动进行检查,并在后台进行BytesIO包装。来源:pillow.readthedocs.io/en/3.0.x/releasenotes/2.8.0.html
维尼修斯中号

谢谢YOUUUUUUUUUUUU,OP。
Sharl Sherif

166

你可以尝试使用StringIO

import urllib, cStringIO

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

谢谢,想补充一点,相同的确切代码将与urllib2(与Python2一起使用)
sofly 2014年

17
在python 3中它将是从urllib.request导入urlopen和io.io.BytesIO而不是StringIO
matyas

2
HELP,IO错误:无法识别<在0x7fb91b6a29b0 _io.BytesIO对象>图像文件我的网址是:...模型= product.template&ID = 16场= image_medium
С. Дэлгэрцэцэг18年

56

我使用请求库。它似乎更强大。

from PIL import Image
import requests
from StringIO import StringIO

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

3
由于某些原因,urllib不适用于某些URL,但是请求在失败的地方
起作用

我找不到PIL软件包,但看起来枕头已经接管了PIL的工作,您可以使用安装python3 pip3.4 install pillow
破坏性

3
请注意,请求会将整个响应加载到内存中,然后PIL将再次将整个响应作为图像加载,因此您在内存中有两个完整副本。上一个使用urllib方法的答案是流式传输数据,因此最终只能得到一个副本加上流式传输缓冲区的大小。您也可以将数据与请求一起流式传输,但是由于响应不支持read()语义,因此必须构建适配器。
sirdodger '16

@sirdodger您是指urllib2还是urllib?
CMCDragonkai '18年

@CMCDragonkai我指的是公认的urllib答案。如果需要考虑内存开销,则比使用此请求更好。(但是,就像我提到的那样,使用请求的不同解决方案可以达到相同的效果。)
sirdodger '18年


27

使用StringIO转读字符串转换为一个类文件对象:

from StringIO import StringIO
import urllib

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

21

对于进行某些sklearn / numpy后处理(即深度学习)的用户,可以使用np.array()包装PIL对象。这样可以避免您像我一样去过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循环中使用!


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()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.