pixel access in pyGame

How to get and set the colour of pixels in pyGame?

(you’ll find code snippets and examples further below)

Images in pyGame are called “Surfaces”.
Surfaces are essentially objects which have image data, and other functions. The image data can be accessed in different ways, some easier, some faster. Typically one makes an object which allows direct pixel access, to the pixels in the Surface. There are two principal ways/objects for accessing pixels, pixelArrays and surfaceArrays. (There’s direct pixel access from the Surface object, but it’s the slowest, particularly for coplicated operations).

SurfaceArrays
( http://www.pygame.org/docs/ref/surfarray.html )
Are the fastest means of accessing pixels in a Surface.
They’re essentially wrappers for the Surface, allowing one to access pixels as if the image was a numpy (numericalPython) object. ( http://numpy.scipy.org/ ).
Numpy, and its cousin Scipy (scientificPython), providing more analytical image operations.

PixelArrays
One can also create a pixelArray object for pixel access
( http://www.pygame.org/docs/ref/pixelarray.html )
But they’re said not to be as quick as surfaceArrays.
Below are code examples of getting an image* from a webcam,
and yet further below, examples of pixel access with the pixelArray / surfaceArray objects.
* a “Surface” in pyGame parlance.

_______________________________________


#   how to initialise a pyGame window
#   and take an image (ie. a “surface” in pyGame speak)
#   this is a kind of prerequisite for the other code examples

# import the relevant libraries
import pygame
import pygame.camera
from pygame.locals import *
#  initialise the display window
screen = pygame.display.set_mode([800,420])

# intialise pyGame
pygame.init()
# initialise the camera
pygame.camera.init()
#  set up a camera object
cam = pygame.camera.Camera(“/dev/video0”,(640,480))
#  start the camera
cam.start()
#  fetch the camera image
image = cam.get_image()
#  blank out the screen – if you feel like it
screen.fill([0,0,0])
#  copy the camera image to the screen
screen.blit( image, ( 100, 0 ) )
#  update the screen to show the latest screen image
pygame.display.update()
pygame.display.flip()

_______________________________________________________________

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#   surfaceArray pixel access

# ( good numpy operations possible on images using this)
# pygame surfaceArray documenation:
http://www.pygame.org/docs/ref/surfarray.html
# numpy/scipy documentation:
http://numpy.scipy.org/

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#__________________________________________________________

#  surfaceArray
#     how to fetch colour values?

#  make a surfaceArray wrapper object to the image (i.e. ‘Surface’)
surf3d = pygame.surfarray.pixels3d( image )
#     read the pixel at coordinate (100,100)
# the result is a numpy array in the form of “[red][green][blue]”
surf3d[100][100]

#  __________________________________________________________

#   surfaceArray
#       change pixel values

# create a wrapper for accessing the image pixels
#   as a numpy array
surf3d = pygame.surfarray.pixels3d( image )
#     set the pixel at (100,100) to white
surf3d[100][100] = [255,255,255]
#     alas, it seems one needs to delete the surfaceArray pixels reference
# to be able to draw the surface (i.e. “image”) it refers to
del surf3d
#       finally, blit and update
screen.blit( image, (100,0))
pygame.display.flip()

#  __________________________________________________

#  surfaceArray
#       quick test of drawing a line with surfarray and numpy

#  create a wrapper to for accessing the image data
surf3d = pygame.surfarray.pixels3d( image )

#  make a loop going through the horizontal pixels
for xpx in xrange( len(surf3d) ):

#  create a reference to the surface used
surf3d = pygame.surfarray.pixels3d( image )
#  select a moving pixel… towards the right
#  set the pixel to white
surf3d[ xpx][240] = [255, 255, 255]
#  delete the surface reference
#    so the surface it references (“image”) can be blitted
del surf3d
#     draw the surface referred to
screen.blit( image, (100,0))
#       draw the screen
pygame.display.flip()

#  _____________________________________________________

#  surfaceArray
#    as above but with spaced out lines

#  create a wrapper to for accessing the image data
surf3d = pygame.surfarray.pixels3d( image )
for xpx in xrange( len(surf3d) ):

#  create a reference to the surface used
surf3d = pygame.surfarray.pixels3d( image )
#  select a moving pixel… towards the right
#  set the pixel to white
surf3d[ xpx][100:300:6] = [0, 0, 255]    #   << modified line
#  delete the surface reference
#    so the surface it references (“image”) can be blitted
del surf3d
#     draw the surface referred to
screen.blit( image, (100,0))
#       draw the screen
pygame.display.flip()

#  _____________________________________________________

#  surfaceArray
#       change the brightness of a whole image

#  get surfaceArray/numpy pixel access object
surf3d = pygame.surfarray.pixels3d( image )
#  increase the values of the pixels, by 50 units
surf3d += 50
#  delete the surface reference
#    so the surface it references (“image”) can be blitted
del surf3d
#     draw the surface referred to
screen.blit( image, (100,0))
#       draw the screen
pygame.display.flip()

_______________________________________________________________

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#   pixelArray pixel access
# ( slower than surfaceArray )
# pygame documentation:
http://www.pygame.org/docs/ref/pixelarray.html

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#__________________________________________________________

# pixelarray
# colour checking

#   use the “unmap_rgb” function of the Surface you’re using
#   to fetch the RGBA values of a given pixel
# i.e the format is SurfaceName.unmap_rgb( pixelarrayObject[xcoord][ycoord] )
#  – accessing pixels at coordinate (0,0)
image.unmap_rgb( pxarray[0][0] )

#  __________________________________________________________

#  pixelarray pixel
#    change one pixel

#  create a pixelAccess object for the image (“surface” in pyGame speak)
pxarray = pygame.PixelArray( image )
#  set the pixel to white, using the (red, green, blue) format
#  at coordinate (100,100)
pxarray[100][100] = (255, 255, 255)
#  to use the resulting image, you need to delte the reference object
del pxarray
#  print the resulting image to the screen
screen.blit( image, (100,0))
#  update the screen, for the changes to become visible
pygame.display.flip()

#  __________________________________________________________

#  pixelarray pixel change
#    for every other line

#  create a pixelAccess object for the image (“surface” in pyGame speak)
pxarray = pygame.PixelArray( image )
#  change the colour of every other column line
pxarray[::2,:] = (0, 255, 255)
#  to use the resulting image, you need to delte the reference object
del pxarray
#  print the resulting image to the screen
screen.blit( image, (100,0))
#  update the screen, for the changes to become visible
pygame.display.flip()

#  __________________________________________________________

#  pixelarray pixel changing
#    for rectangular regions

#  create a pixelAccess object for the image (“surface” in pyGame speak)

pxarray = pygame.PixelArray( image )
#  create a subpixel region
newarray = pxarray[20:40,30:50]
#  colour the whole subpixel region with a given colour
newarray[:] = (255, 255, 255)
#   copy the subpixel region back to the original array
pxarray[20:40,30:50] = newarray
#  to use the resulting image, you need to delte the reference objects
del newarray, pxarray
#  print the resulting image to the screen
screen.blit( image, (100,0))
#  update the screen, for the changes to become visible
pygame.display.flip()

#  __________________________________________________________
#  __________________________________________________________
This entry was posted in Uncategorized. Bookmark the permalink.