27

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

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 中?

4

7 回答 7

43

您可以考虑使用io.BytesIO向兼容性
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)
于 2012-08-18T17:46:37.137 回答
12

使用 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
于 2014-08-17T15:53:23.547 回答
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
于 2012-08-18T17:47:35.717 回答
8

这个拉取请求增加了对 Pillow(友好的 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)

正如mjpieters 在 PR请求中提到的那样,它不会自动解码gzip响应,因此,如果您正在下载由于任何原因进一步压缩的图像,您必须decode_content=True在访问之前在响应对象上设置.raw.

response = requests.get(url, stream=True)
response.raw.decode_content = True
image = Image.open(response.raw)
于 2015-03-29T10:31:15.277 回答
2

urllib文档提到返回的对象不urlopen支持seek操作。

该模块提供了一个用于通过万维网获取数据的高级接口。特别是,urlopen() 函数类似于内置函数 open(),但接受通用资源定位器 (URL) 而不是文件名。有一些限制——它只能打开 URL 进行阅读,并且没有可用的查找操作。

但是,该PIL.open功能明确要求它。

打开

Image.open(infile) => 图像

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

打开并识别给定的图像文件。这是一个惰性操作;在您尝试处理数据(调用 load 方法强制加载)之前,不会从文件中读取实际的图像数据。如果给出了模式参数,它必须是“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
于 2012-08-18T17:37:23.557 回答
0

这个答案是 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')
于 2017-01-12T08:45:10.063 回答
0

使用请求库并以字节形式获取输出

import requests
import io

response = requests.get("https://i.imgur.com/ExdKOOz.png")
image_bytes = io.BytesIO(response.content)
于 2021-04-20T07:12:19.733 回答