CSC 120 Programming Assignment 8 Option 4
Display an Image

Note: You should not work on this assignment during class-time unless:
  1. You have completed all of the in-class assigned work for the day, and
  2. You have permission from the instructor.

This assignment must be handed in to your instructor's handin folder before the beginning of class on the due date.

Description:

Your program should accept input that represents an image encoded using the PPM format, convert this input into numeric values, and use an MUPanel to display the image on the computer screen.

This is the most difficult option for PA8, and it is not worth any more points than the other options.  The instructor will try to help with minor issues, but will not write the program for the student; if you can't get this option to work, you should choose one of the other options.

Change in User Interface for this Option

If you choose this option for PA8, your program does not need an output TextArea -- instead, you should have an output drawingPanel that contains an MUPanel object, so that the image may be drawn on the screen.

The following .zip file archive contains three files (MUFrame.java, MUFrame.form and MUPanel.java) that implement a version of the user interface that you need for this option of PA8.  Feel free to Extract All files from this .zip file and copy the results into the src folder of your PA8 project:
PA8_Starter.zip

Input format:

The PPM image format encodes an image in a pixel-by-pixel manner.  The first three lines of the file are the heading of the file, and have the following format:
P3
<widthInPixels> <heightInPixels>
<maximumColorValue>
After the heading lines, the file contains <widthInPixels> * <heightInPixels> * 3 numeric values in the range from 0 to <maximumColorValue>, inclusive.  Each triplet of numbers represents the red, green and blue components of one pixel, in that order.  Pixels are specified in the file from top to bottom, left to right in the file (called column-major order).  When more than one value is given on a line, the values are separated by a space.

Here is an example that defines a 4x4 image that has color values in the range from 0 to 100:
P3
4 4
100
0 0 0
0 0 0
10 20 80
0 0 0
0 0 0
0 0 0
10 20 80
0 0 0
0 0 0
0 0 0
10 60 80
0 0 0
0 0 0
0 0 0
10 60 80
0 0 0
There are 4x4x3 == 48 values afer the first 3 lines that represent the 16 pixels of the image.  The first four pixel lines represent the left-most column of pixels in the image.

Note that you should use the trim method of the String class to remove all leading and trailing spaces from all parts of the input before processing the values in your program.

Methods and Objects to define in MUPanel.java:

At the top of MUPanel.java, declare a two-dimensional array of Color values named pixel and an Integer named colorMax, like this:
    private Color[][] pixel; 
    private Integer colorMax;
Next, add this code to the paintComponent method of the MUPanel class:
        if (pixel != null) {
            for (int w = 0; w < pixel.length; w++) {
                for (int h = 0; h < pixel[0].length; h++) {
                    g.setColor(pixel[h][w]);
                    g.fillRect(w, h, 1, 1);
                }
            }
        }
Then copy these methods into MUPanel.java after the paintComponent method:
    public void makePixelMap(int width, int height, int cm) {
        pixel = new Color[width][height];
        for (int w = 0; w < width; w++) {
            for (int h = 0; h < height; h++) {
                pixel[w][h] = Color.BLACK;
            }
        }
        colorMax = cm;
    }
       
    public void setAPixel(int lineNum, float red, float green, float blue) {
        int x = lineNum / pixel[0].length;
        int y = lineNum % pixel[0].length;
        pixel[x][y] = new Color(red/colorMax, green/colorMax, blue/colorMax);
    }

Outline of Processing Logic in MUFrame.java:

When the processing button is clicked by the user, the program should split the input entered by the user in the input area into separate strings for each line of the input.  Next, process the first three lines of input separately to obtain the width, height and maxColorValue values from the input.  Once you have those values in Integer variables, call this method of the muPanel object:
    muPanel.makePixelMap( width, height, maxColorValue );
Then for each line of image data in the input (starting with 3 and continuing as long as we are < the length of the input line array),
  1. split the line into three values using the string " " as the delimiter (there is one space between the quotes)
  2. trim off leading and trailing spaces from each of the three values obtained in the previous step
  3. convert the three values from the input line into Floats representing the colors of the pixel (use Float.parseFloat to do the conversion)
  4. call the setAPixel method of muPanel using syntax like this:
        muPanel.setAPixel(lineNum-3, red, green, blue);
    
  5. that's the end of the for loop
Be sure to call muPanel.repaint(); at the end of your actionPerformed method in MUFrame

Input Samples to Use:

Your program should be able to process all of these inputs correctly:
  1. A horizontally-striped pattern   (50 × 50)
  2. A picture of an antelope   (102 × 102)
  3. A picture of marbles   (150 × 150)
  4. A zoom into the Mandelbrot Set   (247 × 247)
  5. A weird star-like pattern   (275 × 275)
  6. Prof. Cindric's college senior photo   (100 × 100)

Credits:

For more information about the PPM image format, visit Paul Bourke's PPM page.

It is expected that each student will complete this assignment INDIVIDUALLY.