PIL 值错误:图像数据不足?
我在尝试从一个网址获取图片,并把响应中的字符串转换成Image
时,遇到了上面的错误信息。
from google.appengine.api import urlfetch
def fetch_img(url):
try:
result = urlfetch.fetch(url=url)
if result.status_code == 200:
return result.content
except Exception, e:
logging.error(e)
url = "http://maps.googleapis.com/maps/api/staticmap?center=Narita+International+Airport,Narita,Chiba+Prefecture,+Japan&zoom=18&size=512x512&maptype=roadmap&markers=color:blue|label:S|40.702147,-74.015794&markers=color:green|label:G|40.711614,-74.012318&markers=color:red|color:red|label:C|40.718217,-73.998284&sensor=false"
img = fetch_img(url)
# As the URL above tells, its size is 512x512
img = Image.fromstring('RGBA', (512, 512), img)
根据PIL的说法,大小选项应该是一个像素的元组。我是这样指定的。有人能告诉我我哪里理解错了吗?
4 个回答
0
请注意,PIL(Python Imaging Library)在App Engine上是不支持的。它只是在开发阶段用作图像API的一个占位符。
你可以这样做:
from google.appengine.api import urlfetch
from google.appengine.api import images
class MainHandler(webapp.RequestHandler):
def get(self):
url = "http://maps.googleapis.com/maps/api/staticmap?center=Narita+International+Airport,Narita,Chiba+Prefecture,+Japan&zoom=18&size=512x512&maptype=roadmap&markers=color:blue|label:S|40.702147,-74.015794&markers=color:green|label:G|40.711614,-74.012318&markers=color:red|color:red|label:C|40.718217,-73.998284&sensor=false"
img = images.Image(urlfetch.fetch(url).content)
5
fromstring
是用来加载原始图像数据的。你在字符串 img
中拥有的是以 PNG 格式编码的图像。你想要做的是创建一个 StringIO 对象,然后让 PIL 从这个对象中读取数据。可以这样做:
>>> from StringIO import StringIO
>>> im = Image.open(StringIO(img))
>>> im
<PngImagePlugin.PngImageFile image mode=P size=512x512 at 0xC585A8>
7
这个图片返回的数据就是图片本身,而不是原始的RGB数据。所以你不需要把它当作原始数据来加载。你可以直接把这些数据保存成文件,这样就会得到一个有效的图片,或者使用PIL库来打开它。例如,我已经把你的代码改成不使用appengine的API,这样任何正常安装了Python的人都可以运行这个例子。
from urllib2 import urlopen
import Image
import sys
import StringIO
url = "http://maps.googleapis.com/maps/api/staticmap?center=Narita+International+Airport,Narita,Chiba+Prefecture,+Japan&zoom=18&size=512x512&maptype=roadmap&markers=color:blue|label:S|40.702147,-74.015794&markers=color:green|label:G|40.711614,-74.012318&markers=color:red|color:red|label:C|40.718217,-73.998284&sensor=false"
result = urlopen(url=url)
if result.getcode() != 200:
print "errrrrr"
sys.exit(1)
imgdata = result.read()
# As the URL above tells, its size is 512x512
img = Image.open(StringIO.StringIO(imgdata))
print img.size
输出:
(512, 512)