It is fun and sometimes useful to have random images display on your website. Although there are a lot of examples in PHP [1] [2] and Perl [3] [4] for displaying random images, there are not very many for Python. With only a little code and some help from Python's builtin libraries writing a random image script can be done very easily.
Before we start programming let's set a few things up. First, I am using a set of 5 different images for this tutorial:
If you want to follow along, download them to a directory; or you can grab some images of your own that you would like to use. I'm including multiple file types (PNG, GIF, and JPEG) so our script will work with any kind of image file.
Second, we are going to use Python's built in CGI server for testing. To run the CGI server from the command line, enter:
python -c "import CGIHTTPServer;CGIHTTPServer.test()"
Or you can put that line into a file on your path or in your working folder and run the command (mine is called servecgi) from the directory any time you need to do some testing. To stop the server try Ctrl+C or Ctrl+Break. When testing scripts, they must be in a cgi-bin folder, otherwise they will be treated as readable instead of executable.
If you want to use CGI to display random or dynamic images it makes sense
to try something simpler, like displaying a static image.
When you request an image from a web server the server sends a response containing the appropriate headers
along with the contents of the file itself [5]. To display a static image we will try to duplicate this behavior.
We will try to output the 1.png file for this example. When Python is run
as a CGI script the output of the program is sent to the browser.
The appropriate header is sent by printing "Content-type: image/png\n". Once the browser recieves the
content-type header you can send the contents of the file. Because we are just reading in the file,
we should supply the second parameter to the file function, which is the mode. If you
are on Windows you need to use "rb" which opens the file in read-binary mode,
if you are on Linux then just use "r".
if __name__ == "__main__": print "Content-type: image/png\n" print file(r"c:\python\random_img\1.png", "rb").read()
Before we get to the random images we must first create a method to determine what kind of file we are sending to the viewer. If the correct content-type is not sent the browser will not know what it is looking at. The easiest way to to do this is to look at the file extension, and use that to lookup the content-type in a dictionary.
ext2conttype = {"jpg": "image/jpeg", "jpeg": "image/jpeg", "png": "image/png", "gif": "image/gif"} def content_type(filename): return ext2conttype[filename[filename.rfind(".")+1:].lower()] if __name__ == "__main__": print "Content-type: %s\n" % (content_type(r"c:\python\random_img\3.jpg")) print file(r"c:\python\random_img\3.jpg", "rb").read()
Now we are ready to pick random files. To list the contents of a directory you can use the listdir function from the os module. Randomly picking one object from a list is done by using the choice function from the random module.
from os import listdir from random import choice ext2conttype = {"jpg": "image/jpeg", "jpeg": "image/jpeg", "png": "image/png", "gif": "image/gif"} def content_type(filename): return ext2conttype[filename[filename.rfind(".")+1:].lower()] def isimage(filename): """true if the filename's extension is in the content-type lookup""" filename = filename.lower() return filename[filename.rfind(".")+1:] in ext2conttype def random_file(dir): """returns the filename of a randomly chosen image in dir""" images = [f for f in listdir(dir) if isimage(f)] return choice(images) if __name__ == "__main__": dir = "c:\\python\\random_img\\" r = random_file(dir) print "Content-type: %s\n" % (content_type(r)) print file(dir+r, "rb").read()
From here you could expand the script to use multiple directories, or randomly serve other kinds of files. We can also use the ideas from here to serve dynamic images.
To see how to serve dynamic images follow along to Part 2: Serving Dynamic Images with Python CGI.
[1]: http://www.alistapart.com/d/randomizer/rotate.txt [2]: http://photomatt.net/scripts/randomimage [3]: http://www.tizag.com/tools/randpic.php [4]: http://rossbeyer.net/software/random_gallery/ [5]: http://en.wikipedia.org/wiki/Web_server