【转】Python中使用PIL的Image函数出错,巧用StringIO解决文件写入权限问题

问题】

已经实现了,将返回的jpg数据保存为jpg文件,然后用PIL的Image.open打开,并调用show显示:

1
2
3
4
5
6
7
8
9
10
11
12
13
respHtml = crifanLib.getUrlRespHtml(captchaUrl);
# captchaDir = "captcha";
# #captchaPicFile = "returned_captcha.jpg";
# captchaPicFile = datetime.now().strftime('%Y%m%d_%H%M%S') + "_captcha.jpg";
# saveToFile = captchaDir + "/" + captchaPicFile;
# crifanLib.saveBinDataToFile(respHtml, saveToFile);
# print "save verify code pic OK, saveToFile=",saveToFile;
# openedImg = Image.open(saveToFile);
# print "openedImg=",openedImg;
# openedImg.show();

而此处,后来看PIL官网的解释中,发现有个frombuffer和fromstring,所以想要用这些函数,实现不需要保存所获得的jpg数据,而直接将此作为图像数据而打开,免去在本地建立多余的jpg文件的过程。

然后用下面的代码:

1
2
3
4
jpgData = respHtml;
newImg = Image.new("RGB", (60,24));
img = newImg.fromstring(jpgData);
img.show();

出错:

1
2
3
  File "xxxPython27libsite-packagesPILImage.py", line 594,in fromstring
    raise ValueError("not enough image data")
ValueError: not enough image data

【解决过程】

1.折腾了半天,试了各种的Image的或im的frombuffer或fromstring,结果都无法实现直接将jpg数据对应的图片显示出来。

2.参考:PIL ValueError: not enough image data?,看到其解释:

The data returned by image is the image itself not the RAW RGB data, hence you don’t need to load it as raw data, instead either just save that data to file and it will be a valid image or use PIL to open it

才想起来,的确是,此处所获得的jpg数据,其实本身是jpg文件了,包括了图片的原始(jpg压缩后的)数据和(jpg)文件头,因此,此时使用frombuffer或fromstring,那肯定是无法正常解析的。因为frombuffer或fromstring所需要的数据,是纯的图像数据,而不能有多余的各种格式的文件头的数据的。

所以,参考其代码,写出了如下代码:

1
2
3
4
from PIL import Image;
import StringIO;
img = Image.open(StringIO.StringIO(respHtml))
img.show();

然后就可以正常显示出图片了。

 

【总结】

1.对于图形图像处理,还是要概念清楚,才能准确发现并解决问题的。

此处就是对于原始图像数据,和jpg文件数据,没有太注意,概念不是很清晰,导致没有正确使用函数。

2.对于image.open来说,打开的是一个文件,而此处可以使用StringIO来作为参数,所以应该是可以将StringIO获得的返回值,作为一个类似文件的东西。以后遇到类似的和文件相关的问题,也可以尝试尝试StringIO。

 

提示:

如果出现显示不了图片,可参考:

【已解决】Python中通过Image的open之后,去show结果打不开bmp图片,无法正常显示图片

 

本文转自:http://www.crifan.com/python_image_valueerror_not_enough_image_data/