如何在PIL中从互联网上打开图像?

问题描述 投票:23回答:6

我想在互联网上找到图像的尺寸。我试过用

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

正如在this answer中所建议的那样,但是我收到了错误消息

addinfourl instance has no attribute 'seek'

我检查了urllib2.urlopen(url)返回的对象似乎没有根据dir的搜索方法。

那么,我需要做些什么才能将图像从Internet加载到PIL中?

python python-imaging-library urllib2
6个回答
34
投票

您可以考虑将io.BytesIO用于forward compatibility。 Python 3中不存在StringIO和cStringIO模块。

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)

8
投票

使用相同的示例,只需使用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

7
投票

使用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

6
投票

这个pull-request增加了对Pillow(友好的PIL fork)原生流处理的支持,应该可以从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)

由于mentioned by mjpieters on the PR请求不会自动解码gzip响应,因此如果您下载的图像因任何原因而被进一步压缩,则必须在访问decode_content=True之前在响应对象上设置.raw

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

2
投票

urllib documentation提到urlopen返回的物体不支持seek操作。

该模块提供了一个高级接口,用于通过万维网获取数据。特别是,urlopen()函数类似于内置函数open(),但接受统一资源定位符(URL)而不是文件名。某些限制适用 - 它只能打开用于阅读的URL,并且不提供任何搜索操作。

但是,PIL.open函数明确要求它。

打开

Image.open(infile)=>图像

Image.open(infile,mode)=>图像

打开并标识给定的图像文件。这是一个懒惰的操作;在您尝试处理数据之前,不会从文件中读取实际图像数据(调用load方法强制加载)。如果给出mode参数,则它必须是“r”。

您可以使用字符串(表示文件名)或文件对象。在后一种情况下,文件对象必须实现read,seek和tell方法,并以二进制模式打开。

尝试使用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

-2
投票

这个答案是在4年前,但它仍然在谷歌的顶部。在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')
© www.soinside.com 2019 - 2024. All rights reserved.