Wednesday, 29th February 2012
Input and output
The first step for any image processing we want to do will be to load the image into a form we can manipulate. To load the image, we use the pygame.image.load() function, which creates a pygame.Surface object. You can manipulate the pixels of these surfaces (using Surface.get_at() and Surface.set_at()), but it's very slow. If we want to do a lot of processing, it faster to first convert the Surface to an array using the pygame.surfarray module. The function below opens a given file and returns an array of pixel intensities.
import pygame def getPixelArray(filename): try: image = pygame.image.load(filename) except pygame.error, message: print "Cannot load image:", filename raise SystemExit, message return pygame.surfarray.array3d(image)
The pixel array returned by this functions is three-dimensional, which may seem surprising given that the image is 2D. You can find the dimensions of your array like this:
pixels = getPixelArray('my_image.jpg') print pixels.shape
If your image is 640x400 image, then you will see the tuple, (640, 400, 3). The extra dimension of size three is because the colour of each pixel is stored as a tuple of three values. These value refer to the intensity of red, blue and green (RGB) respectively, on a scale of 0-255. For example, (255, 0, 0) is pure red, (0, 255, 0) is pure green, (0, 0, 255) is pure blue, (0, 0, 0) is black and (255, 255, 255) is white.
Once we've loaded our image and processed it, we will want to save it. Below is a function that converts a pixel array to saved image using pygame.image.save(). The type of file created by this function depends on the extension of the filename. It can save images as jpg, bmp, png or tga.
def saveSurface(pixels, filename): try: surf = pygame.surfarray.make_surface(pixels) except IndexError: (width, height, colours) = pixels.shape surf = pygame.display.set_mode((width, height)) pygame.surfarray.blit_array(surf, pixels) pygame.image.save(surf, filename)
Normally the first line of the try statement and the save() call are sufficient, but recently I've been having some issues. The code in the except block gets around the problem by first creating a pygame screen and blitting the image to it before saving the screen.
Now we have some functions to convert images to and from arrays. In the next tutorials we will look at how to process arrays in interesting ways.