Search code examples
pythongoogle-app-enginepython-imaging-library

PIL ValueError: not enough image data?


I'm getting an error with its message as above when I tried to fetch an image from a URL and converting the string in its response to Image within App Engine.

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)

According to PIL, size option is suppose to be a tuple of pixels. This I specified. Could anyone point out my misunderstanding?


Solution

  • 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 e.g. (I have converted your code not to use appengine api so that anybody with normal python installation can run the xample)

    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
    

    output:

    (512, 512)