In this assignment we continue to explore image
processing. Unless otherwise noted, everything that said about
the first part of the assignment applies to this part, too.
Part 2: An Image Viewer and Transformer -- Turn
in files here.
In Part One you read data from an input stream and saved it within
IImage objects. You used an external program, such as IrFanView,
to render the file as an image on the screen. Now that you know
something about graphics and drawing in Java, you can create your own
viewer.When you wrote the produceTimesTwo method, you were producing one image from another. Such an operation can be called a "filter". Filters can be imagined to transform images for a wide variety of artistic and practical reasons.
The application you build in Part Two will have a window showing some buttons and two panels where images can be displayed. The buttons cause file operations or image filters to take place. Two required operations are "Load File" and "Save File" (your code from the IImageProcessor is called for this.) Other buttons invoke filters. A filter takes the image from the left-hand panel, transforms it, and displays the output image in the right-hand panel. Don't panic about the buttons or about event handlers! All that code is supplied. Your focus is on displaying and filtering images.
Your Task
Create a Java application with a graphical interface, which can view and filter images. A framework for the application is provided by the classes listed below. Aside from understanding how it fits together, your main job will be implementing ImagePanel and the IImageFilter classes.ImageFrame.java (supplied, but you can modify): a frame with image panels and a row of buttons. You may modify this class to improve the appearance if you wish, but you should not make any substantive changes.
ImageButtonPanel.java (supplied, not modifiable): a panel holding buttons to activate the image operations. This panel is displayed on the Image Frame. When it is constructed, it will be given references to the objects (your classes) that actually perform the operations.
ImagePanel.java (you create from scratch): This extension of AbstractImagePanel.java (supplied; the abstract class already extends JPanel) is capable of displaying an IImage object. Much of your hard work in this project will be the writing and debugging of this class. In addition to JPanel methods, ImagePanel has public methods getImage and setImage, specified by the abstract class. The image, as displayed, should be a recognizable rendering of the original image, although the rendering doesn't have to be exactly what IrFanView would present. The main idea is to draw small Shapes of appropriate size, position, and color to correspond to the pixels in the image being rendered. (Don't overlook opportunities for creativity and experimentation here. The shapes don't have to be rectangles or ovals...) It is not necessary to strictly preserve the original size or aspect ratio (width/height) ratio, although a professional image viewer would have that capability.
Image Filters (you create; more about this below): An image filter satisfies the IImageFilter interface (supplied). It takes an image and produces another image from it. You should write a number of these filter classes and supply them to the ImageFrame (i.e., in ImageApplication when the frame is created). They will then be available on the Image Frame as buttons. Note: making the filters show up as buttons is automatic and won't take any changes by you to either the filter or the panel classes.
ImageApplication.java (you create or modify): A very small class, whose main method creates the ImageFrame. In doing so, it should supply all of the required and optional filters. A sample of this class is supplied, which you will need to modify.
Image
PGMImage, PPMImage (you created): If these worked properly in the earlier part of the project, you should not need to modify them.
JUnit test cases: no requirement this time.
Image Filters
Each image filter is a separate class, and must implement the
IImageFilter interface. The filter should take a valid image and
produce a new valid image from it. Read the comments in the
code for
more information."Doubler" (required): produces an image with pixels duplicated in both directions. The produceTimesTwo code you wrote in Image
"Copier" (required): produce an image that is identical to the original (but is not the same object).
"Lightener" (required): produce an image identical to the original except that the pixels are all slightly lighter in color. If you applied this filter to its output repeatedly, the output would eventually be all white.
And in addition: Think up and implement at least 2 filters of your own. Try to be imaginative. Although there's no extra credit for insane creativity, we will somehow show off the filters so that people inside and outside the class can appreciate them.
Written reports
1. A written report along the usual lines, prepared by you and your partner together.
2. A diagram showing the relationships of all the classes used in the project (whether your own code, supplied code, libraries, etc.). You may omit classes used by ImageButtonPanel from this analysis. This will be a rather large diagram, so don't leave it to the last minute. In fact, doing it before writing any code will help you to understand the project!
3. A confidential, printed report, one per person, which describes the extent and nature of your individual contributions to the project.
Getting Started
1. Think of a short nickname for your team. This will be useful in naming your image filter classes so that names are unique.2. Browse through all of the supplied code.
3. Consider doing the class diagram first (see "written reports" section).
4. As a warm-up, write a small application which paints an ellipse on a panel, right in the middle, and touching all four sides (or nearly). Then make it so that if you resize the window, the ellipse is automatically redrawn properly (no, this doesn NOT require knowing anything about events!). Then draw (four) equal-sized ellipses to fill the screen. Figuring out how to position and scale shapes, as well as how to draw them, is an essential part of getting the ImagePanel to work, so this exercise is highly recommended.
Turn in (by 7/28 at 9:00pm, one per team):
- PPMImage.java, PGMImage,
ImageProcessorsImageProcessor.java (even if the same as last time), with these exact names.
- ImageApplication.java, ImageFrame.java (even if unmodified), with these exact names
- ImagePanel.java. This exact name is recommended.
- The Doubler, Copier, and Lightener image filter classes. They can have any name, but choose names that identify them easily.
- Two or more additional filters, named appropriately. In
order to make it easy to share and demonstrate filters, it would nice
if each such class handed in had a different name. To facilitate
this, you can give your filters names that start with your team
nickname. For example, a team named "Pixar" might name a filter
class "PixarReddenFilter.java".
- Screenshots: one showing a simple image and the result of
doubling it; one each for your own filters, showing the original image
and the filtered image. Write the name of the filter on each
snapshot.
1 image you created by hand.- (A thorough 1 page technical detailing the design decisions made
in
you project and other details of you implementation -- make this part
of the written report mentioned earlier).
- Turn in any paperwork (written reports, screen snapshots, etc.) in class on the day following the electronic turn-in. One copy per team, and make sure both your names are on each piece of paper and staple everything together (except the individual reports, which should be handled separately and folded for confidentiality).