Saturday, June 06, 2009

Dynamic Web Displayed Images: Python and PHP

Ripped from: devrand


Dynamic images on the web can be a tad tricky. The general procedure is to write out an image header as opposed to the standard html one. Following that is the raw binary for the image. Below are examples of doing this in Python and PHP.

Python using the PIL library

from PIL import Image, ImageDraw

import sys
im ="P", (200, 200))

draw = ImageDraw.Draw(im)
draw.rectangle((0, 0) + im.size, fill="blue")

# Any manipulation of the image
print "Content-Type: image/png\r\n", "PNG")

Python Debugging

This is incredibly fragile. I originally tried a solution I found on a mailing list and had to make tons of modification to get it running.

  • Wrong content type: The image/type must match with the output

  • Not including the python executable path: If the top line is not setup correctly(#!/path/to/python) or is missing, it may run correctly in the command line but fail on the web

  • Wrong newline setup: I found I had to have exactly the number of newlines I did, most people show an additional "\r\n", but this broke mine

  • sys.stdout.write: This didn't work for me. It shows up fine on the command line, but doesn't work on the Apache webserver I was using. Use print instead.

  • PIL not installed: The machine it is running on needs the Python Imaging Library

The bad thing about most of these bugs is that they look just fine on the command line, and only fail when run on a web server.

PHP using the GD library

$my_img = imagecreate( 200, 200 );
imagecolorallocate( $my_img, 0, 0, 255 );
# Any manipulations of the image
header( "Content-type: image/png" );
imagepng( $my_img );
imagedestroy( $my_img );

PHP Debugging

The only problem I've had with this is GD not being installed properly. Other than that if you can run PHP scripts you shouldn't have issues.


This is a usefull technique but was very hard to find relevant information online, especially for Python. This is a much better solution than saving off pictures and then pushing that to the user like I've seen alot of online.