A8-Image Manipulation

On This Page


Overview

The main points of this assignment are to:

  • Work with exceptions
  • Work with text files
  • Make changes to an image file

Background Information

Most digital images use a color model known as RGB (Red, Green, Blue). The red, green and blue values combine to create the overall color as shown in the following image taken from Wikipedia.

RGB color combinations

The screen on a computer uses each RGB combination to create the color. At each location on the screen, called a pixel, there are three color sources, one for red, green and blue.

  • On CRT monitors, three different color dots are excited at different intensities
  • On LCD monitors, three different transistors are used to control how much light for each color is let through

Image Files

When storing these images in a file, most image formats use a binary arrangement that is efficient for the computer to read and process. Many image files use data compression to reduce file size and save storage space. However, one file format, called portable pixmap (PPM), stores the RGB values in plain text. The following is a PPM example also taken from the Wikipedia article: Netpbm format.

P3
#the P3 means colors are in ascii, then 3 columns and 2 rows, then 255 for max color, then RGB triplets
3 2
255
255 0 0
0 255 0
0 0 255
255 255 0
255 255 255
0 0 0

This file displays the following image, which is expanded by 6400%.

PPM image from the above example file

The first value is a magic number and is always P3. The next line is often a comment, but comments can appear anywhere. All comments start with a hash mark (#) and last to the end of the line. The next two number are the width and height of the image respectively. The following number is the color depth, which is the maximum red, green or blue value. Thus, a color depth of 255 means that red, green or blue will range from 0 to 255 inclusive of 0 and 255.

Creating and Viewing PPM Image Files

You can create and alter PPM image files using a text editor. However, creating or modifying each RGB triplet for a pixel is tedious. An easier approach is to use an image manipulation program like GIMP, the GNU Image Manipulation Program. To create a PPM file, load an image file into the image manipulation program and then save it as a PPM file. For example, I used GIMP and the following image to create this PPM file: rose.ppm.

Image of a rose

Some programs that support PPM include:

Color Coding

Java supports the standard RGB color model using the Color class. A Color object is created from RGB values using code like:

Color brown = new Color(204, 102, 0);

The RGB values can be specified as either type float (0.0 to 1.0) or type int (0 to 255):

Color(float r, float g, float b) // 0.0 - 1.0
Color(int r, int g, int b)       // 0 - 255

More Information

Program Specifications

Write an image manipulation application that meets the following requirements:

  1. Write a class named Picture that encapsulates all the information about an image.
  2. In the Picture class, store all the RGB color information about the image in an array of Color objects, using the Color class from the java.awt.Color API.
  3. In addition, declare instance variables for the image width, height and color depth.
  4. All member variables of the Picture class, except constant variables, must be declared private.
  5. The Picture class must contain the required public methods listed below.

    You may add more methods as needed, but these are required.

  6. The loadPPM() method must throw an I/O exception if the magic number of the file being loaded is not "P3".
  7. Your Picture class must pass all the tests of the Test Cases provided below with no user input.
  8. Write a second class named PictureApp with a main() method that runs the image manipulation application. The application must provide a menu as shown in the example operation and support the following commands in both upper and lower case:
    • A: add or subtract RGB values to every pixel of the Picture
    • L: load an image from a PPM file
    • S: save the picture to a PPM file
    • Q: quit

    In addition, your program must follow the same sequence of operations for each menu item as the Example Operation shown below.

  9. In your PictureApp class, write a readInt() method, similar to the example in lesson 9.1.6, with the following heading:
    /**
        Read an int from the console.
    
        @return An valid int input by the user.
     */
    public static int readInt(Scanner input, String prompt) { }
    
  10. You must document and organize your code following the requirements in the How To Document and Organize Java Code. Your program must pass CheckStyle configured with the grade_checks.xml for full credit. Note that the CTC has this configured on their computers and that I have instructions for setting up TextPad to use CheckStyle.
  11. Do not use any package statements.
  12. Make an executable JAR of your program containing all the files described in the section of this document: What to Turn In.

Required Public Members of Class Picture

/**
    Default constructor.
*/
Picture() { }

/**
    Returns the width of this Picture.

    @return the width in pixels.
*/
public int getWidth() { }

/**
    Returns the height of this Picture.

    @return the height in pixels.
*/
public int getHeight() { }

/**
    Returns the maximum color depth of this Picture.

    @return the maximum color depth of each RGB value.
*/
public int getColorDepth() { }

/**
    @return a copy of the array of Color objects or null
    if no image is loaded.

    @return a copy of the array of Color objects.
*/
public Color[] getColors() { }

/**
    Adds or subtracts the specified amount of red, green
    and blue to each pixel of this picture. Use negative
    numbers to subtract values.

    @param redAmount The amount of red to add or subtract.
    @param greenAmount The amount of green to add or subtract.
    @param blueAmount The amount of blue to add or subtract.
*/
public void addRGB(int redAmount, int greenAmount,
        int blueAmount) { }

/**
    Loads a PPM file identified by the imageFile.

    @param imageFile The file to load.
    @throws IOException when an I/O exception of some sort
    has occurred, including if the file type is not correct.
*/
public void loadPPM(String imageFile) throws IOException { }

/**
    Save this Picture as a PPM file.

    @param imageFile The name of the file.
    @throws IOException when an I/O exception of some sort
    has occurred
*/
public void savePPM(String imageFile) throws IOException { }

Example Operation

Welcome to PhotoJava!

Choose an operation:
A: add or subtract RGB values to every pixel
L: load an image from a PPM file
S: save the picture to a PPM file
Q: quit
Choice: l
PPM file name: colors.ppm

Choose an operation:
A: add or subtract RGB values to every pixel
L: load an image from a PPM file
S: save the picture to a PPM file
Q: quit
Choice: a
Enter RGB amount to add or subtract.
Use negative numbers to subtract.
Red amount: 1
Green amount: 2
Blue amount: 3

Choose an operation:
A: add or subtract RGB values to every pixel
L: load an image from a PPM file
S: save the picture to a PPM file
Q: quit
Choice: s
PPM file name: colors-out.ppm

Choose an operation:
A: add or subtract RGB values to every pixel
L: load an image from a PPM file
S: save the picture to a PPM file
Q: quit
Choice: q
Goodbye

Also, you can download the asn08demo.jar and colors.ppm files. Run the demo, as shown above, from the command line using:

java -jar asn08demo.jar

Note that the JAR file may contain some extra credit features. Also note that the example program uses the optional PictureDisplay class that will display a Picture in a JFrame. You can use the class if you would like to see the changes you make to your Picture.

PictureDisplay.java

Hints for Getting Started

  1. Start by declaring a class Picture and copying the required methods into the class. Then write the get-methods and add instance variables as needed until the class compiles
  2. Write the loadPPM() method using the techniques for reading a text file discussed in lesson 9.4.7. Use the colors.ppm file to trace your loadPPM() method and ensure your method loads a file correctly
  3. You can work with either 2D or 1D arrays, though 1D is probably easier. Note that getColors() returns a 1D array and you cannot change this requirement. You can convert the index of 2D arrays to 1D using the formula:

    index1D = col * numColumns + row

  4. Use the PictureTester and image files (see Test Cases below) to ensure your Picture class works correctly.

Test Cases

Testing is an important part of software development. Usually, programmers develop tests for each unit of code they produce. This is know as "unit testing" and allows the programmer to verify that the code they develop works correctly.

To assist you in developing your code, I provide tests for this assignment. These tests, known collectively as "test cases", help to make sure that your assignment meets its requirements. I will use these test cases (and perhaps others) to test your assignment, and you should too. If the test cases do not pass, then you will lose points for the assignment.

Install the tests by copying the following file into the same directory as your .java source code files:

Compile and run the test class as you would any other Java program. You may need to compile your source code before compiling and running the test code.

Extra Credit

The following are worth extra credit points:

  1. Write a new IOException subclass named UnsupportedImageFileException and throw this exception, instead of IOException, if the magic number of the file being loaded is not "P3". (2 points)
  2. Add a method to the Picture class with the following heading. The method converts a color image to grayscale using the formula: L = r * 0.229 + g * 0.587 + b * 0.114 and then setting each RGB value to L. (2 points)
    /**
        Change this picture to grayscale.
    */
    public void toGrayScale() { }
    
  3. Add another image file manipulation method to the Picture class. (1 to 2 points depending on difficulty)

Make certain that your README.txt file lists any extra credit attempted.

Grading Criteria

The instructor will evaluate your assignment using the following criteria. Each criteria represents a specific achievement of your assignment and has a scoring guide. The scoring guide explains the possible scores you can receive.

Some scoring guides have a list of indicators. These indicators are a sign of meeting, or a symptom of not meeting, the specific criterion. Note that a single indicator may not always be reliable or appropriate in a given context. However, as a group, they show the condition of meeting the criterion.

For information on grading policies, including interpretation of scores, see the course information page.

Program Compilation

  • 4: Source code compiles with no errors or warnings
  • 2: Source code compiles with warnings
  • 0: Does not compile

Functionality

  • 10: Demonstrates mastery of the assignment
    • Has extra features or demonstrates techniques beyond the assignment
    • Applies concepts from the lesson(s) appropriately
    • Meets all specifications (see above) with particularly elegant solutions
    • No errors encountered during operation
    • All test cases pass
  • 8: Has all the functionality expected of the assignment
    • Demonstrates many techniques from the lesson
    • Meets all specifications (see above)
    • Implementation seems more complicated than necessary.
    • May have one minor error
    • All test cases pass
  • 6: Has most of the functionality expected of the assignment
    • Demonstrates some techniques from the lesson
    • Meets all but one of the specifications (see above)
    • Implementation seems excessively complicated.
    • May have 2-3 minor errors
    • All but one test case passes
  • 4: Has some of the functionality expected of the assignment
    • Demonstrates some techniques from the lesson
    • Meets at least 1/2 of the specifications (see above)
    • Implementation seems excessively complicated.
    • May have more than 3 minor errors
    • At least 1/2 of all test cases pass
  • 2: Serious functional problems but shows some effort and understanding
    • Meets less than 1/2 of the of the specifications (see above)
    • Has a major error or many minor errors
    • Implementation seems very convoluted
    • Demonstrates few techniques from the lesson
    • Less than 1/2 of all test cases pass
  • 0: Does not execute or no specifications met

Program Style

  • 4: Code is well-documented
  • 3: Code has minor documentation errors
    • Has 1 documentation error
  • 2: Code has some documentation errors
    • Has 2-3 documentation errors
  • 1: Code has many documentation errors
    • Has more than 3 documentation errors
  • 0: No apparent attempt to document code

README.txt File

  • 2: README.txt file submitted with specified information included
  • 1: README.txt submitted but some information was not included
  • 0: No README.txt submitted

Maximum Score: 20, plus extra credit

What to Turn In

Submit your assignment following the instructions for homework. Include the following items for grading:

  1. README.txt file
  2. All Java source code and class files in a single executable JAR file

You must submit all the files needed for your assignment to compile and work correctly. Do not assume that the instructors has any files. Also, do not turn in files that are not part of your assignment, especially ones that do not compile. Your assignment must compile after removing all the .class files and running: javac *.java. In addition, your code must work as submitted.

Home | Blackboard | Announcements | Schedule | Room Policies | Course Info
Help | FAQ's | HowTo's | Links
Last Updated: April 22 2009 @17:54:41