CS 160, Summer 2016
Programming Assignment P7
Unscrambling Images
Programming due Monday, Jul. 25 at 6:00pm; late deadline at 11:59pm.
Using 2D Arrays to Write an Image Editor
This assignment has the goal of teaching you how to:
- Implement a set of methods that allow a GUI object to use your class.
- Instantiate and call a supplied class to read and write images.
- Declare and use 2D arrays to store images.
- Manipulate the data in 2D arrays to unscramble images.
Description
The purpose of the assignment is to write a Java class that can be called by a user interface
program to unscramble images in the Portable GreyMap (PGM) format. To do this you need to write
a P10 object that inherits from an interface and implements all methods in that interface.
It also instantiates and calls methods in PictureLibrary.java, and is in turn called
from a graphical user interface (GUI) class called ImageProgram.java. Both of these
are supplied below.
Instructions
Part One
- Create a new project and class called P7, without a main method.
Note: You may want to leverage code from the R10 recitation.
- Download and import PictureLibrary.java
- Download and import ImageProgram.java
- Download and import ImageInterface.java
- Make the class implement the ImageInterface interface, as shown in the lab.
- Do NOT modify any of the given files, just import them into your P7 src folder
Part Two
- At the top of the class, declare the following instance (non-static) variables:
- An object of type PictureLibrary, set to null
- An integer to store the image width, set to 0
- An integer to store the image height, set to 0
- A 2-dimensional array of integers to store the image data, not allocated
- Name your variables whatever you want
- Create a constructor for the P7 class as shown below that allocates an object
of type PictureLibrary into the associated class instance variable.
public P7(){
//Allocates PictureLibrary object
}
Part Three
Implement the methods in the ImageInterface interface.
All methods need to be created before your code will compile.
The readImage method should call the readPGM
method using the PictureLibrary object, passing the input
file name, then it should call the getHeight,
getWidth, and getData methods to fill in the
class instance data defined above. The writeImage
method should call the setData method using the Picture
object with the image data, then call the writePGM
method passing the output file name. The parameters and return
types of the methods in PictureLibrary.java are not documented
here, so you must look at the file to find them. The calls to readImage and
writeImage should be wrapped in a try catch block as follows:
try {
// Calls to readPGM or writePGM and associated code here
} catch (Exception e) {
System.out.println(e.getMessage());
}
Implement imageData by simply returning a copy of the image array. The remaining
methods manipulate the image data in some way or another to restore an image that has
been scrambled.
Part Four
Make sure that all methods exist in your P7.java, even though some of the transformations
may not do anything. You should now be able to run the main program in ImageProgram.java
to read and write PGM files. If you are having trouble integrating with the provided files,
check that your method names and parameters match. We have provided a test file called
Cam.pgm that you can download to the P7 project
directory (not into the /src or /bin subdirectories).
Part Five
Implement the remaining methods as follows:
- Calling decode restores an image in which each pixel has had the
upper six bits negated. To unscramble the image, your code should negate them
again. You can use bitwise operators, as shown below:
- original pixel = 115 = 0b01110011
- upper value = 115 & 0b11111100 = 0b01110000 (upper six bits of original)
- lower value = 115 & 0b00000011 = 0b00000011 (lower two bits of original)
- negate upper value = ~upper & 0b11111100 = 0b10001100
- new pixel = upper | lower = 0b10001100 | 0b00000011 = 0b10001111 = 143
- Calling swap restores an image in which each pixel has been
scrambled by exhanging the lower 2 bits with the upper 2 bits. To do this
requires that your code do the same exchange to restore the original pixel.
Don't modify the middle four bits. By far the easiest way to do this is to
use the bitwise operators. Here's an example for your testing:
- original pixel = 114 = 0b01110010
- upper two bits of original = 0b01110010 & 0b11000000 = 0b01000000
- middle four bits of original = 0b01110010 & 0b00111100 = 0b00110000
- lower two bits of original = 0b01110010 & 0b00000011 = 0b00000010
- new pixel = (lower << 6) | middle | (upper >> 6) = 0b10110001 = 177
- Calling mirror reverses the image left to right. To reverse left to
right, exchange the first column for the last column, the second column for
the second to last column, and so on until the entire image is reversed.
- Calling exchange swaps the image area defined by a rectangle with
width 200 and height 300 starting at row index 20 and column index 20 for
a rectangle of the same size starting at row index 20, and column index 280.
NOTE: The maximum value of a pixel (PictureLibrary.MAXVAL) is 255, so only 8 bits
are valid for each pixel. These are numbered bits 0-7, where bit 0 is equal to 1
and bit 7 is equal to 128. There are no negative values allowed.
Testing
The decode method can be tested with Decode.pgm.
The swap method can be tested with Swap.pgm.
The mirror method can be tested with Mirror.pgm.
The exchange method can be tested with Exchange.pgm.
In all cases, the restored image should be identical to Cam.pgm. After unscrambling an
image you can write it to the disk, and compare it to Cam.pgm using the Linux diff
command, thus all students can verify that their code is perfect before submission!
NOTE: We may test your code with an image file that has a different
size and contents than the provided test file, so do not hardcode anything.
Grading Criteria
Note: Do not modify the provided files in any way, or your program
will not compile in our test system!
- 100 points for perfect submission.
- 0 points for no submission, will not compile, submitted class file, etc.
- We use only the files supplied to you for testing!
- Preliminary Tests
- compileTest: checks that program compiles. (0 points)
- test1: checks that your program can read and write image files (20 points)
- test2: checks that decode exactly restores the input image "Decode.pgm". (20 points)
- test3: checks that swap exactly restores the input image "Swap.pgm". (20 points)
- Final Tests
- test3: checks that mirror exactly restores the input image "Mirror.pgm". (20 points)
- test4: checks that exchange exactly restores the input image "Exchange.pgm". (20 points)
- Final grading includes the preliminary tests.
Please follow the usual rules for submitting Java programs.
- Work on your own.
- The name of the source code file must be exactly P7.java
- Comments at the top with your name, e-Name, date and course.
- Submit the P7.java source file, not the P7.class file.
- We expect programming assignments to be implemented in Eclipse
using Java 1.7 or Java 1.8 (1.6 or less will NOT work).
- We will be testing the code on the machines in the CS computer lab,
so make sure your code runs on those machines.
- We will be checking programs for plagiarism, so please don't copy
from anyone else.
Submission
Submit your modified source file named P7.java to the the Checkin tab on the course web site.
© 2016 CS160 Colorado State University. All Rights Reserved.