Project #3 CMSC 131
Due Friday 10/19 at 11:00PM Object-Oriented Programming I
Type of project: Open Fall 2007

Photograph Manipulation

The Duke "Blue Devil" is crushed beneath the mighty foot of Testudo!

(This photo was actually manipulated with PhotoShop, not with this project, but I couldn't resist.)

Objective

To practice using a library, reading and understanding JavaDoc, writing and calling methods, and to reinforce all of the techniques you've been learning so far.

 

Overview

This project will involve manipulation of photographs.  We have provided the images, below, for you to use with your project, but the project will work with just about any images -- in fact, you can have it manipulate any picture from the internet by typing in the URL.  Here are the photos that are included with the project:

MD.JPG
Duke.JPG
VA.JPG
WV.JPG  
 

 

Digital Images and Pixels

A digital photograph is made up of a rectangular grid of tiny spots of color, called "pixels".  There are many different schemes for how the color in a pixel could be determined -- for this project we will use the most common one (RGB).  The color of each pixel in our photos will be determined by its level of three "primary" colors:  Red, Green, and Blue.  By mixing various amounts of red, green and blue in a pixel, you can create what appears to the human eye as any of a wide range of colors.  For each pixel, the level of each of the three primary colors (red, green, and blue) can be anywhere in the range of 0 to 255.   Below is a table that illustrates how mixing various levels of Red Green and Blue results in different colors:

Red Green Blue Resulting Color
153 102 255  
89 183 105  
214 73 214  
255 255 111  
0 0 0  
255 255 255  

 

JavaDoc

JavaDoc is a tool that Java programmers use to create automatically-generated documentation for their projects.  This sort of documentation has been generated for all of the standard Java class Libraries.  If you haven't already discovered it, take a look:  Java 5.0 API Specifications.

We have created JavaDoc for the cmsc131PhotoLibrary that you will be using for this project.  Take a look:  cmsc131PhotoLibrary API Documentation.  There will be some information in the JavaDoc that you won't be able to understand yet.  Please don't worry about that -- by the end of the course it will all make sense!  You should immediately read and become familiar with the JavaDoc for the Photograph and Pixel classes, found in the link above.

 

The Driver

We are providing a Driver in a class called "Driver.java", located in the package called "editing".  (In Eclipse, click on the "editing" package to see what is inside.)  The driver contains a main method that you should run to make this project work.

When you run the main method in the driver, you will see this dialog box:

 

Enter the name of a photo you would like to edit, and then click the "Get Photo" button.

After selecting a photo, you will see your photo presented in a dialog box like this:

If you select one of the twelve "radio buttons" and then click "Modify Photo", you will see the photo displayed again after the selected "effect" has been applied.  For example, if you select the "Upside Down" radio button and click "Modify Photo" for the picture above, you will see this:

You can continue to apply effects to the image by choosing one of the various options and selecting "Modify Photo".  If at any time you want to start over with a new unaltered photo, just click the "Load New Photo" button, and you will go back to the original dialog box that asks you to enter the location of a photo.

 

PhotoTools Class

This is where you come in.  None of the editing effects will work until you implement them!  You must fill in the implementation for nine static methods of the PhotoTools class.  This class is located in the "editing" package -- in Eclipse, click the editing package to access the files inside.

Below is a description of all of the static methods that you must implement in the PhotoTools class.  You should implement these methods one at a time and run the Driver to test them out one-by-one as you write them!

For each method described below,  you will see a screenshot that shows the resulting image when the effect is applied to the original "MD.JPG" photo.  Your results must look exactly like those pictured below.  Any slight variation will cause you to fail the release tests!

  1. public static Photograph copy(Photograph photo) -- This method will return a new Photograph that is an exact copy of the parameter.  You will need to instantiate a blank Photograph that is the same size as the parameter, and then copy all of the pixels from the parameter to the new Photograph.  (Hint:  Use nested loops!)  Note:  Do not return a reference to the parameter itself; you must return a reference to a distinct copy of the parameter.

  2. public static Photograph makeBlackAndWhite(Photograph photo) -- This method will return a new Photograph that is a black and white copy of the parameter.  Here is how to create each pixel in the new photo:  Take the average of the red, green, and blue levels of the corresponding pixel in the parameter, and set all three levels for the pixel in the new photo equal to this value.  For example, if the RGB values for a particular pixel in the original photo are <100, 120, 140> then you would set the RGB values for the corresponding pixel in the new photo to <120, 120, 120> since 120 is the average of the values in the original pixel.  Note:  If the average is not a whole number, then round down.
     

  3. public static Photograph striped(Photograph photo) -- This method will return a new Photograph where the first 10 columns look like the original; the next 10 columns are all black; the next 10 columns look like the original; the next 10 are all black; etc.  To create the black pixels, set all three of the red, green and blue values to 0.
     

  4. public static Photograph isolateColor(Photograph photo, int type) -- This method will return a new Photograph that is a copy of the parameter, but with only one of the three primary colors visible .  In other words, for each pixel in the new photo, one of the primary colors will remain unchanged, but the other two will be set to zero.  The second parameter, type, will be used to specify which color will remain -- it will be:   0 for red; 1 for green; 2 for blue.  For example, if the type is 1 (green), then each pixel in the new photo will preserve the original green value, but will have the red and blue values set to 0.  Below is an example where type is 1:
     

  5. public static Photograph stretched(Photograph photo, int type) -- This method will return a new Photograph that is either twice as wide or twice as high as the original.  The parameter type will be either:  0 for a horizontal stretch, or 1 for a vertical stretch.  In other words, if type is 0, then each column in the original photo will appear twice in the new one.  If type is 1, then each row in the original photo will appear twice in the new one.  Below is an example where type is 0:
     

  6. public static Photograph enlargement(Photograph photo) -- This method will return a new Photograph that is both twice as wide and twice as high as the original.
     

  7. public static Photograph rotated(Photograph photo) -- This method will return a new Photograph that is the same as the original, but turned 90 degrees clockwise.  

  8. public static Photograph upsideDown(Photograph photo) -- This method will return a new Photograph that is an exact copy of the parameter, but rotated 180 degrees.

  9. public static Photograph weirdCombo(Photograph photo) -- This one is tricky.  The new photo will consist of an upside-down copy of the original photo positioned side-by-side with a copy of the photo rotated 90 degrees clockwise.  The height of the new photo will be equal to either the height or the width of the original (whichever is larger).  The width of the new photo will be equal to the sum of the height and width of the original.  All pixels in the new photo that do not fall within either of the original pictures must be set to black.  Below is an example:
     

 

 

Requirements

 

Grading

For this project, we have written one test for each of the methods you will be implementing.