Pil Valueerror: Not Enough Image Data?

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 = ""

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?

1

4 Answers

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 = ""
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)

fromstring is used for loading raw image data. What you have in the string img is an image encoded as PNG format. What you want to do is create a StringIO object and have PIL read from it. Like this:

>>> from StringIO import StringIO
>>> im = Image.open(StringIO(img))
>>> im
<PngImagePlugin.PngImageFile image mode=P size=512x512 at 0xC585A8>

Note that PIL is not supported on App Engine. It's only used in dev as a stub for the images API.

You can do something like this:

from google.appengine.api import urlfetch
from google.appengine.api import images

class MainHandler(webapp.RequestHandler):
  def get(self):
    url = ""
    img = images.Image(urlfetch.fetch(url).content)
1
response = requests.get(url)
img = Image.open(BytesIO(response.content))
img.show()

It work for my

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Marcus Vance
Author

Marcus Vance

Marcus Vance is a cybersecurity auditor and technology writer dedicated to educating the public about online safety, data privacy regulations, enterprise security, and emerging cyber threats.