Revisiting images

Back in project 1, we worked with PPM pictures, but were limited to tasks that didn't require us to store any pixel values. Now that we know arrays, we can do better.

To make life a little more straightforward, we'll be using PGM images, which are exactly like PPM images, except limited to black-and-white. So, each pixel has a single integer representing it's brightness, rather than three representing R, G, and B. So, for example,

4 4
0   255 0   0
0   0   255 0
0   0   0   255
128 128 128 128

gives you this:

So we will be reading, storing and writing files in these formats. I want you to use your own pictures for this stuff. Hopefully you already know how to download and save image files. What you need to know, however, is how to convert them to pgm files. Fortunately, the lab machines have a suite of tools called "Imagemagick" installed. One of these, convert, can do this conversion for you. Suppose foo.jpg is a file of yours (could be .png, .gif, whatever). To convert it to pgm do the following:

Whenever the output file in convert is a .pgm file, be sure to give the -compress none option! It's a good idea to check each .pgm file to make sure the format looks OK using the less command, like this (hit q to quit less):

less foo.pgm

convert -compress none foo.jpg fpp.pgm

You can convert back to .jpg with the following:

convert bar.pgm bar.jpg

You can also resize with Imagemagick. For example, to stretch/compress the an image tmp.jpg into a 300 wide by 500 pixel high image, I can do:

convert -resize 300x500! tmp.jpg tmpNEW.jpg

With these simple commands in hand, you should be able to prepare your own images for this lab. To view an image, use the eog program. For example:

eog foo.pgm &

I really prefer you find some images of your own. If you want, however, here are two for you to play with: dog.pgm / dog.jpg and cat.pgm / cat.jpg

Part 1: Posterize (up to 25/100)

Write a program in a file called part1.cppthat reads in a file in .pgm format, and produces a "posterized" version of that file. Note: even though this particular part doesn't require it, I insist that you read the file completely and store it in a 2D array, and only then create the posterized version. Here's an example:

~/$ ./part1
filename: cat.pgm
output filename: postercat.pgm

goes from


The rule for posterization I used was this: if a pixel in the original has value > 128, in the new image that pixel has value 255. Otherwise, it has value 0.

Part 2: Reflections (up to 60/100)

Write a program in a file called part2.cpp that reads in a file in .pgm format, and produces a version of that file that is the image with its reflection along the bottom of the original image. So this:

~/$ ./part2
filename: dog.pgm
output filename: mirrordog.pgm

takes this


Part 3: Rotate (up to 85/100)

Write a program in a file called part3.cpp that reads in a file in .pgm format, and produces a version of that file with the image rotated 90 degrees counter-clockwise. Here's an example:

~/$ ./part3
filename: cat.pgm
output filename: rotatecat.pgm

takes the cat image to this:

Part 4: Color (up to 100/100)

We could, of course, do all these things using our color PPM images, as well, but it would require a 3D array, where image[i][j][0] is the red channel of pixel on row i and column j, image[i][j][1] is the green channel, and image[i][j][2] is the blue channel.

What type will your array be? Well, it'll be an array of 2D arrays... so int***.

Remember that to convert an image to PPM, you use the command convert -compress none somePic.jpg somePic.ppm.

Redo part 3, but using a color ppm image, in a file called part4.cpp.

Who needs a prof?

From here, the sky's the limit. What do you want to do? You could draw pictures in pixels, fade to black as you move horizontally across an image, merge to images so that the top is image 1, the bottom is image 2, and the transition between is smooth. How about "masking", e.g. take one of the posterized images and a second image, and make it so that the second image only shows through where the posterized image is white. You could do that thing where you create a big picture that's made up of little pictures. You could even produce animated gifs with a little more help from Imagemagick.