Lab 8
Get started now

Objectives

  • Employ both binary and text file input and output to read and write image files.
  • Implement software using multiple instances of inheritance.
  • Construct an interactive graphical user interface using event listeners and inner classes and/or lambda expressions.
  • Research and implement at least one event listener that is not an ActionListener.
  • Handle exceptions in a robust and meaningful fashion.

Overview

In this assignment you will be developing an image manipulation program. The program itself will be capable of reading and writing in multiple image formats including .bmp, .jpg, .png, and .ppm files. The program will also be capable to apply simple transformations to the image like:

  • Converting the image to grayscale
  • Producing the negative of the original image

Assignment

This is the last laboratory assignment for the quarter and is partitioned into multiple parts. Specific deliverables are given for two weeks. Your instructor will set the requirements for any additional deliverables. The assignment has been designed to provide numerous ways in which the program may be expanded. Students are encouraged to use their creativity to implement additional functionality beyond the requirements of the assignment; however, it is important to complete the required functionality before getting too carried away.

User Interface

Week 8 Summary

In the first week you must implement the following functionality:

  • Load and reload images stored in the following image file formats: .jpg, .png, and .ppm.
  • Display the image that has been loaded
  • Write images in the following image file formats: .jpg, .png, and .ppm. The format written must match the file extension. For example, if the current picture was loaded from a .jpg file and the user enters image.png, the image must be saved in the .png file format.
  • Use JFileChoosers to select the image file to load and save.
  • The appropriate graphical user interface to support the operations listed above.

Your program should be able to load this PPM image.

Week 9 Summary

In the second week you must implement the following functionality:

  • Load and write images in the .bmp file format.
  • Apply the following transforms to the current picture:
    • Make grayscale version of picture
    • Make red-channel version of picture (removes green and blue channels)
    • Make negative version of the picture
    • Make red-gray version of the picture
  • The appropriate graphical user interface to support the operations listed above.

Details

Loading and Saving Images

At a minimum, the program must support loading and saving .bmp, .jpg, .png, and .ppm image file formats. The load button will open a JFileChooser dialog that will allow the user to select the file to be loaded. The program will use the extension to determine the format of the file and load the image (provided the extension type is supported). Pressing the reload button will reload the last loaded image from the file system.

The save button will function in a similar manner. When the user presses the save button, a JFileChooser dialog box will open allowing the user to select the destination folder and type in the filename and extension. The program will then write the image to that file using the file format that matches the file extension. If an unsupported file extension is entered, the program will display an error message without attempting to save the image.

You may use the javax.imageio.ImageIO class to read and write files in the .jpg and .png formats. You must implement your own code for reading and writing .ppm files. In particular, you are required to implement the ASCII version ("P3") of the Portable PixMap (PPM) format. Good documentation for the format is available here. Note: when creating a BufferedImage you should use the BufferedImage.TYPE_INT_RGB type.

Similarly, you must implement your own code for reading and writing .bmp files. The BMP format is significantly more complicated than the PPM format (details). It's evident from the BMP description that the header information for these files is considerably more involved than the header information for PPM files. Also, BMP files are stored as binary files. As a result, the code to read and write BMP files is more challenging to write than the code for the PPM files.

You are encouraged to use the provided BMPPicture class (BMPPicture.java) as a starting point. The file contains a partial implementation and detailed comments to help guide your implementation.

Your program should be able to load this BMP image.

Image Transformations

The program will support a number of image transformations.

Grayscale

This transformation converts the image into a grayscale image. If the image is already grayscale, the transformation has no affect. In this transformation, the RGB components of each pixel are replaced with a single value. The replacement value is calculated as: gray = 0.2126R + 0.7152G + 0.0722B (more info).

Grayscale Transform

Negative

This transformation converts the image into a negative image of the original. In this transform, each RGB component is replaced with 255 - original value. Thus, an RGB value of (255, 255, 0) would become (0, 0, 255). (more info).

Negative Transform

Red Only

This transformation acts as a red filter. The green and blue components of each pixel are set to zero.

Red Only Transform

Red-Gray

This transformation is based on an experiment demonstrated by Edwin Land, founder of Polaroid, in 1959 (more info). The experiment was based on the Retinex Theory of Color Vision. This page has a nice explanation of the experiment and the Retinex theory. The transform is quite simple: perform a Grayscale transformation on the pixels in alternating rows and perform a Red Only transformation on the pixels in the other rows.1)

Red-Gray Transform

Class Structure

Extensive javadoc for the classes you are required to implement is available. The Pixel class, which you will use frequently has been provided (Pixel.java).

The remaining class structure that your program must adhere to is shown in the figure below. Classes above the line must be implemented in order to complete the week 8 requirements. Classes below the line must be implemented in order to complete the week 9 requirements.

The Picture class is an abstract class which serves as the basis for the specific picture classes that represent various image formats.

The PixelManipulator interface provides the basis for building specific transforms. The various transform classes are used by the ImageTransform class to perform the appropriate transformation on the image.

The user interface is implemented entirely in the ImageViewer class. This includes all of the UI components as well as event handlers. You may implement the event handlers as inner classes, anonymous inner classes, or lambda expressions.

Exception Handling

There are a number of situations that could cause your program to throw an exception. For example, if the file is not found, cannot be opened, or contains incorrectly formatted data, it is likely that an exception will be thrown. In these cases, the program should display an appropriate JOptionPane dialog and log the error.

Your program should write to the log file ImageExceptions.txt.

Beyond week 9

Your instructor may have specific additional requirements; however, all students must implement a feature that makes use of and event listener other than an ActionListener. For example, you could use a listener to:

  • allow you to draw on the image with the mouse
  • display the x, y coordinates of the location of the mouse on the image
  • play a sound when clicking on a pixel with a particular color
  • flip back and forth between the image and its negative whenever the window is minimized
  • select a region of the image

Extras

There are many additional enhancements that could build on the required functionality. You are encouraged to enhance this application using your creativity. A number of enhancements are included below; however, you should not feel limited to these suggestions.

  • Add a menu to the JFrame to replace (or in addition to) the buttons
  • Use a JColorChooser to pick a color (could be used in conjunction with drawing on the image or playing a sound when a particular color is clicked)
  • Apply a transform to only a selected region of the image
  • Display original image and transformed image side-by-side
  • Toggle between original and transformed image when mouse button is pressed on the image
  • Tonal adjustment (e.g., adding a red hue to the image underneath the mouse)
  • Provide undo functionality
  • Implement additional transformations
  • Apply filters (see here)

Lab Deliverables

See your professor's instructions for details on submission guidelines and due dates.
Dr. Dennis' students: See Blackboard
See Dr. Rebenitsch for instructions
Dr. Taylor's students: See below
See Prof. Ung for instructions
If you have any questions, consult your instructor.

Acknowledgment

This laboratory assignment was developed by Dr. Walter Schilling and Dr. Chris Taylor.

1) This is a slight simplification from the actual transformation. You may chose to implement the actual transformation, if you choose to (you'll need to look it up). Be sure to indicate with a comment if you choose to do this.

Tuesday, 10-Jan-2017 00:00:29 EST