We have now discussed the most basic control structures and can start using them in combination. In this lab, we work with images, which can be seen as two-dimensional collections of pixels. We work with such structures using a variety of combinations of sequence, selection and iteration, notably multidimensional iteration in which one loop is placed inside another.

Representing Images

An image is encoded as a two-dimensional grid of pixels. Each pixel is addressed using its x index and its y index, and represents its color using separate intensity values for red, green and blue.

Here, the image of Zim is 300 pixels wide and 482 pixels high. The background pixels of the image are all white (255, 255, 255), but the pixel at address (115, 32) is a shade of magenta (169, 66, 96).

Working with Images

We work with images by manipulating their pixels.

PImage zim;

void setup() {
  zim = loadImage("zim-large.jpg");
  size(zim.width, zim.height);
  noLoop();
}

void draw() {
  zim.set(250, 400, color(0,0,0));
  image(zim, 0, 0);
}

In this program, we load an image of Zim and set the pixel at address (250, 400) to black. This places a small black spec (a pixel!) in the lower right part of the image (address (250, 400)!). Note that the command zim.set(250, 400, color(0, 0, 0)) asks the zim image object to set its pixel at position (250, 400) to color (0, 0, 0); we’ll detail these basic commands below.

Using these commands, we can manipulate the image by visiting all the pixels and changing them in systematic ways. Iteration provides a concise way to program systematic operations on a large number of pixels (e.g., there are 144,600 pixels in the Zim image!).

color c;
PImage zim;

void setup() {
  zim = loadImage("zim-large.jpg");
  size(zim.width, zim.height);
  noLoop();
}

void draw() {
  for (int i = 0; i < width; i++) {
    for (int j = 0; j < height; j++) {
      c = zim.get(i, j);
      zim.set(i, j, color(red(c) + 100, 
                          green(c) + 100, 
                          blue(c) + 100));
    }
  }
  image(zim, 0, 0);
}

Pattern:

for (xInit; xLoopCond; xStepExpr)
  for (yInit; yLoopCond; yStepExpr)
    statement
  • Init - The outer initialization sets the index on the x axis; the inner initialization sets the index on the y-axis.
  • loopCond - The outer loop condition stops when the x index hits the width; the inner loop condition stops when the y index hits the height.
  • stepExpr - Both step expressions increment their respective indexes by 1 each time around.
  • statement - The statement or block is executed on each iteration for a particular set of x and y indexes.

This program uses a nested loop to access each of the pixels in turn. For each pixel, it gets the color value of the pixel and sets a new color value that has larger RGB values. Here are the key image/color manipulation methods required for these sorts of manipulations:

Exercise 3.g.1. Modify the sample brightening program so that you can brighten or darken an image. Practice with the zim image (07zimLarge.jpg).

Creating Images

You can download digital images from the world-wide-web or create your own using a digital camera. Once digitized, any image can be manipulated by a program.

Exercise 3.g.2. Find or create an image of your own choice, load it onto your computer, and then do the following exercises:

Examples of these effects (and others) are shown here.

Original:
Negative:
Grayscale:
Sepia tone:
Blur:

Image Manipulation Applications

The Gnu Image Manipulation Package (GIMP - see http://www.gimp.org/) is an open source image manipulation package similar to Photoshop. If there is time, you can install GIMP and use it to work with your image. It uses algorithms such as the ones you’ve experimented with here to do all of its effects.

Checking In

Submit your code for the lab exercises and include a screen capture for each.