从URL读取图像并将其保存在内存中

时间:2018-05-04 11:12:29

标签: python python-requests python-imaging-library

我正在使用Python并请求库。我只是想将一个图像下载到一个numpy数组,例如有多个问题,你可以找到不同的组合(使用opencv,PIL,requests,urllib ......)

它们都不适合我的情况。我尝试下载图像时基本上收到此错误:

:\>cdb classy.exe
Microsoft (R) Windows Debugger Version 10.0.16299.15 X86

0:000> bu classy!CalcArea ".if(((@@c++(rect->width))==0n40)){ .echo \"hit\" } .else{gc}"

0:000> bl
 0 e 00841100     0001 (0001)  0:**** 
classy!CalcArea ".if(  ((@@c++(rect->width))==0n40)  ) { .echo \"hit\" } .else {gc}"

0:000> g

Area for Rect(10,10) = 100
Area for Rect(15,20) = 300
Area for Rect(20,30) = 600
Area for Rect(25,40) = 1000
Area for Rect(30,50) = 1500
Area for Rect(35,60) = 2100
hit <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
eax=00000028 ebx=7ffdf000 ecx=002dff08 edx=00000046 esi=008c9bf0 edi=000d8b28
eip=00841100 esp=002dfef8 ebp=002dff18 iopl=0         nv up ei ng nz na pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000287
classy!CalcArea:
00841100 55              push    ebp


0:000> ?? rect
class Rectangle * 0x002dff08
   +0x000 width            : 0n40  <<<<<<<<<<<<<<<
   +0x004 height           : 0n70
0:000>

我的代码的一个简单示例可以是:

cannot identify image file <_io.BytesIO object at 0x7f6a9734da98>

这让我疯狂的主要原因是,如果我将图像下载到文件(使用urllib),整个过程运行没有任何问题!

import requests
from PIL import Image

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

我可以做错什么?

编辑:

我的错误最终与URL形成有关,而与请求无关  或PIL库。如果URL正确,我之前的代码示例应该可以正常工作。

1 个答案:

答案 0 :(得分:3)

我认为您在使用requests.raw对象中的数据之前将其保存在Image中,但请求响应原始对象不可查找,您只能从中读取一次:

>>> response.raw.seekable()
False

首先打开就可以了:

>>> response.raw.tell()
0
>>> image = Image.open(response.raw)

第二次打开抛出错误(流位置已经在文件末尾):

>>> response.raw.tell()
695  # this file length https://docs.python.org/3/_static/py.png

>>> image = Image.open(response.raw)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/PIL/Image.py", line 2295, in open
    % (filename if filename else fp))
OSError: cannot identify image file <_io.BytesIO object at 0x7f11850074c0>

如果你想多次使用它们,你应该在类似文件的对象(或文件)中保存来自请求响应的数据

import io
image_data = io.BytesIO(response.raw.read())

现在,您可以根据需要多次读取图像流并进行回放:

>>> image_data.seekable()
True

image = Image.open(image_data)
image1 = Image.open(image_data)