This lab we will be writing programs that manipulate images. We will be using a format called PGM (.pgm), that is very simple. It represents an image in a text file in which each pixel is represented by a number from 0 and 255. 0 is black, and 255 is white.

So, for example:
P2
4 4
255
0   255 0   0
0   0   255 0
0   0   0   255
128 128 128 128   
<-- header
<-- size: 4 (width) x 4 (height)
<-- max value = 255 
We will be reading, storing and writing files in these formats. Here are two images for you to play with: dog.pgm / dog.jpg and cat.pgm / cat.jpg

Part 1: Posterize -- part1.cpp

Write a program that 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:

run of programcat.pgmpostercat.pgm
~/$ ./part1
filename: cat.pgm
output filename: postercat.pgm
The rule for posterization I used was this:

Viewing pgm files

To view your image, use the eog program. For example:
eog postercar.pgm &

Test vector

  1. Download test_postercat.pgm.
  2. Download diffsh.
  3. Change the permission of diffsh in the terminal:
    ~/$ chmod 700 diffsh
  4. Check if your output file is correct:
    ~/$ ./diffsh postercat.pgm test_postercat.pgm

Submit

~/bin/submit -c=IC210 -p=lab08 part*.cpp

Part 2: Mirror -- part2.cpp

Write a program 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. Here's an example:
run of programdog.pgmmirrordog.pgm
~/$ ./part2
filename: dog.pgm
output filename: mirrordog.pgm

Test vector

  1. Download test_mirrordog.pgm.
  2. Check if your output file is correct:
    ~/$ ./diffsh mirrordog.pgm test_mirrordog.pgm

Submit

~/bin/submit -c=IC210 -p=lab08 part*.cpp

Part 3: Merge -- part3.cpp

Write a program that reads in two files in .pgm format, both of the same size, and produces a new file of that size merges the two files. Here's an example:
run of programcat.pgmdog.pgmcatdog.pgm
~/$ ./part3
file 1: cat.pgm
file 2: dog.pgm
output filename: catdog.pgm

The rule for merging is as follows:

Test vector

  1. Download test_catdog.pgm.
  2. Check if your output file is correct:
    ~/$ ./diffsh catdog.pgm test_catdog.pgm

Submit

~/bin/submit -c=IC210 -p=lab08 part*.cpp

Part 4: Rotate -- part4.cpp

Write a program 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:
run of programcat.pgmrotatecat.pgm
~/$ ./part4 
filename: cat.pgm
output filename: rotatecat.pgm

Test vector

  1. Download test_rotatecat.pgm.
  2. Check if your output file is correct:
    ~/$ ./diffsh rotatecat.pgm test_rotatecat.pgm

Submit

~/bin/submit -c=IC210 -p=lab08 part*.cpp

Part 5: Show your pictures to the instructor

I want you to use your own pictures for this stuff.
Other useful commands

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

jpg/png/gif → pgm

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:

convert -compress none foo.jpg fpp.pgm
-compress none: 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 more command, like this:
more foo.pgm

Viewing pgm files

To view an image, use the eog program. For example:
eog foo.pgm &
To do: Show your images (posterized, mirrored, merged, and rotated) to your instructor!

Part 6: Going Further - striping -- part6.cpp

Write a program that reads in two files in .pgm format, both of the same size, and produces a new file of that size consisting of vertical strips alternatingly from one then the other of the input files. The user will input the width of each vertical strip (in pixels). Here's an example:
run of programcat.pgmdog.pgmcatdog.pgm
~/$ ./part6
file 1: cat.pgm
file 2: dog.pgm
width of a strip in pixels: 8
output filename: stripcatdog.pgm

Test vector

  1. Download test_stripcatdog.pgm.
  2. Check if your output file is correct:
    ~/$ ./diffsh stripcatdog.pgm test_stripcatdog.pgm

Submit

~/bin/submit -c=IC210 -p=lab08 part*.cpp

Part 7: Going Further - blur -- part7.cpp

Write a program that reads in a file in .pgm format, and produces a version of that image that's blurred. Here's an example:
run of programdog.pgmblurdog.pgm
~/$ ./part7
filename: dog.pgm
blur size: 3
output filename: blurdog.pgm
Here's how I did the blur:

Test vector

  1. Download test_blurdog.pgm.
  2. Check if your output file is correct:
    ~/$ ./diffsh blurdog.pgm test_blurdog.pgm

Submit

~/bin/submit -c=IC210 -p=lab08 part*.cpp

Part 8: Still Going Further

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 take an image and produce an ASCII art equivalent. You could do that thing where you create a big picture that's made up of little pictures.