Using Google AppEngine and the Pure Python PNGCanvas
For anyone who is investigating using Google’s AppEngine at the moment, would be well aware that whilst it is pretty amazing (as I indicated in a previous post) it does have it’s limitations.
One limitation I came across was in regards to the implementation of the Python Imaging Library within the engine. You can do resizing, cropping, flipping, etc of images, and whilst that is useful it really didn’t meet the needs I had for ConceptBuzz. So I had to look for an alternative, and one that used only pure python in it’s implementation.
To my rescue, came the excellent Pure Python PNG Canvas which enables some more advanced manipulation of PNG images using only pure python code. This code, although, has some limitations of it’s own:
- The library can load only 8bit PNG images of PNG ColorType 2 (which means basically RGB pallette – not indexed, with no alpha channel).
- PNG Canvas does struggle to load with some image files (mine fell over when attempting to load a 300×150 image)
Converting PNGs to a usable format
I use Inkscape for my vector graphic editing (really happy with it too), but it does not generate images in the correct format (all PNG images generated from inkscape contain an alpha channel, which is PNG colortype 6). Converting the image to the appropriate format is very simple though if you have access to ImageMagick:
convert image1.png -alpha deactivate image2.pngThe key in the above command is the “-alpha deactivate” command, which tells ImageMagick to strip the alpha channel from the PNG, leaving the PNG in colortype 2 format. It’s easy when you know how, but this took a couple of hours of digging to find a tool to do what I needed to.
Disabling PNG Canvas CRC checking
In the “chunks” method of the PNGCanvas class, I commented out the lines which perform the CRC checking (obviously taking my life into my own hands). For me this caused no noticable problems, and will investigate a proper solution when more time presents itself. After my hack, this is what the chunks method looks like:
243 244 245 246 247 248 249 250 251 252 253 254 255 256 | def chunks(self,f): while 1: try: length = struct.unpack("!I",f.read(4))[0] tag = f.read(4) data = f.read(length) crc = struct.unpack("!i",f.read(4))[0] except: return # 21/03/2009 - looks to be a problem with the CRC calculation #if zlib.crc32(tag + data) != crc: # raise IOError yield [tag,data] |
After all of this was completed, I was able to load, manipulate and display my PNG image using the PNG Canvas in Google’s appengine. Took a little bit of work, but certainly less than writing my own native python to manipulate PNGs so my sincerest thanks goes to Rui Carmo for making his code available.


Hi there! Glad my code was useful. I’ll look into the CRC stuff, but AFAIK it maps directly to the local zlib library…
As to alpha, I think I can eventually take a decent stab at it… I looked at manipulating tRNS but didn’t need it at the time.
Mate, that would be awesome – really appreciate anything you can do. Thanks again for the code.