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

Dan*_*inn 159 python python-imaging-library

当我们处理本地文件时,我正在尝试做的事情相当简单,但是当我尝试使用远程URL执行此操作时会出现问题.

基本上,我正在尝试从URL中提取的文件中创建PIL图像对象.当然,我总是可以获取URL并将其存储在临时文件中,然后将其打开到图像对象中,但这样效率非常低.

这就是我所拥有的:

Image.open(urlopen(url))
Run Code Online (Sandbox Code Playgroud)

它散开了抱怨,这seek()是不可用的,所以我试过这个:

Image.open(urlopen(url).read())
Run Code Online (Sandbox Code Playgroud)

但这也不起作用.有没有更好的方法来做到这一点,或者写一个临时文件是可接受的做这种事情的方式?

And*_*ull 234

在Python3中,StringIO和cStringIO模块已经消失.

在Python3中你应该使用:

from PIL import Image
import requests
from io import BytesIO

response = requests.get(url)
img = Image.open(BytesIO(response.content))
Run Code Online (Sandbox Code Playgroud)

  • 自 PIL >= 2.8.0 起,不再需要手动包装 BytesIO。只需使用“Image.open(response.raw)”即可。PIL 现在会自动检查这一点,并在幕后进行 BytesIO 包装。来自:https://pillow.readthedocs.io/en/3.0.x/releasenotes/2.8.0.html (13认同)
  • 有点烦人,需要 3 个库... Pillow 应该添加这个功能! (2认同)

Fáb*_*niz 165

你可以尝试使用StringIO

import urllib, cStringIO

file = cStringIO.StringIO(urllib.urlopen(URL).read())
img = Image.open(file)
Run Code Online (Sandbox Code Playgroud)

  • 在python 3中,它将来自urllib.request import urlopen和io.io.BytesIO而不是StringIO (17认同)
  • 帮助,IOError:无法识别图像文件 <_io.BytesIO 对象在 0x7fb91b6a29b0> 我的网址是:...model=product.template&id=16&field=image_medium (2认同)

Sau*_*rav 55

我使用请求库.它看起来更强大.

from PIL import Image
import requests
from StringIO import StringIO

response = requests.get(url)
img = Image.open(StringIO(response.content))
Run Code Online (Sandbox Code Playgroud)

  • 由于某种原因,urllib不适用于某些URL,但请求在失败的地方有效 (3认同)
  • 请注意,请求会将整个响应加载到内存中,然后PIL会将整个内容再次作为映像加载,因此您有两个完整的副本驻留在内存中.使用urllib方法的上一个答案会对数据进行流式传输,因此您只能使用一个副本加上流缓冲区大小.您也可以使用请求流式传输数据,但由于响应不支持read()语义,因此您必须构建适配器. (3认同)

Gio*_*tto 38

对于那些使用Pillow的人,从版本2.8.0开始,您可以:

from PIL import Image
import urllib2

im = Image.open(urllib2.urlopen(url))
Run Code Online (Sandbox Code Playgroud)

或者如果您使用requests:

from PIL import Image
import requests

im = Image.open(requests.get(url, stream=True).raw)
Run Code Online (Sandbox Code Playgroud)

参考文献:

  • 我认为 urllib2 适用于 Python2,它已经过时了。对于Python 3,它是 urllib.requests: `urllib.request.urlopen(url).read()` (3认同)
  • 正如@wordsforthewise 所提到的,urllib 已经过时了。我使用了第二个选项,因为我在代码中无论如何都使用了“请求”并且它有效,所以投票。是否应该删除解决方案的 urllib 部分,以便读者不会花时间尝试第一种方法,只是意识到它不起作用,然后转向下一种方法? (2认同)

Dan*_* D. 27

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

from StringIO import StringIO
import urllib

Image.open(StringIO(urllib.requests.urlopen(url).read()))
Run Code Online (Sandbox Code Playgroud)


小智 21

对于那些做一些sklearn/numpy后期处理(即深度学习)的人,你可以用np.array()包装PIL对象.这可能会让您免于像我一样使用谷歌:

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)))
Run Code Online (Sandbox Code Playgroud)


ano*_*non 18

现在可以说推荐的图像输入/输出方法是使用专用包ImageIO。只需一行简单的代码,就可以直接从 URL 读取图像数据:

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

此页面上的许多答案早于该软件包的发布,因此没有提及它。ImageIO 最初是作为Scikit-Image工具包的组件。除了流行的图像处理库PILlow提供的格式之外,它还支持多种科学格式。它将所有内容都包装在一个干净的 API 中,该 API 仅专注于图像输入/输出。事实上,SciPy删除了自己的图像读取器/写入器,取而代之的是 ImageIO

  • 正如答案所解释的,这*是* skimage (Scikit-Image) 方法。它和你的互联网连接一样慢。 (2认同)

Mil*_*uss 13

Python 3

from urllib.request import urlopen
from PIL import Image

img = Image.open(urlopen(url))
img
Run Code Online (Sandbox Code Playgroud)

Jupyter Notebook和IPython

import IPython
url = 'https://newevolutiondesigns.com/images/freebies/colorful-background-14.jpg'
IPython.display.Image(url, width = 250)
Run Code Online (Sandbox Code Playgroud)

与其他方法不同,此方法还可以在for循环中使用!


Ham*_*eza 5

在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
Run Code Online (Sandbox Code Playgroud)

打开它;

from PIL import Image

img = Image.open('my_image.png')
img.show()
Run Code Online (Sandbox Code Playgroud)