Design and development of significantly sized software using top-down design and bottom-up implementation. Dynamically allocated data, object-oriented programming, architecture of memory, basics of language translation, and basics of algorithm analysis. Development of simple graphical user interfaces. Prerequisite: CS 110 (grade of C or better).

Project 2 - Image Manipulation - (100 points)



Due date: Part 1 - 3/2/2016 at 11:59pm

Due date: Part 2 - 3/6/2016 at 11:59pm

Objectives



  • Gain practice with algorithmic thinking and array manipulation
  • Learn to use existing classes in your program
  • Learn basic image manipulation algorithms
For this assignment, you will practice algorithmic thinking and array manipulation by writing an image manipulation program. This assignment is adapted from an assignment by Richard Wicentowski and Tia Newhall of Swarthmore. This assignment requires you to build on code developed and provided by Wicentowski and Newhall as part of their original assignment.

An image is effectively a 2D array of Pixels where each pixel is represented by three numbers from 0-255: the amount of red, amount of green, and amount of blue in the pixel. (255, 255, 255) represents a white pixel (0, 0, 0) represents a black pixel. Unlike an array, however, pixels are referenced by their (x, y) coordinates. In the example below, the pixel marked in RED as (2, 3) -- so column first then row rather than the array style of row then column.

(0,0) (1,0) (2,0) (3,0) (4,0) (5,0) (6,0)
(0,1) (1,1) (2,1) (3,1) (4,1) (5,1) (6,1)
(0,2) (1,2) (2,2) (3,2) (4,2) (5,2) (6,2)
(0,3) (1,3) (2,3) (3,3) (4,3) (5,3) (6,3)


The class Picture.java allows you to create a new image by specifying a height and width, or a filename.

  • If you specify the name of a file containing a gif image, the Picture() constructor will create a new image of the correct size.
  • You can retrieve the height and width of the image, as well as get and set pixels in the image. The get/setPixel methods reference Pixelobjects.
  • The class Pixel.java defines an object containing three int values: Red, Green, and Blue. The individual color values for every pixel can be accessed or changed.
  • Suppose a variable of type Picture called image refers to an image with height 4 and width 6 as shown above, image.setPixel(2, 3, new Pixel(255, 255, 255)) would set the pixel marked in red above to be white.

ImageDriver and ImageManipulator class



For this project, you will implement two classes: ImageDriver and the ImageManipulator class.

  • The ImageDriver will take as input a file name from the user.
  • It will create a new ImageManipulator object passing the filename as input to the ImageManipulator constructor.
  • It will then invoke the methods of ImageManipulator, which will manipulate the image as specified and save a new image to the file indicated.
  • ImageManipulator: ImageManipulator will contain the following methods.
  • Part 1 methods - due 3/2:
    • public void makeNegative() - creates an inversion of the original image by setting the red value for each pixel to be 255 minus the original red value, and the same for green and blue. The new image will be saved to a file called negative.gif.
    • public void flipVertical() - flips the image along the vertical axis, effectively turning it upside down. The new image will be saved to a file called verticalflip.gif.
    • public void flipHorizontal() - takes no input and will flip the image along the horizontal axis, effectively creating a mirror image. The new image will be saved to a file called horizontalflip.gif
    • public void lighten(double amount) - takes as input a floating point number between 0 and 1 that indicates by how much the image should be lightened. For each pixel, it will set its new red value to be (1-amount)oldred + amount*255, doing the same for green and blue. The new image will be saved to a file lighter.gif.
    • public void darken(double amount) - takes as input a floating point number between 0 and 1 that indicates by how much the image should be darkened. For each pixel, it will set its new red value to be (1-amount)oldred, doing the same for green and blue. The new image will be saved to a file darker.gif.
  • Part 2 methods - due 3/6:
    • public void scrollHorizontal(int numpixels) - takes as input a number of pixels and scrolls the image by that amount horizontally. The image will be shifted to the left, and the leftmost numpixels will appear on the right side of the image. The new image will be saved to a file scrollhorizontal.gif.
    • public void scrollVertical(int numpixels) - takes as input a number of pixels and scrolls the image by that amount vertically. The image will be shifted up, and the topmost numpixels will appear on the bottom of the image. The new image will be saved to a file scrollvertical.gif.
    • public void makeGreyscale() - converts the image to "black and white" by setting the red, green, and blue value for each pixel to be 30% of the old red value + 59% of the old green value + 11% of the old blue value for that pixel (see: http://en.wikipedia.org/wiki/Grayscale). The new image will be saved to a file greyscale.gif.
    • public void rotate() - rotates the image clockwise by 90 degrees. The new image will be saved to a file rotate.gif.
    • public void swapCorners() - divides the image into four subsquares and moves the upper right to the bottom left and vice versa. The new image will be saved to a file cornerswap.gif.
    • public void blur() - blurs the image using the following algorithm: for each pixel, the red value will be set to the average of all red values in a 3x3 square surrounding the pixel, and the same for green and blue. The red value at position (3, 6) would be set to the average of the red values at (2, 5) (3, 5) (4, 5) (2, 6) (3, 6) (4, 6) (2, 7) (3, 7) (4, 7). Make sure to handle the case of a pixel at the edge of the image. The new image will be saved to a file blur.gif.
  • Extra credit options - due 3/6:
    • Note: all required methods above must be complete for extra credit to be awarded. It is advised that you speak with your instructor during office hours for more detail on how to implement these methods.
    • public void scaleLarger(int factor) - scales the image by making a larger image as specified by the parameter factor. If factor is 2, for example, the image will be doubled in size. The new image will be saved to a file scaled.gif. (2 points)
    • public void eightSquares() - divides the image into 9 subsquares and then reassigns 8 of those subsquares into random locations, as in http://www.cs.swarthmore.edu/~newhall/imagemanip/hw07figs/eight.jpg. The new image will be saved to a file eightsquares.gif. (2 points)
    • public void histogram() - creates a histogram of the R, G, and B pixel values. This method will print to standard output the results (in text format). (2 points)

Submitting the assignment



  • Submit the Java files and the README.txt file using SVN.
  • You can resubmit the assignment as many times as you want. It will upload a new copy of the files to the SVN repository. We will only grade the one that is closest to 11:59pm on the due date.