Assignment 5: Image Magic Due July 21 and 28 at 9:00pm and

In this assignment we will be exploring file input and image processing. In the process, we will also gain experience using exceptions and assertions. The project is to be worked on in pairs with the first part being due on July 21 ar 9:00pm and the second part being due on July 28 at 9:00pm.

Part 1: Input/Output

In this part we will develop the infrastructure to read in images from files. There are two types of files we will be dealing with: black and white images, and color (RGB) images. But before we get to all that, a note on images. . .

Digital Images

Digital images are represented in a computer as a grid of intensity values. Each grid element, indexed by row and column number, is known as a pixel, short for picture element. For a black and white image, each pixel contains one value representing how bright that pixel should be (for our purposes, all intensity values will be represented as values from 0 to 255). A value of 255 is totally white.

For color images, each pixel stores three values, one for each primary color of light, red, green, and blue. Because of the way our eyes work, combining these colors in different amounts creates the illusion of millions of different colors spanning the entire spectrum!

One more thing: i mentioned before that pixels are reffered to by their row and column (r,c). This is true but you should know that the pixel at row 0, column 0 (0,0) is at the upper left corner of the image while the pixel at (height-1, width-1) is at the lower right.

File Formats

We will be manipulating files using two formats: PGM and PPM. PGM (Portable Grey Map) is a format for storing grayscale images and PPM (Portable Pixel Map) is used to store color images.

The file format for PGM images is very simple. The element of the file is the string P2. The next elements are the number of columns followed by the number of rows followed by the number of levels. (The number of levels is the number of divisions between full black and full white.) When I say "element" I mean a string of alphanumeric characters separated by whitespace. After the number of levels, the intensity for each pixel is given. Additionally, any line that begins with '#' is a comment. For example:

P2
# i made this image by hand
10 10
255
0 0 0 0 0 0 0 0 0 0 
0 255 0 0 255 0 255 255 255 0 
0 255 0 0 255 0 0 255 0 0 
0 255 0 0 255 0 0 255 0 0 
0 255 255 255 255 0 0 255 0 0 
0 255 0 0 255 0 0 255 0 0 
0 255 0 0 255 0 0 255 0 0 
0 255 0 0 255 0 0 255 0 0 
0 255 0 0 255 0 255 255 255 0 
0 0 0 0 0 0 0 0 0 0 

The PPM format is very similar. Instead of P6 there is P3 and instead of single values for each pixel, there are three values in a row, one for red, one for green, and one for blue. For example:

P3
10 10
255
0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 
0 255 255 0 255 255 255 255 0 0 255 255 0 255 255 255 255 0 0 255 255 255 0 255 255 0 255 255 0 255 
0 255 255 0 255 255 255 255 0 0 255 255 0 255 255 255 255 0 0 255 255 0 255 255 255 0 255 0 255 255 
0 255 255 0 255 255 255 255 0 0 255 255 0 255 255 255 255 0 0 255 255 0 255 255 255 0 255 0 255 255 
0 255 255 0 255 255 255 255 0 255 255 0 255 255 0 255 255 0 0 255 255 0 255 255 255 0 255 0 255 255 
0 255 255 0 255 255 255 255 0 0 255 255 0 255 255 255 255 0 0 255 255 0 255 255 255 0 255 0 255 255 
0 255 255 0 255 255 255 255 0 0 255 255 0 255 255 255 255 0 0 255 255 0 255 255 255 0 255 0 255 255 
0 255 255 0 255 255 255 255 0 0 255 255 0 255 255 255 255 0 0 255 255 0 255 255 255 0 255 0 255 255 
0 255 255 0 255 255 255 255 0 0 255 255 0 255 255 255 255 0 0 255 255 255 0 255 255 0 255 255 0 255 
0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 
0 255 255 

(Try copying and pasting the above text into a text editor and saving the file with a .pgm or .ppm extension...you should have a viewable image!

Your Task

Create classes called PPMImage and PGMImage in the imageprocessing package. These class should implement an interface Image or extend an abstract class Image. Whether you use inheritance or interfaces is up to you, but be sure you are able to justify your choice. The image class/interface should define the methods:

Each of these classes should store the width and height of the image and have a method int[] getPixel(int r, int c) that returns the values at the specified row and column. If the image is a color image (a ppm) the colors should be in RGB order with the R at index 0. You should define methods the two classes have in common in the interface or abstract class, Image.

Create a file called ImageReader which takes a single String representing the file name of the image to be read. An appropriate response is required at this point if the file is invalid. When the method Image produceImage() is called, the image is loaded from the file and returned. The image should not be loaded until the produceImage method is called. Again something reasonable (having to do with exceptions!) should be done in the case of something going wrong (such as getPixelValues being called before the image has been produced...).

Note that ImageReader should be able to read both PPM images and PGM images.

Create a class called ImageWriter whose constructor takes an Image and a file name and writes the image to the file.

In all cases, if your program can fail, it should fail gracefully! Use exceptions and assertions wherever appropriate!

Create a class called TimesTwo whose constructor takes only an Image and and has a method Image produceImage() that returns an image identical to the image input into the constructor but twice the size. That is, it scales the image by 2x.

A class for viewing your loaded images is provided along with some sample images. The class ImageViewer is a member of the imageprocessing package. Its constructor takes an Image and pops up a window with the image on the screen. Additionally you can use a number of programs freely available online to produce you own images; I recomend IrfanView.

Turn in (by 7/21 at 9:00pm):

Part 2: . . .

A big surprise!