first commit

This commit is contained in:
Boris
2024-01-15 20:14:10 +00:00
commit 8c81ee28b7
3106 changed files with 474415 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

View File

@@ -0,0 +1,5 @@
#BlueJ class context
comment0.params=name
comment0.target=DarkerFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ DarkerFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
numComments=1

View File

@@ -0,0 +1,33 @@
/**
* An image filter to make the image a bit darker.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class DarkerFilter extends Filter
{
/**
* Constructor for objects of class DarkerFilter.
* @param name The name of the filter.
*/
public DarkerFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
image.setPixel(x, y, image.getPixel(x, y).darker());
}
}
}
}

View File

@@ -0,0 +1,20 @@
#BlueJ class context
comment0.params=name
comment0.target=EdgeFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ EdgeFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
comment1.params=image
comment1.target=void\ apply(OFImage)
comment1.text=\n\ Apply\ this\ filter\ to\ an\ image.\n\ \n\ @param\ \ image\ \ The\ image\ to\ be\ changed\ by\ this\ filter.\n
comment2.params=xpos\ ypos
comment2.target=java.awt.Color\ edge(int,\ int)
comment2.text=\n\ Return\ a\ new\ color\ that\ is\ the\ smoothed\ color\ of\ a\ given\n\ position.\ The\ "smoothed\ color"\ is\ the\ color\ value\ that\ is\ the\n\ average\ of\ this\ pixel\ and\ all\ the\ adjacent\ pixels.\n\ @param\ xpos\ The\ x\ position\ of\ the\ pixel.\n\ @param\ ypos\ The\ y\ position\ of\ the\ pixel.\n\ @return\ The\ smoothed\ color.\n
comment3.params=pixels
comment3.target=int\ diffRed(java.util.List)
comment3.text=\n\ @param\ pixels\ The\ list\ of\ pixels\ to\ be\ averaged.\n\ @return\ The\ average\ of\ all\ the\ red\ values\ in\ the\ given\ list\ of\ pixels.\n
comment4.params=pixels
comment4.target=int\ diffGreen(java.util.List)
comment4.text=\n\ @param\ pixels\ The\ list\ of\ pixels\ to\ be\ averaged.\n\ @return\ The\ average\ of\ all\ the\ green\ values\ in\ the\ given\ list\ of\ pixels.\n
comment5.params=pixels
comment5.target=int\ diffBlue(java.util.List)
comment5.text=\n\ @param\ pixels\ The\ list\ of\ pixels\ to\ be\ averaged.\n\ @return\ The\ average\ of\ all\ the\ blue\ values\ in\ the\ given\ list\ of\ pixels.\n
numComments=6

View File

@@ -0,0 +1,143 @@
import java.awt.Color;
import java.util.List;
import java.util.ArrayList;
/**
* An image filter to detect edges and highlight them, a bit like
* a colored pencil drawing.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class EdgeFilter extends Filter
{
private static final int TOLERANCE = 20;
private OFImage original;
private int width;
private int height;
/**
* Constructor for objects of class EdgeFilter.
* @param name The name of the filter.
*/
public EdgeFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
original = new OFImage(image);
width = original.getWidth();
height = original.getHeight();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
image.setPixel(x, y, edge(x, y));
}
}
}
/**
* Return a new color that is the smoothed color of a given
* position. The "smoothed color" is the color value that is the
* average of this pixel and all the adjacent pixels.
* @param xpos The x position of the pixel.
* @param ypos The y position of the pixel.
* @return The smoothed color.
*/
private Color edge(int xpos, int ypos)
{
List<Color> pixels = new ArrayList<>(9);
for(int y = ypos-1; y <= ypos+1; y++) {
for(int x = xpos-1; x <= xpos+1; x++) {
if( x >= 0 && x < width && y >= 0 && y < height ) {
pixels.add(original.getPixel(x, y));
}
}
}
return new Color(255 - diffRed(pixels), 255 - diffGreen(pixels), 255 - diffBlue(pixels));
}
/**
* @param pixels The list of pixels to be averaged.
* @return The average of all the red values in the given list of pixels.
*/
private int diffRed(List<Color> pixels)
{
int max = 0;
int min = 255;
for(Color color : pixels) {
int val = color.getRed();
if(val > max) {
max = val;
}
if(val < min) {
min = val;
}
}
int difference = max - min - TOLERANCE;
if(difference < 0) {
difference = 0;
}
return difference;
}
/**
* @param pixels The list of pixels to be averaged.
* @return The average of all the green values in the given list of pixels.
*/
private int diffGreen(List<Color> pixels)
{
int max = 0;
int min = 255;
for(Color color : pixels) {
int val = color.getGreen();
if(val > max) {
max = val;
}
if(val < min) {
min = val;
}
}
int difference = max - min - TOLERANCE;
if(difference < 0) {
difference = 0;
}
return difference;
}
/**
* @param pixels The list of pixels to be averaged.
* @return The average of all the blue values in the given list of pixels.
*/
private int diffBlue(List<Color> pixels)
{
int max = 0;
int min = 255;
for(Color color : pixels) {
int val = color.getBlue();
if(val > max) {
max = val;
}
if(val < min) {
min = val;
}
}
int difference = max - min - TOLERANCE;
if(difference < 0) {
difference = 0;
}
return difference;
}
}

View File

@@ -0,0 +1,8 @@
#BlueJ class context
comment0.params=name
comment0.target=Filter(java.lang.String)
comment0.text=\n\ Create\ a\ new\ filter\ with\ a\ given\ name.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
comment1.params=
comment1.target=java.lang.String\ getName()
comment1.text=\n\ Return\ the\ name\ of\ this\ filter.\n\ \n\ @return\ \ The\ name\ of\ this\ filter.\n
numComments=2

View File

@@ -0,0 +1,38 @@
/**
* Filter is an abstract superclass for all image filters in this
* application. Filters can be applied to OFImages by invoking the apply
* method.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public abstract class Filter
{
private String name;
/**
* Create a new filter with a given name.
* @param name The name of the filter.
*/
public Filter(String name)
{
this.name = name;
}
/**
* Return the name of this filter.
*
* @return The name of this filter.
*/
public String getName()
{
return name;
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public abstract void apply(OFImage image);
}

View File

@@ -0,0 +1,11 @@
#BlueJ class context
comment0.params=name
comment0.target=FishEyeFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ LensFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
comment1.params=width
comment1.target=int[]\ computeXArray(int)
comment1.text=\n\ Compute\ and\ return\ an\ array\ of\ horizontal\ offsets\ for\ each\ pixel\ column.\n\ These\ can\ then\ be\ applied\ as\ the\ horizontal\ offset\ for\ each\ pixel.\n
comment2.params=height
comment2.target=int[]\ computeYArray(int)
comment2.text=\n\ Compute\ and\ return\ an\ array\ of\ vertical\ offsets\ for\ each\ pixel\ row.\n\ These\ can\ then\ be\ applied\ as\ the\ vertical\ offset\ for\ each\ pixel.\n
numComments=3

View File

@@ -0,0 +1,73 @@
import java.awt.Color;
/**
* An image filter to create an effect similar to a fisheye camera lens.
* (Works especially well on portraits.)
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class FishEyeFilter extends Filter
{
// constants:
private final static int SCALE = 20; // this defines the strenght of the filter
private final static double TWO_PI = 2 * Math.PI;
/**
* Constructor for objects of class LensFilter.
* @param name The name of the filter.
*/
public FishEyeFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
OFImage original = new OFImage(image);
int[] xa = computeXArray(width);
int[] ya = computeYArray(height);
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
image.setPixel(x, y, original.getPixel(x + xa[x], y + ya[y]));
}
}
}
/**
* Compute and return an array of horizontal offsets for each pixel column.
* These can then be applied as the horizontal offset for each pixel.
*/
private int[] computeXArray(int width)
{
int[] xArray = new int[width];
for(int i=0; i < width; i++) {
xArray[i] = (int)(Math.sin( ((double)i / width) * TWO_PI) * SCALE);
}
return xArray;
}
/**
* Compute and return an array of vertical offsets for each pixel row.
* These can then be applied as the vertical offset for each pixel.
*/
private int[] computeYArray(int height)
{
int[] yArray = new int[height];
for(int i=0; i < height; i++) {
yArray[i] = (int)(Math.sin( ((double)i / height) * TWO_PI) * SCALE);
}
return yArray;
}
}

View File

@@ -0,0 +1,5 @@
#BlueJ class context
comment0.params=name
comment0.target=GrayScaleFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ GrayScaleFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
numComments=1

View File

@@ -0,0 +1,37 @@
import java.awt.Color;
/**
* An image filter to remove color from an image.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class GrayScaleFilter extends Filter
{
/**
* Constructor for objects of class GrayScaleFilter.
* @param name The name of the filter.
*/
public GrayScaleFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
Color pix = image.getPixel(x, y);
int avg = (pix.getRed() + pix.getGreen() + pix.getBlue()) / 3;
image.setPixel(x, y, new Color(avg, avg, avg));
}
}
}
}

View File

@@ -0,0 +1,8 @@
#BlueJ class context
comment0.params=imageFile
comment0.target=OFImage\ loadImage(java.io.File)
comment0.text=\n\ Read\ an\ image\ file\ from\ disk\ and\ return\ it\ as\ an\ image.\ This\ method\n\ can\ read\ JPG\ and\ PNG\ file\ formats.\ In\ case\ of\ any\ problem\ (e.g\ the\ file\ \n\ does\ not\ exist,\ is\ in\ an\ undecodable\ format,\ or\ any\ other\ read\ error)\ \n\ this\ method\ returns\ null.\n\ \n\ @param\ imageFile\ \ The\ image\ file\ to\ be\ loaded.\n\ @return\ \ \ \ \ \ \ \ \ \ \ The\ image\ object\ or\ null\ if\ it\ could\ not\ be\ read.\n
comment1.params=image\ file
comment1.target=void\ saveImage(OFImage,\ java.io.File)
comment1.text=\n\ Write\ an\ image\ file\ to\ disk.\ The\ file\ format\ is\ JPG.\ In\ case\ of\ any\ \n\ problem\ the\ method\ just\ silently\ returns.\n\ \n\ @param\ image\ \ The\ image\ to\ be\ saved.\n\ @param\ file\ \ \ The\ file\ to\ save\ to.\n
numComments=2

View File

@@ -0,0 +1,61 @@
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
/**
* ImageFileManager is a small utility class with static methods to load
* and save images.
*
* The files on disk can be in JPG or PNG image format. For files written
* by this class, the format is determined by the constant IMAGE_FORMAT.
*
* @author Michael Kölling and David J. Barnes.
* @version 2.0
*/
public class ImageFileManager
{
// A constant for the image format that this writer uses for writing.
// Available formats are "jpg" and "png".
private static final String IMAGE_FORMAT = "jpg";
/**
* Read an image file from disk and return it as an image. This method
* can read JPG and PNG file formats. In case of any problem (e.g the file
* does not exist, is in an undecodable format, or any other read error)
* this method returns null.
*
* @param imageFile The image file to be loaded.
* @return The image object or null if it could not be read.
*/
public static OFImage loadImage(File imageFile)
{
try {
BufferedImage image = ImageIO.read(imageFile);
if(image == null || (image.getWidth(null) < 0)) {
// we could not load the image - probably invalid file format
return null;
}
return new OFImage(image);
}
catch(IOException exc) {
return null;
}
}
/**
* Write an image file to disk. The file format is JPG. In case of any
* problem the method just silently returns.
*
* @param image The image to be saved.
* @param file The file to save to.
*/
public static void saveImage(OFImage image, File file)
{
try {
ImageIO.write(image, IMAGE_FORMAT, file);
}
catch(IOException exc) {
return;
}
}
}

View File

@@ -0,0 +1,14 @@
#BlueJ class context
comment0.params=
comment0.target=ImagePanel()
comment0.text=\n\ Create\ a\ new,\ empty\ ImagePanel.\n
comment1.params=
comment1.target=void\ clearImage()
comment1.text=\n\ Clear\ the\ image\ on\ this\ panel.\n
comment2.params=
comment2.target=java.awt.Dimension\ getPreferredSize()
comment2.text=\n\ Tell\ the\ layout\ manager\ how\ big\ we\ would\ like\ to\ be.\n\ (This\ method\ gets\ called\ by\ layout\ managers\ for\ placing\n\ the\ components.)\n\ \n\ @return\ The\ preferred\ dimension\ for\ this\ component.\n
comment3.params=g
comment3.target=void\ paintComponent(java.awt.Graphics)
comment3.text=\n\ This\ component\ needs\ to\ be\ redisplayed.\ Copy\ the\ internal\ image\ \n\ to\ screen.\ (This\ method\ gets\ called\ by\ the\ Swing\ screen\ painter\ \n\ every\ time\ it\ want\ this\ component\ displayed.)\n\ \n\ @param\ g\ The\ graphics\ context\ that\ can\ be\ used\ to\ draw\ on\ this\ component.\n
numComments=4

View File

@@ -0,0 +1,89 @@
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
/**
* An ImagePanel is a Swing component that can display an OFImage.
* It is constructed as a subclass of JComponent with the added functionality
* of setting an OFImage that will be displayed on the surface of this
* component.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class ImagePanel extends JComponent
{
// The current width and height of this panel
private int width, height;
// An internal image buffer that is used for painting. For
// actual display, this image buffer is then copied to screen.
private OFImage panelImage;
/**
* Create a new, empty ImagePanel.
*/
public ImagePanel()
{
width = 360; // arbitrary size for empty panel
height = 240;
panelImage = null;
}
/**
* Set the image that this panel should show.
*
* @param image The image to be displayed.
*/
public void setImage(OFImage image)
{
if(image != null) {
width = image.getWidth();
height = image.getHeight();
panelImage = image;
repaint();
}
}
/**
* Clear the image on this panel.
*/
public void clearImage()
{
Graphics imageGraphics = panelImage.getGraphics();
imageGraphics.setColor(Color.LIGHT_GRAY);
imageGraphics.fillRect(0, 0, width, height);
repaint();
}
// The following methods are redefinitions of methods
// inherited from superclasses.
/**
* Tell the layout manager how big we would like to be.
* (This method gets called by layout managers for placing
* the components.)
*
* @return The preferred dimension for this component.
*/
public Dimension getPreferredSize()
{
return new Dimension(width, height);
}
/**
* This component needs to be redisplayed. Copy the internal image
* to screen. (This method gets called by the Swing screen painter
* every time it want this component displayed.)
*
* @param g The graphics context that can be used to draw on this component.
*/
public void paintComponent(Graphics g)
{
Dimension size = getSize();
g.clearRect(0, 0, size.width, size.height);
if(panelImage != null) {
g.drawImage(panelImage, 0, 0, null);
}
}
}

View File

@@ -0,0 +1,47 @@
#BlueJ class context
comment0.params=
comment0.target=ImageViewer()
comment0.text=\n\ Create\ an\ ImageViewer\ and\ display\ its\ GUI\ on\ screen.\n
comment1.params=
comment1.target=void\ openFile()
comment1.text=\n\ Open\ function\:\ open\ a\ file\ chooser\ to\ select\ a\ new\ image\ file,\n\ and\ then\ display\ the\ chosen\ image.\n
comment10.params=text
comment10.target=void\ showStatus(java.lang.String)
comment10.text=\n\ Show\ a\ message\ in\ the\ status\ bar\ at\ the\ bottom\ of\ the\ screen.\n\ @param\ text\ The\ status\ message.\n
comment11.params=status
comment11.target=void\ setButtonsEnabled(boolean)
comment11.text=\n\ Enable\ or\ disable\ all\ toolbar\ buttons.\n\ \n\ @param\ status\ \ 'true'\ to\ enable\ the\ buttons,\ 'false'\ to\ disable.\n
comment12.params=
comment12.target=java.util.List\ createFilters()
comment12.text=\n\ Create\ a\ list\ with\ all\ the\ known\ filters.\n\ @return\ The\ list\ of\ filters.\n
comment13.params=
comment13.target=void\ makeFrame()
comment13.text=\n\ Create\ the\ Swing\ frame\ and\ its\ content.\n
comment14.params=frame
comment14.target=void\ makeMenuBar(javax.swing.JFrame)
comment14.text=\n\ Create\ the\ main\ frame's\ menu\ bar.\n\ \n\ @param\ frame\ \ \ The\ frame\ that\ the\ menu\ bar\ should\ be\ added\ to.\n
comment2.params=
comment2.target=void\ close()
comment2.text=\n\ Close\ function\:\ close\ the\ current\ image.\n
comment3.params=
comment3.target=void\ saveAs()
comment3.text=\n\ Save\ As\ function\:\ save\ the\ current\ image\ to\ a\ file.\n
comment4.params=
comment4.target=void\ quit()
comment4.text=\n\ Quit\ function\:\ quit\ the\ application.\n
comment5.params=filter
comment5.target=void\ applyFilter(Filter)
comment5.text=\n\ Apply\ a\ given\ filter\ to\ the\ current\ image.\n\ \n\ @param\ filter\ \ \ The\ filter\ object\ to\ be\ applied.\n
comment6.params=
comment6.target=void\ showAbout()
comment6.text=\n\ 'About'\ function\:\ show\ the\ 'about'\ box.\n
comment7.params=
comment7.target=void\ makeLarger()
comment7.text=\n\ Make\ the\ current\ picture\ larger.\n
comment8.params=
comment8.target=void\ makeSmaller()
comment8.text=\n\ Make\ the\ current\ picture\ smaller.\n
comment9.params=filename
comment9.target=void\ showFilename(java.lang.String)
comment9.text=\n\ Show\ the\ file\ name\ of\ the\ current\ image\ in\ the\ fils\ display\ label.\n\ 'null'\ may\ be\ used\ as\ a\ parameter\ if\ no\ file\ is\ currently\ loaded.\n\ \n\ @param\ filename\ \ The\ file\ name\ to\ be\ displayed,\ or\ null\ for\ 'no\ file'.\n
numComments=15

View File

@@ -0,0 +1,381 @@
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.*;
import java.io.File;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
/**
* ImageViewer is the main class of the image viewer application. It builds and
* displays the application GUI and initialises all other components.
*
* To start the application, create an object of this class.
*
* @author Michael Kölling and David J. Barnes.
* @version 3.1
*/
public class ImageViewer
{
// static fields:
private static final String VERSION = "Version 3.1";
private static JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));
// fields:
private JFrame frame;
private ImagePanel imagePanel;
private JLabel filenameLabel;
private JLabel statusLabel;
private JButton smallerButton;
private JButton largerButton;
private OFImage currentImage;
private List<Filter> filters;
/**
* Create an ImageViewer and display its GUI on screen.
*/
public ImageViewer()
{
currentImage = null;
filters = createFilters();
makeFrame();
}
// ---- implementation of menu functions ----
/**
* Open function: open a file chooser to select a new image file,
* and then display the chosen image.
*/
private void openFile()
{
int returnVal = fileChooser.showOpenDialog(frame);
if(returnVal != JFileChooser.APPROVE_OPTION) {
return; // cancelled
}
File selectedFile = fileChooser.getSelectedFile();
currentImage = ImageFileManager.loadImage(selectedFile);
if(currentImage == null) { // image file was not a valid image
JOptionPane.showMessageDialog(frame,
"The file was not in a recognized image file format.",
"Image Load Error",
JOptionPane.ERROR_MESSAGE);
return;
}
imagePanel.setImage(currentImage);
setButtonsEnabled(true);
showFilename(selectedFile.getPath());
showStatus("File loaded.");
frame.pack();
}
/**
* Close function: close the current image.
*/
private void close()
{
currentImage = null;
imagePanel.clearImage();
showFilename(null);
setButtonsEnabled(false);
}
/**
* Save As function: save the current image to a file.
*/
private void saveAs()
{
if(currentImage != null) {
int returnVal = fileChooser.showSaveDialog(frame);
if(returnVal != JFileChooser.APPROVE_OPTION) {
return; // cancelled
}
File selectedFile = fileChooser.getSelectedFile();
ImageFileManager.saveImage(currentImage, selectedFile);
showFilename(selectedFile.getPath());
}
}
/**
* Quit function: quit the application.
*/
private void quit()
{
System.exit(0);
}
/**
* Apply a given filter to the current image.
*
* @param filter The filter object to be applied.
*/
private void applyFilter(Filter filter)
{
if(currentImage != null) {
filter.apply(currentImage);
frame.repaint();
showStatus("Applied: " + filter.getName());
}
else {
showStatus("No image loaded.");
}
}
/**
* 'About' function: show the 'about' box.
*/
private void showAbout()
{
JOptionPane.showMessageDialog(frame,
"ImageViewer\n" + VERSION,
"About ImageViewer",
JOptionPane.INFORMATION_MESSAGE);
}
/**
* Make the current picture larger.
*/
private void makeLarger()
{
if(currentImage != null) {
// create new image with double size
int width = currentImage.getWidth();
int height = currentImage.getHeight();
OFImage newImage = new OFImage(width * 2, height * 2);
// copy pixel data into new image
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
Color col = currentImage.getPixel(x, y);
newImage.setPixel(x * 2, y * 2, col);
newImage.setPixel(x * 2 + 1, y * 2, col);
newImage.setPixel(x * 2, y * 2 + 1, col);
newImage.setPixel(x * 2+1, y * 2 + 1, col);
}
}
currentImage = newImage;
imagePanel.setImage(currentImage);
frame.pack();
}
}
/**
* Make the current picture smaller.
*/
private void makeSmaller()
{
if(currentImage != null) {
// create new image with double size
int width = currentImage.getWidth() / 2;
int height = currentImage.getHeight() / 2;
OFImage newImage = new OFImage(width, height);
// copy pixel data into new image
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
newImage.setPixel(x, y, currentImage.getPixel(x * 2, y * 2));
}
}
currentImage = newImage;
imagePanel.setImage(currentImage);
frame.pack();
}
}
// ---- support methods ----
/**
* Show the file name of the current image in the fils display label.
* 'null' may be used as a parameter if no file is currently loaded.
*
* @param filename The file name to be displayed, or null for 'no file'.
*/
private void showFilename(String filename)
{
if(filename == null) {
filenameLabel.setText("No file displayed.");
}
else {
filenameLabel.setText("File: " + filename);
}
}
/**
* Show a message in the status bar at the bottom of the screen.
* @param text The status message.
*/
private void showStatus(String text)
{
statusLabel.setText(text);
}
/**
* Enable or disable all toolbar buttons.
*
* @param status 'true' to enable the buttons, 'false' to disable.
*/
private void setButtonsEnabled(boolean status)
{
smallerButton.setEnabled(status);
largerButton.setEnabled(status);
}
/**
* Create a list with all the known filters.
* @return The list of filters.
*/
private List<Filter> createFilters()
{
List<Filter> filterList = new ArrayList<>();
filterList.add(new DarkerFilter("Darker"));
filterList.add(new LighterFilter("Lighter"));
filterList.add(new ThresholdFilter("Threshold"));
filterList.add(new InvertFilter("Invert"));
filterList.add(new SolarizeFilter("Solarize"));
filterList.add(new SmoothFilter("Smooth"));
filterList.add(new PixelizeFilter("Pixelize"));
filterList.add(new MirrorFilter("Mirror"));
filterList.add(new GrayScaleFilter("Grayscale"));
filterList.add(new EdgeFilter("Edge Detection"));
filterList.add(new FishEyeFilter("Fish Eye"));
return filterList;
}
// ---- Swing stuff to build the frame and all its components and menus ----
/**
* Create the Swing frame and its content.
*/
private void makeFrame()
{
frame = new JFrame("ImageViewer");
JPanel contentPane = (JPanel)frame.getContentPane();
contentPane.setBorder(new EmptyBorder(12, 12, 12, 12));
makeMenuBar(frame);
// Specify the layout manager with nice spacing
contentPane.setLayout(new BorderLayout(6, 6));
// Create the image pane in the center
imagePanel = new ImagePanel();
imagePanel.setBorder(new EtchedBorder());
contentPane.add(imagePanel, BorderLayout.CENTER);
// Create two labels at top and bottom for the file name and status messages
filenameLabel = new JLabel();
contentPane.add(filenameLabel, BorderLayout.NORTH);
statusLabel = new JLabel(VERSION);
contentPane.add(statusLabel, BorderLayout.SOUTH);
// Create the toolbar with the buttons
JPanel toolbar = new JPanel();
toolbar.setLayout(new GridLayout(0, 1));
smallerButton = new JButton("Smaller");
smallerButton.addActionListener(e -> makeSmaller());
toolbar.add(smallerButton);
largerButton = new JButton("Larger");
largerButton.addActionListener(e -> makeLarger());
toolbar.add(largerButton);
// Add toolbar into panel with flow layout for spacing
JPanel flow = new JPanel();
flow.add(toolbar);
contentPane.add(flow, BorderLayout.WEST);
// building is done - arrange the components
showFilename(null);
setButtonsEnabled(false);
frame.pack();
// place the frame at the center of the screen and show
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);
frame.setVisible(true);
}
/**
* Create the main frame's menu bar.
*
* @param frame The frame that the menu bar should be added to.
*/
private void makeMenuBar(JFrame frame)
{
final int SHORTCUT_MASK =
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
JMenuBar menubar = new JMenuBar();
frame.setJMenuBar(menubar);
JMenu menu;
JMenuItem item;
// create the File menu
menu = new JMenu("File");
menubar.add(menu);
item = new JMenuItem("Open...");
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_MASK));
item.addActionListener(e -> openFile());
menu.add(item);
item = new JMenuItem("Close");
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, SHORTCUT_MASK));
item.addActionListener(e -> close());
menu.add(item);
menu.addSeparator();
item = new JMenuItem("Save As...");
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_MASK));
item.addActionListener(e -> saveAs());
menu.add(item);
menu.addSeparator();
item = new JMenuItem("Quit");
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));
item.addActionListener(e -> quit());
menu.add(item);
// create the Filter menu
menu = new JMenu("Filter");
menubar.add(menu);
for(Filter filter : filters) {
item = new JMenuItem(filter.getName());
item.addActionListener(e -> applyFilter(filter));
menu.add(item);
}
// create the Help menu
menu = new JMenu("Help");
menubar.add(menu);
item = new JMenuItem("About ImageViewer...");
item.addActionListener(e -> showAbout());
menu.add(item);
}
}

View File

@@ -0,0 +1,5 @@
#BlueJ class context
comment0.params=name
comment0.target=InvertFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ InvertFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
numComments=1

View File

@@ -0,0 +1,38 @@
import java.awt.Color;
/**
* An image filter to invert colors.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class InvertFilter extends Filter
{
/**
* Constructor for objects of class InvertFilter.
* @param name The name of the filter.
*/
public InvertFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
Color pix = image.getPixel(x, y);
image.setPixel(x, y, new Color(255 - pix.getRed(),
255 - pix.getGreen(),
255 - pix.getBlue()));
}
}
}
}

View File

@@ -0,0 +1,5 @@
#BlueJ class context
comment0.params=name
comment0.target=LighterFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ LighterFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
numComments=1

View File

@@ -0,0 +1,34 @@
/**
* An image filter to make the image a bit lighter.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class LighterFilter extends Filter
{
/**
* Constructor for objects of class LighterFilter.
* @param name The name of the filter.
*/
public LighterFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
image.setPixel(x, y, image.getPixel(x, y).brighter());
}
}
}
}

View File

@@ -0,0 +1,5 @@
#BlueJ class context
comment0.params=name
comment0.target=MirrorFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ MirrorFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
numComments=1

View File

@@ -0,0 +1,37 @@
import java.awt.Color;
/**
* An image filter to mirror (flip) the image horizontally.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class MirrorFilter extends Filter
{
/**
* Constructor for objects of class MirrorFilter.
* @param name The name of the filter.
*/
public MirrorFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width / 2; x++) {
Color left = image.getPixel(x, y);
image.setPixel(x, y, image.getPixel(width - 1 - x, y));
image.setPixel(width - 1 - x, y, left);
}
}
}
}

View File

@@ -0,0 +1,14 @@
#BlueJ class context
comment0.params=image
comment0.target=OFImage(java.awt.image.BufferedImage)
comment0.text=\n\ Create\ an\ OFImage\ copied\ from\ a\ BufferedImage.\n\ @param\ image\ The\ image\ to\ copy.\n
comment1.params=width\ height
comment1.target=OFImage(int,\ int)
comment1.text=\n\ Create\ an\ OFImage\ with\ specified\ size\ and\ unspecified\ content.\n\ @param\ width\ The\ width\ of\ the\ image.\n\ @param\ height\ The\ height\ of\ the\ image.\n
comment2.params=x\ y\ col
comment2.target=void\ setPixel(int,\ int,\ java.awt.Color)
comment2.text=\n\ Set\ a\ given\ pixel\ of\ this\ image\ to\ a\ specified\ color.\ The\n\ color\ is\ represented\ as\ an\ (r,g,b)\ value.\n\ @param\ x\ The\ x\ position\ of\ the\ pixel.\n\ @param\ y\ The\ y\ position\ of\ the\ pixel.\n\ @param\ col\ The\ color\ of\ the\ pixel.\n
comment3.params=x\ y
comment3.target=java.awt.Color\ getPixel(int,\ int)
comment3.text=\n\ Get\ the\ color\ value\ at\ a\ specified\ pixel\ position.\n\ @param\ x\ The\ x\ position\ of\ the\ pixel.\n\ @param\ y\ The\ y\ position\ of\ the\ pixel.\n\ @return\ The\ color\ of\ the\ pixel\ at\ the\ given\ position.\n
numComments=4

View File

@@ -0,0 +1,57 @@
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
/**
* OFImage is a class that defines an image in OF (Objects First) format.
*
* @author Michael Kölling and David J. Barnes.
* @version 2.0
*/
public class OFImage extends BufferedImage
{
/**
* Create an OFImage copied from a BufferedImage.
* @param image The image to copy.
*/
public OFImage(BufferedImage image)
{
super(image.getColorModel(), image.copyData(null),
image.isAlphaPremultiplied(), null);
}
/**
* Create an OFImage with specified size and unspecified content.
* @param width The width of the image.
* @param height The height of the image.
*/
public OFImage(int width, int height)
{
super(width, height, TYPE_INT_RGB);
}
/**
* Set a given pixel of this image to a specified color. The
* color is represented as an (r,g,b) value.
* @param x The x position of the pixel.
* @param y The y position of the pixel.
* @param col The color of the pixel.
*/
public void setPixel(int x, int y, Color col)
{
int pixel = col.getRGB();
setRGB(x, y, pixel);
}
/**
* Get the color value at a specified pixel position.
* @param x The x position of the pixel.
* @param y The y position of the pixel.
* @return The color of the pixel at the given position.
*/
public Color getPixel(int x, int y)
{
int pixel = getRGB(x, y);
return new Color(pixel);
}
}

View File

@@ -0,0 +1,5 @@
#BlueJ class context
comment0.params=name
comment0.target=PixelizeFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ PixelizeFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
numComments=1

View File

@@ -0,0 +1,44 @@
import java.awt.Color;
/**
* An image filter to create a pixelization effect, like an enlarged
* low-resolution digital image.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class PixelizeFilter extends Filter
{
/**
* Constructor for objects of class PixelizeFilter.
* @param name The name of the filter.
*/
public PixelizeFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
final int PIXEL_SIZE = 5;
int width = image.getWidth();
int height = image.getHeight();
for(int y = 0; y < height; y += PIXEL_SIZE) {
for(int x = 0; x < width; x += PIXEL_SIZE) {
Color pix = image.getPixel(x, y);
for(int dy = y; dy < y + PIXEL_SIZE; dy++) {
for(int dx = x; dx < x + PIXEL_SIZE; dx++) {
if( dx < width && dy < height )
image.setPixel(dx, dy, pix);
}
}
}
}
}
}

View File

@@ -0,0 +1,25 @@
Project "imageviewer-final" (version 3.1)
Authors: David Barnes and Michael Kölling
This project is part of the material for the book
Objects First with Java - A Practical Introduction using BlueJ
Sixth edition
David J. Barnes and Michael Kölling
Pearson Education, 2016
It is discussed in chapter 13.
This project demonstrates the building of a simple GUI (including labels,
buttons, layout managers, event handling, menus, dialogs) as well as a bit of
image processing.
This project is started by creating an object of class ImageViewer. This will
automatically display the application's GUI - no further interaction with the
object on the object bench is necessary.
WARNING:
It sometimes happens (unfortunately) that the image viewer window opens BEHIND the
BlueJ window. This can be confusing, since it initially appears as if nothing
is happening.

View File

@@ -0,0 +1,20 @@
#BlueJ class context
comment0.params=name
comment0.target=SmoothFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ SmoothFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
comment1.params=image
comment1.target=void\ apply(OFImage)
comment1.text=\n\ Apply\ this\ filter\ to\ an\ image.\n\ \n\ @param\ \ image\ \ The\ image\ to\ be\ changed\ by\ this\ filter.\n
comment2.params=xpos\ ypos
comment2.target=java.awt.Color\ smooth(int,\ int)
comment2.text=\n\ Return\ a\ new\ color\ that\ is\ the\ smoothed\ color\ of\ a\ given\n\ position.\ The\ "smoothed\ color"\ is\ the\ color\ value\ that\ is\ the\n\ average\ of\ this\ pixel\ and\ all\ the\ adjacent\ pixels.\n\ @param\ xpos\ The\ xposition\ of\ the\ pixel.\n\ @param\ ypos\ The\ yposition\ of\ the\ pixel.\n\ @return\ The\ smoothed\ color.\n
comment3.params=pixels
comment3.target=int\ avgRed(java.util.List)
comment3.text=\n\ @param\ pixels\ The\ list\ of\ pixels.\n\ @return\ The\ average\ of\ all\ the\ red\ values\ in\ the\ given\ list\ of\ pixels.\n
comment4.params=pixels
comment4.target=int\ avgGreen(java.util.List)
comment4.text=\n\ @param\ pixels\ The\ list\ of\ pixels.\n\ @return\ The\ average\ of\ all\ the\ green\ values\ in\ the\ given\ list\ of\ pixels.\n
comment5.params=pixels
comment5.target=int\ avgBlue(java.util.List)
comment5.text=\n\ @param\ pixels\ The\ list\ of\ pixels.\n\ @return\ The\ average\ of\ all\ the\ blue\ values\ in\ the\ given\ list\ of\ pixels.\n
numComments=6

View File

@@ -0,0 +1,105 @@
import java.awt.Color;
import java.util.List;
import java.util.ArrayList;
/**
* An image filter to reduce sharp edges and pixelization. A bit like
* a soft lens.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class SmoothFilter extends Filter
{
private OFImage original;
private int width;
private int height;
/**
* Constructor for objects of class SmoothFilter.
* @param name The name of the filter.
*/
public SmoothFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
original = new OFImage(image);
width = original.getWidth();
height = original.getHeight();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
image.setPixel(x, y, smooth(x, y));
}
}
}
/**
* Return a new color that is the smoothed color of a given
* position. The "smoothed color" is the color value that is the
* average of this pixel and all the adjacent pixels.
* @param xpos The xposition of the pixel.
* @param ypos The yposition of the pixel.
* @return The smoothed color.
*/
private Color smooth(int xpos, int ypos)
{
List<Color> pixels = new ArrayList<>(9);
for(int y = ypos - 1; y <= ypos + 1; y++) {
for(int x = xpos - 1; x <= xpos + 1; x++) {
if( x >= 0 && x < width && y >= 0 && y < height )
pixels.add(original.getPixel(x, y));
}
}
return new Color(avgRed(pixels), avgGreen(pixels), avgBlue(pixels));
}
/**
* @param pixels The list of pixels.
* @return The average of all the red values in the given list of pixels.
*/
private int avgRed(List<Color> pixels)
{
int total = 0;
for(Color color : pixels) {
total += color.getRed();
}
return total / pixels.size();
}
/**
* @param pixels The list of pixels.
* @return The average of all the green values in the given list of pixels.
*/
private int avgGreen(List<Color> pixels)
{
int total = 0;
for(Color color : pixels) {
total += color.getGreen();
}
return total / pixels.size();
}
/**
* @param pixels The list of pixels.
* @return The average of all the blue values in the given list of pixels.
*/
private int avgBlue(List<Color> pixels)
{
int total = 0;
for(Color color : pixels) {
total += color.getBlue();
}
return total / pixels.size();
}
}

View File

@@ -0,0 +1,5 @@
#BlueJ class context
comment0.params=name
comment0.target=SolarizeFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ Solarize.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
numComments=1

View File

@@ -0,0 +1,49 @@
import java.awt.Color;
/**
* An image filter to create a solarization effect.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class SolarizeFilter extends Filter
{
/**
* Constructor for objects of class Solarize.
* @param name The name of the filter.
*/
public SolarizeFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
Color pix = image.getPixel(x, y);
int red = pix.getRed();
if(red <= 127) {
red = 255 - red;
}
int green = pix.getGreen();
if(green <= 127) {
green = 255 - green;
}
int blue = pix.getBlue();
if(blue <= 127) {
blue = 255 - blue;
}
image.setPixel(x, y, new Color(red, green, blue));
}
}
}
}

View File

@@ -0,0 +1,5 @@
#BlueJ class context
comment0.params=name
comment0.target=ThresholdFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ ThresholdFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
numComments=1

View File

@@ -0,0 +1,45 @@
import java.awt.Color;
/**
* An three-level gray-based threshold filter.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class ThresholdFilter extends Filter
{
/**
* Constructor for objects of class ThresholdFilter.
* @param name The name of the filter.
*/
public ThresholdFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
Color pixel = image.getPixel(x, y);
int brightness = (pixel.getRed() + pixel.getBlue() + pixel.getGreen()) / 3;
if(brightness <= 85) {
image.setPixel(x, y, Color.BLACK);
}
else if(brightness <= 170) {
image.setPixel(x, y, Color.GRAY);
}
else {
image.setPixel(x, y, Color.WHITE);
}
}
}
}
}

View File

@@ -0,0 +1,311 @@
#BlueJ package file
dependency1.from=EdgeFilter
dependency1.to=OFImage
dependency1.type=UsesDependency
dependency10.from=ImageViewer
dependency10.to=LighterFilter
dependency10.type=UsesDependency
dependency11.from=ImageViewer
dependency11.to=SolarizeFilter
dependency11.type=UsesDependency
dependency12.from=ImageViewer
dependency12.to=MirrorFilter
dependency12.type=UsesDependency
dependency13.from=ImageViewer
dependency13.to=ThresholdFilter
dependency13.type=UsesDependency
dependency14.from=ImageViewer
dependency14.to=FishEyeFilter
dependency14.type=UsesDependency
dependency15.from=ImageViewer
dependency15.to=Filter
dependency15.type=UsesDependency
dependency16.from=ImageViewer
dependency16.to=InvertFilter
dependency16.type=UsesDependency
dependency17.from=SolarizeFilter
dependency17.to=OFImage
dependency17.type=UsesDependency
dependency18.from=LighterFilter
dependency18.to=OFImage
dependency18.type=UsesDependency
dependency19.from=DarkerFilter
dependency19.to=OFImage
dependency19.type=UsesDependency
dependency2.from=SmoothFilter
dependency2.to=OFImage
dependency2.type=UsesDependency
dependency20.from=PixelizeFilter
dependency20.to=OFImage
dependency20.type=UsesDependency
dependency21.from=MirrorFilter
dependency21.to=OFImage
dependency21.type=UsesDependency
dependency22.from=ThresholdFilter
dependency22.to=OFImage
dependency22.type=UsesDependency
dependency23.from=ImagePanel
dependency23.to=OFImage
dependency23.type=UsesDependency
dependency24.from=FishEyeFilter
dependency24.to=OFImage
dependency24.type=UsesDependency
dependency25.from=Filter
dependency25.to=OFImage
dependency25.type=UsesDependency
dependency26.from=InvertFilter
dependency26.to=OFImage
dependency26.type=UsesDependency
dependency27.from=GrayScaleFilter
dependency27.to=OFImage
dependency27.type=UsesDependency
dependency28.from=ImageFileManager
dependency28.to=OFImage
dependency28.type=UsesDependency
dependency29.from=ImageViewer
dependency29.to=ImageFileManager
dependency29.type=UsesDependency
dependency3.from=ImageViewer
dependency3.to=SmoothFilter
dependency3.type=UsesDependency
dependency4.from=ImageViewer
dependency4.to=DarkerFilter
dependency4.type=UsesDependency
dependency5.from=ImageViewer
dependency5.to=PixelizeFilter
dependency5.type=UsesDependency
dependency6.from=ImageViewer
dependency6.to=OFImage
dependency6.type=UsesDependency
dependency7.from=ImageViewer
dependency7.to=ImagePanel
dependency7.type=UsesDependency
dependency8.from=ImageViewer
dependency8.to=GrayScaleFilter
dependency8.type=UsesDependency
dependency9.from=ImageViewer
dependency9.to=EdgeFilter
dependency9.type=UsesDependency
objectbench.height=76
objectbench.width=1074
package.editor.height=636
package.editor.width=966
package.editor.x=70
package.editor.y=80
package.numDependencies=29
package.numTargets=16
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=642
readme.editor.width=871
readme.editor.x=41
readme.editor.y=67
target1.editor.height=731
target1.editor.width=850
target1.editor.x=50
target1.editor.y=60
target1.height=60
target1.name=SolarizeFilter
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=110
target1.x=780
target1.y=190
target10.editor.height=734
target10.editor.width=889
target10.editor.x=50
target10.editor.y=60
target10.height=60
target10.name=Filter
target10.naviview.expanded=true
target10.showInterface=false
target10.type=AbstractTarget
target10.typeParameters=
target10.width=100
target10.x=600
target10.y=260
target11.editor.height=730
target11.editor.width=976
target11.editor.x=50
target11.editor.y=60
target11.height=60
target11.name=EdgeFilter
target11.naviview.expanded=true
target11.showInterface=false
target11.type=ClassTarget
target11.typeParameters=
target11.width=90
target11.x=450
target11.y=120
target12.editor.height=731
target12.editor.width=890
target12.editor.x=50
target12.editor.y=60
target12.height=60
target12.name=FishEyeFilter
target12.naviview.expanded=true
target12.showInterface=false
target12.type=ClassTarget
target12.typeParameters=
target12.width=100
target12.x=550
target12.y=120
target13.editor.height=730
target13.editor.width=869
target13.editor.x=50
target13.editor.y=60
target13.height=60
target13.name=MirrorFilter
target13.naviview.expanded=true
target13.showInterface=false
target13.type=ClassTarget
target13.typeParameters=
target13.width=110
target13.x=780
target13.y=260
target14.editor.height=699
target14.editor.width=1004
target14.editor.x=41
target14.editor.y=23
target14.height=60
target14.name=ImageViewer
target14.naviview.expanded=true
target14.showInterface=false
target14.type=ClassTarget
target14.typeParameters=
target14.width=130
target14.x=230
target14.y=30
target15.editor.height=724
target15.editor.width=877
target15.editor.x=50
target15.editor.y=60
target15.height=60
target15.name=SmoothFilter
target15.naviview.expanded=true
target15.showInterface=false
target15.type=ClassTarget
target15.typeParameters=
target15.width=110
target15.x=780
target15.y=330
target16.editor.height=728
target16.editor.width=885
target16.editor.x=50
target16.editor.y=60
target16.height=60
target16.name=ImagePanel
target16.naviview.expanded=true
target16.showInterface=false
target16.type=ClassTarget
target16.typeParameters=
target16.width=140
target16.x=60
target16.y=270
target2.editor.height=720
target2.editor.width=946
target2.editor.x=50
target2.editor.y=60
target2.height=60
target2.name=ThresholdFilter
target2.naviview.expanded=true
target2.showInterface=false
target2.type=ClassTarget
target2.typeParameters=
target2.width=120
target2.x=650
target2.y=400
target3.editor.height=728
target3.editor.width=858
target3.editor.x=50
target3.editor.y=60
target3.height=60
target3.name=InvertFilter
target3.naviview.expanded=true
target3.showInterface=false
target3.type=ClassTarget
target3.typeParameters=
target3.width=110
target3.x=780
target3.y=400
target4.editor.height=732
target4.editor.width=895
target4.editor.x=50
target4.editor.y=60
target4.height=60
target4.name=GrayScaleFilter
target4.naviview.expanded=true
target4.showInterface=false
target4.type=ClassTarget
target4.typeParameters=
target4.width=110
target4.x=660
target4.y=120
target5.editor.height=731
target5.editor.width=858
target5.editor.x=50
target5.editor.y=60
target5.height=60
target5.name=DarkerFilter
target5.naviview.expanded=true
target5.showInterface=false
target5.type=ClassTarget
target5.typeParameters=
target5.width=100
target5.x=430
target5.y=400
target6.editor.height=729
target6.editor.width=878
target6.editor.x=50
target6.editor.y=60
target6.height=60
target6.name=PixelizeFilter
target6.naviview.expanded=true
target6.showInterface=false
target6.type=ClassTarget
target6.typeParameters=
target6.width=110
target6.x=780
target6.y=120
target7.editor.height=737
target7.editor.width=846
target7.editor.x=50
target7.editor.y=60
target7.height=60
target7.name=ImageFileManager
target7.naviview.expanded=true
target7.showInterface=false
target7.type=ClassTarget
target7.typeParameters=
target7.width=140
target7.x=60
target7.y=190
target8.editor.height=718
target8.editor.width=872
target8.editor.x=50
target8.editor.y=60
target8.height=60
target8.name=LighterFilter
target8.naviview.expanded=true
target8.showInterface=false
target8.type=ClassTarget
target8.typeParameters=
target8.width=100
target8.x=540
target8.y=400
target9.editor.height=700
target9.editor.width=863
target9.editor.x=0
target9.editor.y=22
target9.height=90
target9.name=OFImage
target9.naviview.expanded=true
target9.showInterface=false
target9.type=ClassTarget
target9.typeParameters=
target9.width=110
target9.x=90
target9.y=510

View File

@@ -0,0 +1,8 @@
#BlueJ class context
comment0.params=
comment0.target=ImageViewer()
comment0.text=\n\ Create\ an\ ImageViewer\ show\ it\ on\ screen.\n
comment1.params=
comment1.target=void\ makeFrame()
comment1.text=\n\ Create\ the\ Swing\ frame\ and\ its\ content.\n
numComments=2

View File

@@ -0,0 +1,42 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* ImageViewer is the main class of the image viewer application. It builds
* and displays the application GUI and initialises all other components.
*
* To start the application, create an object of this class.
*
* @author Michael Kölling and David J. Barnes.
* @version 0.1
*/
public class ImageViewer
{
private JFrame frame;
/**
* Create an ImageViewer show it on screen.
*/
public ImageViewer()
{
makeFrame();
}
// ---- swing stuff to build the frame and all its components ----
/**
* Create the Swing frame and its content.
*/
private void makeFrame()
{
frame = new JFrame("ImageViewer");
Container contentPane = frame.getContentPane();
JLabel label = new JLabel("I am a label. I can display some text.");
contentPane.add(label);
frame.pack();
frame.setVisible(true);
}
}

View File

@@ -0,0 +1,14 @@
Project: imageviewer, version 0.1
Authors: David Barnes and Michael Kölling
This project is part of the material for the book
Objects First with Java - A Practical Introduction using BlueJ
Sixth edition
David J. Barnes and Michael Kölling
Pearson Education, 2016
It is discussed in chapter 13.
To use this project, create an instance of class ImageViewer.
For details, refer to the book chapter.

View File

@@ -0,0 +1,29 @@
#BlueJ package file
objectbench.height=76
objectbench.width=682
package.editor.height=368
package.editor.width=574
package.editor.x=70
package.editor.y=80
package.numDependencies=0
package.numTargets=1
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=565
readme.editor.width=787
readme.editor.x=53
readme.editor.y=23
target1.editor.height=777
target1.editor.width=945
target1.editor.x=427
target1.editor.y=23
target1.height=60
target1.name=ImageViewer
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=110
target1.x=170
target1.y=100

View File

@@ -0,0 +1,8 @@
#BlueJ class context
comment0.params=
comment0.target=ImageViewer()
comment0.text=\n\ Create\ an\ ImageViewer\ show\ it\ on\ screen.\n
comment1.params=
comment1.target=void\ makeFrame()
comment1.text=\n\ Create\ the\ Swing\ frame\ and\ its\ content.\n
numComments=2

View File

@@ -0,0 +1,41 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* ImageViewer is the main class of the image viewer application. It builds
* and displays the application GUI and initialises all other components.
*
* To start the application, create an object of this class.
*
* @author Michael Kölling and David J. Barnes.
* @version 0.1a
*/
public class ImageViewer extends JFrame
{
/**
* Create an ImageViewer show it on screen.
*/
public ImageViewer()
{
super("ImageViewer");
makeFrame();
}
// ---- swing stuff to build the frame and all its components ----
/**
* Create the Swing frame and its content.
*/
private void makeFrame()
{
Container contentPane = getContentPane();
JLabel label = new JLabel("I am a label. I can display some text.");
contentPane.add(label);
pack();
setVisible(true);
}
}

View File

@@ -0,0 +1,14 @@
Project: imageviewer, version 0.1a
Authors: David Barnes and Michael Kölling
This project is part of the material for the book
Objects First with Java - A Practical Introduction using BlueJ
Sixth edition
David J. Barnes and Michael Kölling
Pearson Education, 2016
It is discussed in chapter 13.
To use this project, create an instance of class ImageViewer.
For details, refer to the book chapter.

View File

@@ -0,0 +1,29 @@
#BlueJ package file
objectbench.height=76
objectbench.width=665
package.editor.height=395
package.editor.width=557
package.editor.x=70
package.editor.y=80
package.numDependencies=0
package.numTargets=1
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=571
readme.editor.width=843
readme.editor.x=53
readme.editor.y=23
target1.editor.height=819
target1.editor.width=890
target1.editor.x=963
target1.editor.y=71
target1.height=60
target1.name=ImageViewer
target1.naviview.expanded=false
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=110
target1.x=170
target1.y=120

View File

@@ -0,0 +1,14 @@
#BlueJ class context
comment0.params=
comment0.target=ImageViewer()
comment0.text=\n\ Create\ an\ ImageViewer\ show\ it\ on\ screen.\n
comment1.params=event
comment1.target=void\ actionPerformed(java.awt.event.ActionEvent)
comment1.text=\n\ Receive\ notification\ of\ an\ action.\n\ @param\ event\ Details\ of\ the\ action.\n
comment2.params=
comment2.target=void\ makeFrame()
comment2.text=\n\ Create\ the\ Swing\ frame\ and\ its\ content.\n
comment3.params=frame
comment3.target=void\ makeMenuBar(javax.swing.JFrame)
comment3.text=\n\ Create\ the\ main\ frame's\ menu\ bar.\n\ @param\ frame\ \ \ The\ frame\ that\ the\ menu\ bar\ should\ be\ added\ to.\n
numComments=4

View File

@@ -0,0 +1,78 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* ImageViewer is the main class of the image viewer application. It builds
* and displays the application GUI.
*
* To start the application, create an object of this class.
*
* @author Michael Kölling and David J. Barnes.
* @version 0.2
*/
public class ImageViewer
implements ActionListener
{
private JFrame frame;
/**
* Create an ImageViewer show it on screen.
*/
public ImageViewer()
{
makeFrame();
}
/**
* Receive notification of an action.
* @param event Details of the action.
*/
public void actionPerformed(ActionEvent event)
{
System.out.println("Menu item: " + event.getActionCommand());
}
// ---- swing stuff to build the frame and all its components ----
/**
* Create the Swing frame and its content.
*/
private void makeFrame()
{
frame = new JFrame("ImageViewer");
makeMenuBar(frame);
Container contentPane = frame.getContentPane();
JLabel label = new JLabel("I am a label. I can display some text.");
contentPane.add(label);
// building is done - arrange the components and show
frame.pack();
frame.setVisible(true);
}
/**
* Create the main frame's menu bar.
* @param frame The frame that the menu bar should be added to.
*/
private void makeMenuBar(JFrame frame)
{
JMenuBar menubar = new JMenuBar();
frame.setJMenuBar(menubar);
// create the File menu
JMenu fileMenu = new JMenu("File");
menubar.add(fileMenu);
JMenuItem openItem = new JMenuItem("Open");
openItem.addActionListener(this);
fileMenu.add(openItem);
JMenuItem quitItem = new JMenuItem("Quit");
quitItem.addActionListener(this);
fileMenu.add(quitItem);
}
}

View File

@@ -0,0 +1,14 @@
Project: imageviewer, version 0.2
Authors: David Barnes and Michael Kölling
This project is part of the material for the book
Objects First with Java - A Practical Introduction using BlueJ
Sixth edition
David J. Barnes and Michael Kölling
Pearson Education, 2016
It is discussed in chapter 13.
To use this project, create an instance of class ImageViewer.
For details, refer to the book chapter.

View File

@@ -0,0 +1,29 @@
#BlueJ package file
objectbench.height=76
objectbench.width=683
package.editor.height=364
package.editor.width=575
package.editor.x=70
package.editor.y=80
package.numDependencies=0
package.numTargets=1
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=543
readme.editor.width=810
readme.editor.x=53
readme.editor.y=23
target1.editor.height=714
target1.editor.width=892
target1.editor.x=53
target1.editor.y=36
target1.height=60
target1.name=ImageViewer
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=120
target1.x=180
target1.y=120

View File

@@ -0,0 +1,17 @@
#BlueJ class context
comment0.params=
comment0.target=ImageViewer()
comment0.text=\n\ Create\ an\ ImageViewer\ show\ it\ on\ screen.\n
comment1.params=
comment1.target=void\ openFile()
comment1.text=\n\ Open\ function\:\ open\ a\ file\ chooser\ to\ select\ a\ new\ image\ file.\n
comment2.params=
comment2.target=void\ quit()
comment2.text=\n\ Quit\ function\:\ quit\ the\ application.\n
comment3.params=
comment3.target=void\ makeFrame()
comment3.text=\n\ Create\ the\ Swing\ frame\ and\ its\ content.\n
comment4.params=frame
comment4.target=void\ makeMenuBar(javax.swing.JFrame)
comment4.text=\n\ Create\ the\ main\ frame's\ menu\ bar.\n\ @param\ frame\ \ \ The\ frame\ that\ the\ menu\ bar\ should\ be\ added\ to.\n
numComments=5

View File

@@ -0,0 +1,87 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* ImageViewer is the main class of the image viewer application. It builds
* and displays the application GUI.
*
* To start the application, create an object of this class.
*
* @author Michael Kölling and David J. Barnes.
* @version 0.3
*/
public class ImageViewer
{
private JFrame frame;
/**
* Create an ImageViewer show it on screen.
*/
public ImageViewer()
{
makeFrame();
}
// ---- implementation of menu functions ----
/**
* Open function: open a file chooser to select a new image file.
*/
private void openFile()
{
// this is some test output, until we do this properly
System.out.println("open file");
}
/**
* Quit function: quit the application.
*/
private void quit()
{
System.exit(0);
}
// ---- swing stuff to build the frame and all its components ----
/**
* Create the Swing frame and its content.
*/
private void makeFrame()
{
frame = new JFrame("ImageViewer");
makeMenuBar(frame);
Container contentPane = frame.getContentPane();
JLabel label = new JLabel("I am a label. I can display some text.");
contentPane.add(label);
// building is done - arrange the components and show
frame.pack();
frame.setVisible(true);
}
/**
* Create the main frame's menu bar.
* @param frame The frame that the menu bar should be added to.
*/
private void makeMenuBar(JFrame frame)
{
JMenuBar menubar = new JMenuBar();
frame.setJMenuBar(menubar);
// create the File menu
JMenu fileMenu = new JMenu("File");
menubar.add(fileMenu);
JMenuItem openItem = new JMenuItem("Open");
openItem.addActionListener(e -> openFile());
fileMenu.add(openItem);
JMenuItem quitItem = new JMenuItem("Quit");
quitItem.addActionListener(e -> quit());
fileMenu.add(quitItem);
}
}

View File

@@ -0,0 +1,14 @@
Project: imageviewer, version 0.3
Authors: David Barnes and Michael Kölling
This project is part of the material for the book
Objects First with Java - A Practical Introduction using BlueJ
Sixth edition
David J. Barnes and Michael Kölling
Pearson Education, 2016
It is discussed in chapter 13.
To use this project, create an instance of class ImageViewer.
For details, refer to the book chapter.

View File

@@ -0,0 +1,29 @@
#BlueJ package file
objectbench.height=76
objectbench.width=679
package.editor.height=369
package.editor.width=571
package.editor.x=70
package.editor.y=80
package.numDependencies=0
package.numTargets=1
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=534
readme.editor.width=776
readme.editor.x=53
readme.editor.y=23
target1.editor.height=736
target1.editor.width=938
target1.editor.x=231
target1.editor.y=58
target1.height=60
target1.name=ImageViewer
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=120
target1.x=210
target1.y=130

View File

@@ -0,0 +1,11 @@
#BlueJ class context
comment0.params=
comment0.target=OFImage\ getImage()
comment0.text=\n\ Open\ a\ file\ chooser\ and\ let\ the\ user\ select\ an\ image\ file\ in\ the\ file\n\ system.\ Then\ read\ an\ image\ file\ from\ disk\ and\ return\ it\ as\ an\ image.\ This\ method\n\ can\ read\ JPG\ and\ PNG\ file\ formats.\ In\ case\ of\ any\ problem\ (e.g\ the\ file\ does\n\ not\ exist,\ is\ in\ an\ undecodable\ format,\ or\ any\ other\ read\ error)\ this\ method\n\ returns\ null.\n\ \n\ @return\ \ \ \ \ \ \ The\ image\ object\ or\ null\ is\ it\ was\ not\ a\ valid\ image\ file.\n
comment1.params=imageFile
comment1.target=OFImage\ loadImage(java.io.File)
comment1.text=\n\ Read\ an\ image\ file\ from\ disk\ and\ return\ it\ as\ a\ BufferedImage.\ This\ method\n\ can\ read\ JPG\ and\ PNG\ file\ formats.\ In\ case\ of\ any\ problem\ (e.g\ the\ file\ does\n\ not\ exist,\ is\ in\ an\ undecodable\ format,\ or\ any\ other\ read\ error)\ this\ method\n\ returns\ null.\n\ \n\ @param\ imageFile\ \ The\ image\ file\ to\ be\ loaded.\n\ @return\ \ \ \ \ \ \ \ \ \ \ The\ image\ object\ or\ null\ if\ it\ was\ not\ a\ valid\ image\ file.\n
comment2.params=image\ file
comment2.target=void\ saveImage(OFImage,\ java.io.File)
comment2.text=\n\ Write\ an\ image\ file\ to\ disk.\ The\ file\ format\ is\ JPG.\ In\ case\ of\ any\ problem\n\ the\ method\ just\ silently\ returns.\n\ \n\ @param\ image\ \ The\ image\ to\ be\ saved.\n\ @param\ file\ \ \ The\ file\ to\ save\ to.\n
numComments=3

View File

@@ -0,0 +1,83 @@
import java.awt.image.*;
import javax.imageio.*;
import javax.swing.*;
import java.io.*;
/**
* ImageFileManager is a small utility class with static methods to load
* and save images.
*
* The files on disk can be in JPG or PNG image format. For files written
* by this class, the format is determined by the constant IMAGE_FORMAT.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class ImageFileManager
{
// A constant for the image format that this writer uses for writing.
// Available formats are "jpg" and "png".
private static final String IMAGE_FORMAT = "jpg";
private static JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));
/**
* Open a file chooser and let the user select an image file in the file
* system. Then read an image file from disk and return it as an image. This method
* can read JPG and PNG file formats. In case of any problem (e.g the file does
* not exist, is in an undecodable format, or any other read error) this method
* returns null.
*
* @return The image object or null is it was not a valid image file.
*/
public static OFImage getImage()
{
int returnVal = fileChooser.showOpenDialog(null);
if(returnVal != JFileChooser.APPROVE_OPTION) {
return null; // cancelled
}
File selectedFile = fileChooser.getSelectedFile();
return loadImage(selectedFile);
}
/**
* Read an image file from disk and return it as a BufferedImage. This method
* can read JPG and PNG file formats. In case of any problem (e.g the file does
* not exist, is in an undecodable format, or any other read error) this method
* returns null.
*
* @param imageFile The image file to be loaded.
* @return The image object or null if it was not a valid image file.
*/
public static OFImage loadImage(File imageFile)
{
try {
BufferedImage image = ImageIO.read(imageFile);
if(image == null || (image.getWidth(null) < 0)) {
// we could not load the image - probably invalid file format
return null;
}
return new OFImage(image);
}
catch(IOException exc) {
return null;
}
}
/**
* Write an image file to disk. The file format is JPG. In case of any problem
* the method just silently returns.
*
* @param image The image to be saved.
* @param file The file to save to.
*/
public static void saveImage(OFImage image, File file)
{
try {
ImageIO.write(image, IMAGE_FORMAT, file);
}
catch(IOException exc) {
return;
}
}
}

View File

@@ -0,0 +1,17 @@
#BlueJ class context
comment0.params=
comment0.target=ImagePanel()
comment0.text=\n\ Create\ a\ new,\ empty\ ImagePanel.\n
comment1.params=image
comment1.target=void\ setImage(OFImage)
comment1.text=\n\ Set\ the\ image\ that\ this\ panel\ should\ show.\n\ \n\ @param\ image\ \ The\ image\ to\ be\ displayed.\n
comment2.params=
comment2.target=void\ clearImage()
comment2.text=\n\ Clear\ the\ image\ on\ this\ panel.\n
comment3.params=
comment3.target=java.awt.Dimension\ getPreferredSize()
comment3.text=\n\ Tell\ the\ layout\ manager\ how\ big\ we\ would\ like\ to\ be.\n\ (This\ method\ gets\ called\ by\ layout\ managers\ for\ placing\n\ the\ components.)\n\ \n\ @return\ The\ preferred\ dimension\ for\ this\ component.\n
comment4.params=g
comment4.target=void\ paintComponent(java.awt.Graphics)
comment4.text=\n\ This\ component\ needs\ to\ be\ redisplayed.\ Copy\ the\ internal\ image\ \n\ to\ screen.\ (This\ method\ gets\ called\ by\ the\ Swing\ screen\ painter\ \n\ every\ time\ it\ want\ this\ component\ displayed.)\n\ \n\ @param\ g\ The\ graphics\ context\ that\ can\ be\ used\ to\ draw\ on\ this\ component.\n
numComments=5

View File

@@ -0,0 +1,89 @@
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
/**
* An ImagePanel is a Swing component that can display an OFImage.
* It is constructed as a subclass of JComponent with the added functionality
* of setting an OFImage that will be displayed on the surface of this
* component.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class ImagePanel extends JComponent
{
// The current width and height of this panel
private int width, height;
// An internal image buffer that is used for painting. For
// actual display, this image buffer is then copied to screen.
private OFImage panelImage;
/**
* Create a new, empty ImagePanel.
*/
public ImagePanel()
{
width = 360; // arbitrary size for empty panel
height = 240;
panelImage = null;
}
/**
* Set the image that this panel should show.
*
* @param image The image to be displayed.
*/
public void setImage(OFImage image)
{
if(image != null) {
width = image.getWidth();
height = image.getHeight();
panelImage = image;
repaint();
}
}
/**
* Clear the image on this panel.
*/
public void clearImage()
{
Graphics imageGraphics = panelImage.getGraphics();
imageGraphics.setColor(Color.LIGHT_GRAY);
imageGraphics.fillRect(0, 0, width, height);
repaint();
}
// The following methods are redefinitions of methods
// inherited from superclasses.
/**
* Tell the layout manager how big we would like to be.
* (This method gets called by layout managers for placing
* the components.)
*
* @return The preferred dimension for this component.
*/
public Dimension getPreferredSize()
{
return new Dimension(width, height);
}
/**
* This component needs to be redisplayed. Copy the internal image
* to screen. (This method gets called by the Swing screen painter
* every time it want this component displayed.)
*
* @param g The graphics context that can be used to draw on this component.
*/
public void paintComponent(Graphics g)
{
Dimension size = getSize();
g.clearRect(0, 0, size.width, size.height);
if(panelImage != null) {
g.drawImage(panelImage, 0, 0, null);
}
}
}

View File

@@ -0,0 +1,17 @@
#BlueJ class context
comment0.params=
comment0.target=ImageViewer()
comment0.text=\n\ Create\ an\ ImageViewer\ show\ it\ on\ screen.\n
comment1.params=
comment1.target=void\ openFile()
comment1.text=\n\ Open\ function\:\ open\ a\ file\ chooser\ to\ select\ a\ new\ image\ file.\n
comment2.params=
comment2.target=void\ quit()
comment2.text=\n\ Quit\ function\:\ quit\ the\ application.\n
comment3.params=
comment3.target=void\ makeFrame()
comment3.text=\n\ Create\ the\ Swing\ frame\ and\ its\ content.\n
comment4.params=frame
comment4.target=void\ makeMenuBar(javax.swing.JFrame)
comment4.text=\n\ Create\ the\ main\ frame's\ menu\ bar.\n\ @param\ frame\ \ \ The\ frame\ that\ the\ menu\ bar\ should\ be\ added\ to.\n
numComments=5

View File

@@ -0,0 +1,96 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* ImageViewer is the main class of the image viewer application. It builds and
* displays the application GUI and initialises all other components.
*
* To start the application, create an object of this class.
*
* @author Michael Kölling and David J. Barnes.
* @version 0.4
*/
public class ImageViewer
{
private JFrame frame;
private ImagePanel imagePanel;
/**
* Create an ImageViewer show it on screen.
*/
public ImageViewer()
{
makeFrame();
}
// ---- implementation of menu functions ----
/**
* Open function: open a file chooser to select a new image file.
*/
private void openFile()
{
OFImage image = ImageFileManager.getImage();
imagePanel.setImage(image);
frame.pack();
}
/**
* Quit function: quit the application.
*/
private void quit()
{
System.exit(0);
}
// ---- swing stuff to build the frame and all its components ----
/**
* Create the Swing frame and its content.
*/
private void makeFrame()
{
frame = new JFrame("ImageViewer");
makeMenuBar(frame);
Container contentPane = frame.getContentPane();
imagePanel = new ImagePanel();
contentPane.add(imagePanel);
// building is done - arrange the components and show
frame.pack();
frame.setVisible(true);
}
/**
* Create the main frame's menu bar.
* @param frame The frame that the menu bar should be added to.
*/
private void makeMenuBar(JFrame frame)
{
final int SHORTCUT_MASK =
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
JMenuBar menubar = new JMenuBar();
frame.setJMenuBar(menubar);
// create the File manu
JMenu fileMenu = new JMenu("File");
menubar.add(fileMenu);
JMenuItem openItem = new JMenuItem("Open");
openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_MASK));
openItem.addActionListener(e -> openFile());
fileMenu.add(openItem);
JMenuItem quitItem = new JMenuItem("Quit");
quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));
quitItem.addActionListener(e -> quit());
fileMenu.add(quitItem);
}
}

View File

@@ -0,0 +1,14 @@
#BlueJ class context
comment0.params=image
comment0.target=OFImage(java.awt.image.BufferedImage)
comment0.text=\n\ Create\ an\ OFImage\ copied\ from\ a\ BufferedImage.\n\ @param\ image\ The\ image\ to\ copy.\n
comment1.params=width\ height
comment1.target=OFImage(int,\ int)
comment1.text=\n\ Create\ an\ OFImage\ with\ specified\ size\ and\ unspecified\ content.\n\ @param\ width\ The\ width\ of\ the\ image.\n\ @param\ height\ The\ height\ of\ the\ image.\n
comment2.params=x\ y\ col
comment2.target=void\ setPixel(int,\ int,\ java.awt.Color)
comment2.text=\n\ Set\ a\ given\ pixel\ of\ this\ image\ to\ a\ specified\ color.\ The\n\ color\ is\ represented\ as\ an\ (r,g,b)\ value.\n\ @param\ x\ The\ x\ position\ of\ the\ pixel.\n\ @param\ y\ The\ y\ position\ of\ the\ pixel.\n\ @param\ col\ The\ color\ of\ the\ pixel.\n
comment3.params=x\ y
comment3.target=java.awt.Color\ getPixel(int,\ int)
comment3.text=\n\ Get\ the\ color\ value\ at\ a\ specified\ pixel\ position.\n\ @param\ x\ The\ x\ position\ of\ the\ pixel.\n\ @param\ y\ The\ y\ position\ of\ the\ pixel.\n\ @return\ The\ color\ of\ the\ pixel\ at\ the\ given\ position.\n
numComments=4

View File

@@ -0,0 +1,57 @@
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
/**
* OFImage is a class that defines an image in OF (Objects First) format.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class OFImage extends BufferedImage
{
/**
* Create an OFImage copied from a BufferedImage.
* @param image The image to copy.
*/
public OFImage(BufferedImage image)
{
super(image.getColorModel(), image.copyData(null),
image.isAlphaPremultiplied(), null);
}
/**
* Create an OFImage with specified size and unspecified content.
* @param width The width of the image.
* @param height The height of the image.
*/
public OFImage(int width, int height)
{
super(width, height, TYPE_INT_RGB);
}
/**
* Set a given pixel of this image to a specified color. The
* color is represented as an (r,g,b) value.
* @param x The x position of the pixel.
* @param y The y position of the pixel.
* @param col The color of the pixel.
*/
public void setPixel(int x, int y, Color col)
{
int pixel = col.getRGB();
setRGB(x, y, pixel);
}
/**
* Get the color value at a specified pixel position.
* @param x The x position of the pixel.
* @param y The y position of the pixel.
* @return The color of the pixel at the given position.
*/
public Color getPixel(int x, int y)
{
int pixel = getRGB(x, y);
return new Color(pixel);
}
}

View File

@@ -0,0 +1,14 @@
Project: imageviewer, version 0.4
Authors: David Barnes and Michael Kölling
This project is part of the material for the book
Objects First with Java - A Practical Introduction using BlueJ
Sixth edition
David J. Barnes and Michael Kölling
Pearson Education, 2016
It is discussed in chapter 13.
To use this project, create an instance of class ImageViewer.
For details, refer to the book chapter.

View File

@@ -0,0 +1,83 @@
#BlueJ package file
dependency1.from=ImageViewer
dependency1.to=ImagePanel
dependency1.type=UsesDependency
dependency2.from=ImageViewer
dependency2.to=OFImage
dependency2.type=UsesDependency
dependency3.from=ImageViewer
dependency3.to=ImageFileManager
dependency3.type=UsesDependency
dependency4.from=ImageFileManager
dependency4.to=OFImage
dependency4.type=UsesDependency
dependency5.from=ImagePanel
dependency5.to=OFImage
dependency5.type=UsesDependency
objectbench.height=76
objectbench.width=782
package.editor.height=445
package.editor.width=674
package.editor.x=70
package.editor.y=80
package.numDependencies=5
package.numTargets=4
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=557
readme.editor.width=820
readme.editor.x=53
readme.editor.y=23
target1.editor.height=714
target1.editor.width=889
target1.editor.x=50
target1.editor.y=60
target1.height=60
target1.name=OFImage
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=120
target1.x=320
target1.y=320
target2.editor.height=733
target2.editor.width=961
target2.editor.x=532
target2.editor.y=42
target2.height=60
target2.name=ImageFileManager
target2.naviview.expanded=true
target2.showInterface=false
target2.type=ClassTarget
target2.typeParameters=
target2.width=140
target2.x=430
target2.y=180
target3.editor.height=674
target3.editor.width=938
target3.editor.x=69
target3.editor.y=90
target3.height=60
target3.name=ImageViewer
target3.naviview.expanded=true
target3.showInterface=false
target3.type=ClassTarget
target3.typeParameters=
target3.width=120
target3.x=220
target3.y=70
target4.editor.height=726
target4.editor.width=907
target4.editor.x=50
target4.editor.y=60
target4.height=60
target4.name=ImagePanel
target4.naviview.expanded=true
target4.showInterface=false
target4.type=ClassTarget
target4.typeParameters=
target4.width=120
target4.x=60
target4.y=180

View File

@@ -0,0 +1,8 @@
#BlueJ class context
comment0.params=imageFile
comment0.target=OFImage\ loadImage(java.io.File)
comment0.text=\n\ Read\ an\ image\ file\ from\ disk\ and\ return\ it\ as\ an\ image.\ This\ method\n\ can\ read\ JPG\ and\ PNG\ file\ formats.\ In\ case\ of\ any\ problem\ (e.g\ the\ file\ \n\ does\ not\ exist,\ is\ in\ an\ undecodable\ format,\ or\ any\ other\ read\ error)\ \n\ this\ method\ returns\ null.\n\ \n\ @param\ imageFile\ \ The\ image\ file\ to\ be\ loaded.\n\ @return\ \ \ \ \ \ \ \ \ \ \ The\ image\ object\ or\ null\ if\ it\ could\ not\ be\ read.\n
comment1.params=image\ file
comment1.target=void\ saveImage(OFImage,\ java.io.File)
comment1.text=\n\ Write\ an\ image\ file\ to\ disk.\ The\ file\ format\ is\ JPG.\ In\ case\ of\ any\ \n\ problem\ the\ method\ just\ silently\ returns.\n\ \n\ @param\ image\ \ The\ image\ to\ be\ saved.\n\ @param\ file\ \ \ The\ file\ to\ save\ to.\n
numComments=2

View File

@@ -0,0 +1,61 @@
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
/**
* ImageFileManager is a small utility class with static methods to load
* and save images.
*
* The files on disk can be in JPG or PNG image format. For files written
* by this class, the format is determined by the constant IMAGE_FORMAT.
*
* @author Michael Kölling and David J. Barnes.
* @version 2.0
*/
public class ImageFileManager
{
// A constant for the image format that this writer uses for writing.
// Available formats are "jpg" and "png".
private static final String IMAGE_FORMAT = "jpg";
/**
* Read an image file from disk and return it as an image. This method
* can read JPG and PNG file formats. In case of any problem (e.g the file
* does not exist, is in an undecodable format, or any other read error)
* this method returns null.
*
* @param imageFile The image file to be loaded.
* @return The image object or null if it could not be read.
*/
public static OFImage loadImage(File imageFile)
{
try {
BufferedImage image = ImageIO.read(imageFile);
if(image == null || (image.getWidth(null) < 0)) {
// we could not load the image - probably invalid file format
return null;
}
return new OFImage(image);
}
catch(IOException exc) {
return null;
}
}
/**
* Write an image file to disk. The file format is JPG. In case of any
* problem the method just silently returns.
*
* @param image The image to be saved.
* @param file The file to save to.
*/
public static void saveImage(OFImage image, File file)
{
try {
ImageIO.write(image, IMAGE_FORMAT, file);
}
catch(IOException exc) {
return;
}
}
}

View File

@@ -0,0 +1,14 @@
#BlueJ class context
comment0.params=
comment0.target=ImagePanel()
comment0.text=\n\ Create\ a\ new,\ empty\ ImagePanel.\n
comment1.params=
comment1.target=void\ clearImage()
comment1.text=\n\ Clear\ the\ image\ on\ this\ panel.\n
comment2.params=
comment2.target=java.awt.Dimension\ getPreferredSize()
comment2.text=\n\ Tell\ the\ layout\ manager\ how\ big\ we\ would\ like\ to\ be.\n\ (This\ method\ gets\ called\ by\ layout\ managers\ for\ placing\n\ the\ components.)\n\ \n\ @return\ The\ preferred\ dimension\ for\ this\ component.\n
comment3.params=g
comment3.target=void\ paintComponent(java.awt.Graphics)
comment3.text=\n\ This\ component\ needs\ to\ be\ redisplayed.\ Copy\ the\ internal\ image\ \n\ to\ screen.\ (This\ method\ gets\ called\ by\ the\ Swing\ screen\ painter\ \n\ every\ time\ it\ want\ this\ component\ displayed.)\n\ \n\ @param\ g\ The\ graphics\ context\ that\ can\ be\ used\ to\ draw\ on\ this\ component.\n
numComments=4

View File

@@ -0,0 +1,89 @@
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
/**
* An ImagePanel is a Swing component that can display an OFImage.
* It is constructed as a subclass of JComponent with the added functionality
* of setting an OFImage that will be displayed on the surface of this
* component.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class ImagePanel extends JComponent
{
// The current width and height of this panel
private int width, height;
// An internal image buffer that is used for painting. For
// actual display, this image buffer is then copied to screen.
private OFImage panelImage;
/**
* Create a new, empty ImagePanel.
*/
public ImagePanel()
{
width = 360; // arbitrary size for empty panel
height = 240;
panelImage = null;
}
/**
* Set the image that this panel should show.
*
* @param image The image to be displayed.
*/
public void setImage(OFImage image)
{
if(image != null) {
width = image.getWidth();
height = image.getHeight();
panelImage = image;
repaint();
}
}
/**
* Clear the image on this panel.
*/
public void clearImage()
{
Graphics imageGraphics = panelImage.getGraphics();
imageGraphics.setColor(Color.LIGHT_GRAY);
imageGraphics.fillRect(0, 0, width, height);
repaint();
}
// The following methods are redefinitions of methods
// inherited from superclasses.
/**
* Tell the layout manager how big we would like to be.
* (This method gets called by layout managers for placing
* the components.)
*
* @return The preferred dimension for this component.
*/
public Dimension getPreferredSize()
{
return new Dimension(width, height);
}
/**
* This component needs to be redisplayed. Copy the internal image
* to screen. (This method gets called by the Swing screen painter
* every time it want this component displayed.)
*
* @param g The graphics context that can be used to draw on this component.
*/
public void paintComponent(Graphics g)
{
Dimension size = getSize();
g.clearRect(0, 0, size.width, size.height);
if(panelImage != null) {
g.drawImage(panelImage, 0, 0, null);
}
}
}

View File

@@ -0,0 +1,38 @@
#BlueJ class context
comment0.params=
comment0.target=ImageViewer()
comment0.text=\n\ Create\ an\ ImageViewer\ show\ it\ on\ screen.\n
comment1.params=
comment1.target=void\ openFile()
comment1.text=\n\ Open\ function\:\ open\ a\ file\ chooser\ to\ select\ a\ new\ image\ file.\n
comment10.params=
comment10.target=void\ makeFrame()
comment10.text=\n\ Create\ the\ Swing\ frame\ and\ its\ content.\n
comment11.params=frame
comment11.target=void\ makeMenuBar(javax.swing.JFrame)
comment11.text=\n\ Create\ the\ main\ frame's\ menu\ bar.\n\ @param\ frame\ \ \ The\ frame\ that\ the\ menu\ bar\ should\ be\ added\ to.\n
comment2.params=
comment2.target=void\ close()
comment2.text=\n\ Close\ function\:\ close\ the\ current\ image.\n
comment3.params=
comment3.target=void\ quit()
comment3.text=\n\ Quit\ function\:\ quit\ the\ application.\n
comment4.params=
comment4.target=void\ makeDarker()
comment4.text=\n\ 'Darker'\ function\:\ make\ the\ picture\ darker.\n
comment5.params=
comment5.target=void\ makeLighter()
comment5.text=\n\ 'Lighter'\ function\:\ make\ the\ picture\ lighter\n
comment6.params=
comment6.target=void\ threshold()
comment6.text=\n\ 'threshold'\ function\:\ apply\ the\ threshold\ filter\n
comment7.params=
comment7.target=void\ showAbout()
comment7.text=\n\ Show\ the\ 'About...'\ dialog.\n
comment8.params=filename
comment8.target=void\ showFilename(java.lang.String)
comment8.text=\n\ Display\ a\ file\ name\ on\ the\ appropriate\ label.\n\ @param\ filename\ The\ file\ name\ to\ be\ displayed.\n
comment9.params=text
comment9.target=void\ showStatus(java.lang.String)
comment9.text=\n\ Display\ a\ status\ message\ in\ the\ frame's\ status\ bar.\n\ @param\ text\ The\ status\ message\ to\ be\ displayed.\n
numComments=12

View File

@@ -0,0 +1,266 @@
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.io.File;
/**
* ImageViewer is the main class of the image viewer application. It builds and
* displays the application GUI and initialises all other components.
*
* To start the application, create an object of this class.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class ImageViewer
{
// static fields:
private static final String VERSION = "Version 1.0";
private static JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));
// fields:
private JFrame frame;
private ImagePanel imagePanel;
private JLabel filenameLabel;
private JLabel statusLabel;
private OFImage currentImage;
/**
* Create an ImageViewer show it on screen.
*/
public ImageViewer()
{
currentImage = null;
makeFrame();
}
// ---- implementation of menu functions ----
/**
* Open function: open a file chooser to select a new image file.
*/
private void openFile()
{
int returnVal = fileChooser.showOpenDialog(frame);
if(returnVal != JFileChooser.APPROVE_OPTION) {
return; // cancelled
}
File selectedFile = fileChooser.getSelectedFile();
currentImage = ImageFileManager.loadImage(selectedFile);
if(currentImage == null) { // image file was not a valid image
JOptionPane.showMessageDialog(frame,
"The file was not in a recognized image file format.",
"Image Load Error",
JOptionPane.ERROR_MESSAGE);
return;
}
imagePanel.setImage(currentImage);
showFilename(selectedFile.getPath());
showStatus("File loaded.");
frame.pack();
}
/**
* Close function: close the current image.
*/
private void close()
{
currentImage = null;
imagePanel.clearImage();
showFilename(null);
}
/**
* Quit function: quit the application.
*/
private void quit()
{
System.exit(0);
}
/**
* 'Darker' function: make the picture darker.
*/
private void makeDarker()
{
if(currentImage != null) {
currentImage.darker();
frame.repaint();
showStatus("Applied: darker");
}
else {
showStatus("No image loaded.");
}
}
/**
* 'Lighter' function: make the picture lighter
*/
private void makeLighter()
{
if(currentImage != null) {
currentImage.lighter();
frame.repaint();
showStatus("Applied: lighter");
}
else {
showStatus("No image loaded.");
}
}
/**
* 'threshold' function: apply the threshold filter
*/
private void threshold()
{
if(currentImage != null) {
currentImage.threshold();
frame.repaint();
showStatus("Applied: threshold");
}
else {
showStatus("No image loaded.");
}
}
/**
* Show the 'About...' dialog.
*/
private void showAbout()
{
JOptionPane.showMessageDialog(frame,
"ImageViewer\n" + VERSION,
"About ImageViewer",
JOptionPane.INFORMATION_MESSAGE);
}
// ---- support methods ----
/**
* Display a file name on the appropriate label.
* @param filename The file name to be displayed.
*/
private void showFilename(String filename)
{
if(filename == null) {
filenameLabel.setText("No file displayed.");
}
else {
filenameLabel.setText("File: " + filename);
}
}
/**
* Display a status message in the frame's status bar.
* @param text The status message to be displayed.
*/
private void showStatus(String text)
{
statusLabel.setText(text);
}
// ---- swing stuff to build the frame and all its components ----
/**
* Create the Swing frame and its content.
*/
private void makeFrame()
{
frame = new JFrame("ImageViewer");
makeMenuBar(frame);
Container contentPane = frame.getContentPane();
// Specify the layout manager with nice spacing
contentPane.setLayout(new BorderLayout(6, 6));
filenameLabel = new JLabel();
contentPane.add(filenameLabel, BorderLayout.NORTH);
imagePanel = new ImagePanel();
contentPane.add(imagePanel, BorderLayout.CENTER);
statusLabel = new JLabel(VERSION);
contentPane.add(statusLabel, BorderLayout.SOUTH);
// building is done - arrange the components and show
showFilename(null);
frame.pack();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);
frame.setVisible(true);
}
/**
* Create the main frame's menu bar.
* @param frame The frame that the menu bar should be added to.
*/
private void makeMenuBar(JFrame frame)
{
final int SHORTCUT_MASK =
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
JMenuBar menubar = new JMenuBar();
frame.setJMenuBar(menubar);
JMenu menu;
JMenuItem item;
// create the File menu
menu = new JMenu("File");
menubar.add(menu);
item = new JMenuItem("Open");
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_MASK));
item.addActionListener(e -> openFile());
menu.add(item);
item = new JMenuItem("Close");
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, SHORTCUT_MASK));
item.addActionListener(e -> close());
menu.add(item);
menu.addSeparator();
item = new JMenuItem("Quit");
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));
item.addActionListener(e -> quit());
menu.add(item);
// create the Filter menu
menu = new JMenu("Filter");
menubar.add(menu);
item = new JMenuItem("Darker");
item.addActionListener(e -> makeDarker());
menu.add(item);
item = new JMenuItem("Lighter");
item.addActionListener(e -> makeLighter());
menu.add(item);
item = new JMenuItem("Threshold");
item.addActionListener(e -> threshold());
menu.add(item);
// create the Help menu
menu = new JMenu("Help");
menubar.add(menu);
item = new JMenuItem("About ImageViewer...");
item.addActionListener(e -> showAbout());
menu.add(item);
}
}

View File

@@ -0,0 +1,23 @@
#BlueJ class context
comment0.params=image
comment0.target=OFImage(java.awt.image.BufferedImage)
comment0.text=\n\ Create\ an\ OFImage\ copied\ from\ a\ BufferedImage.\n\ @param\ image\ The\ image\ to\ copy.\n
comment1.params=width\ height
comment1.target=OFImage(int,\ int)
comment1.text=\n\ Create\ an\ OFImage\ with\ specified\ size\ and\ unspecified\ content.\n\ @param\ width\ The\ width\ of\ the\ image.\n\ @param\ height\ The\ height\ of\ the\ image.\n
comment2.params=x\ y\ col
comment2.target=void\ setPixel(int,\ int,\ java.awt.Color)
comment2.text=\n\ Set\ a\ given\ pixel\ of\ this\ image\ to\ a\ specified\ color.\ The\n\ color\ is\ represented\ as\ an\ (r,g,b)\ value.\n\ @param\ x\ The\ x\ position\ of\ the\ pixel.\n\ @param\ y\ The\ y\ position\ of\ the\ pixel.\n\ @param\ col\ The\ color\ of\ the\ pixel.\n
comment3.params=x\ y
comment3.target=java.awt.Color\ getPixel(int,\ int)
comment3.text=\n\ Get\ the\ color\ value\ at\ a\ specified\ pixel\ position.\n\ @param\ x\ The\ x\ position\ of\ the\ pixel.\n\ @param\ y\ The\ y\ position\ of\ the\ pixel.\n\ @return\ The\ color\ of\ the\ pixel\ at\ the\ given\ position.\n
comment4.params=
comment4.target=void\ darker()
comment4.text=\n\ Make\ this\ image\ a\ bit\ darker.\n
comment5.params=
comment5.target=void\ lighter()
comment5.text=\n\ Make\ this\ image\ a\ bit\ lighter.\n
comment6.params=
comment6.target=void\ threshold()
comment6.text=\n\ Perform\ a\ three\ level\ threshold\ operation.\n\ That\ is\:\ repaint\ the\ image\ with\ only\ three\ color\ values\:\n\ \ \ \ \ \ \ \ \ \ white,\ gray,\ and\ black.\n
numComments=7

View File

@@ -0,0 +1,111 @@
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
/**
* OFImage is a class that defines an image in OF (Objects First) format.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.1
*/
public class OFImage extends BufferedImage
{
/**
* Create an OFImage copied from a BufferedImage.
* @param image The image to copy.
*/
public OFImage(BufferedImage image)
{
super(image.getColorModel(), image.copyData(null),
image.isAlphaPremultiplied(), null);
}
/**
* Create an OFImage with specified size and unspecified content.
* @param width The width of the image.
* @param height The height of the image.
*/
public OFImage(int width, int height)
{
super(width, height, TYPE_INT_RGB);
}
/**
* Set a given pixel of this image to a specified color. The
* color is represented as an (r,g,b) value.
* @param x The x position of the pixel.
* @param y The y position of the pixel.
* @param col The color of the pixel.
*/
public void setPixel(int x, int y, Color col)
{
int pixel = col.getRGB();
setRGB(x, y, pixel);
}
/**
* Get the color value at a specified pixel position.
* @param x The x position of the pixel.
* @param y The y position of the pixel.
* @return The color of the pixel at the given position.
*/
public Color getPixel(int x, int y)
{
int pixel = getRGB(x, y);
return new Color(pixel);
}
/**
* Make this image a bit darker.
*/
public void darker()
{
int height = getHeight();
int width = getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
setPixel(x, y, getPixel(x, y).darker());
}
}
}
/**
* Make this image a bit lighter.
*/
public void lighter()
{
int height = getHeight();
int width = getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
setPixel(x, y, getPixel(x, y).brighter());
}
}
}
/**
* Perform a three level threshold operation.
* That is: repaint the image with only three color values:
* white, gray, and black.
*/
public void threshold()
{
int height = getHeight();
int width = getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
Color pixel = getPixel(x, y);
int brightness = (pixel.getRed() + pixel.getBlue() + pixel.getGreen()) / 3;
if(brightness <= 85) {
setPixel(x, y, Color.BLACK);
}
else if(brightness <= 170) {
setPixel(x, y, Color.GRAY);
}
else {
setPixel(x, y, Color.WHITE);
}
}
}
}
}

View File

@@ -0,0 +1,17 @@
Project: imageviewer, version 1.0
Authors: David Barnes and Michael Kölling
This project is part of the material for the book
Objects First with Java - A Practical Introduction using BlueJ
Sixth edition
David J. Barnes and Michael Kölling
Pearson Education, 2016
It is discussed in chapter 13.
To use this project, create an instance of class ImageViewer.
This version is the first completed version of this project. It is not
perfect, but at least it can display some images.
For details, refer to the book chapter.

View File

@@ -0,0 +1,83 @@
#BlueJ package file
dependency1.from=ImageViewer
dependency1.to=OFImage
dependency1.type=UsesDependency
dependency2.from=ImageViewer
dependency2.to=ImagePanel
dependency2.type=UsesDependency
dependency3.from=ImageFileManager
dependency3.to=OFImage
dependency3.type=UsesDependency
dependency4.from=ImagePanel
dependency4.to=OFImage
dependency4.type=UsesDependency
dependency5.from=ImageViewer
dependency5.to=ImageFileManager
dependency5.type=UsesDependency
objectbench.height=76
objectbench.width=784
package.editor.height=456
package.editor.width=676
package.editor.x=70
package.editor.y=80
package.numDependencies=5
package.numTargets=4
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=492
readme.editor.width=809
readme.editor.x=53
readme.editor.y=95
target1.editor.height=727
target1.editor.width=966
target1.editor.x=53
target1.editor.y=23
target1.height=60
target1.name=OFImage
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=120
target1.x=310
target1.y=330
target2.editor.height=730
target2.editor.width=911
target2.editor.x=520
target2.editor.y=51
target2.height=60
target2.name=ImageFileManager
target2.naviview.expanded=true
target2.showInterface=false
target2.type=ClassTarget
target2.typeParameters=
target2.width=140
target2.x=410
target2.y=160
target3.editor.height=777
target3.editor.width=989
target3.editor.x=55
target3.editor.y=23
target3.height=60
target3.name=ImageViewer
target3.naviview.expanded=true
target3.showInterface=false
target3.type=ClassTarget
target3.typeParameters=
target3.width=120
target3.x=200
target3.y=60
target4.editor.height=731
target4.editor.width=903
target4.editor.x=53
target4.editor.y=60
target4.height=60
target4.name=ImagePanel
target4.naviview.expanded=true
target4.showInterface=false
target4.type=ClassTarget
target4.typeParameters=
target4.width=110
target4.x=80
target4.y=200

View File

@@ -0,0 +1,5 @@
#BlueJ class context
comment0.params=name
comment0.target=DarkerFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ DarkerFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
numComments=1

View File

@@ -0,0 +1,33 @@
/**
* An image filter to make the image a bit darker.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class DarkerFilter extends Filter
{
/**
* Constructor for objects of class DarkerFilter.
* @param name The name of the filter.
*/
public DarkerFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
image.setPixel(x, y, image.getPixel(x, y).darker());
}
}
}
}

View File

@@ -0,0 +1,8 @@
#BlueJ class context
comment0.params=name
comment0.target=Filter(java.lang.String)
comment0.text=\n\ Create\ a\ new\ filter\ with\ a\ given\ name.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
comment1.params=
comment1.target=java.lang.String\ getName()
comment1.text=\n\ Return\ the\ name\ of\ this\ filter.\n\ \n\ @return\ \ The\ name\ of\ this\ filter.\n
numComments=2

View File

@@ -0,0 +1,38 @@
/**
* Filter is an abstract superclass for all image filters in this
* application. Filters can be applied to OFImages by invoking the apply
* method.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public abstract class Filter
{
private String name;
/**
* Create a new filter with a given name.
* @param name The name of the filter.
*/
public Filter(String name)
{
this.name = name;
}
/**
* Return the name of this filter.
*
* @return The name of this filter.
*/
public String getName()
{
return name;
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public abstract void apply(OFImage image);
}

View File

@@ -0,0 +1,2 @@
#BlueJ class context
numComments=0

View File

@@ -0,0 +1,61 @@
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
/**
* ImageFileManager is a small utility class with static methods to load
* and save images.
*
* The files on disk can be in JPG or PNG image format. For files written
* by this class, the format is determined by the constant IMAGE_FORMAT.
*
* @author Michael Kölling and David J. Barnes.
* @version 2.0
*/
public class ImageFileManager
{
// A constant for the image format that this writer uses for writing.
// Available formats are "jpg" and "png".
private static final String IMAGE_FORMAT = "jpg";
/**
* Read an image file from disk and return it as an image. This method
* can read JPG and PNG file formats. In case of any problem (e.g the file
* does not exist, is in an undecodable format, or any other read error)
* this method returns null.
*
* @param imageFile The image file to be loaded.
* @return The image object or null is it could not be read.
*/
public static OFImage loadImage(File imageFile)
{
try {
BufferedImage image = ImageIO.read(imageFile);
if(image == null || (image.getWidth(null) < 0)) {
// we could not load the image - probably invalid file format
return null;
}
return new OFImage(image);
}
catch(IOException exc) {
return null;
}
}
/**
* Write an image file to disk. The file format is JPG. In case of any
* problem the method just silently returns.
*
* @param image The image to be saved.
* @param file The file to save to.
*/
public static void saveImage(OFImage image, File file)
{
try {
ImageIO.write(image, IMAGE_FORMAT, file);
}
catch(IOException exc) {
return;
}
}
}

View File

@@ -0,0 +1,14 @@
#BlueJ class context
comment0.params=
comment0.target=ImagePanel()
comment0.text=\n\ Create\ a\ new,\ empty\ ImagePanel.\n
comment1.params=
comment1.target=void\ clearImage()
comment1.text=\n\ Clear\ the\ image\ on\ this\ panel.\n
comment2.params=
comment2.target=java.awt.Dimension\ getPreferredSize()
comment2.text=\n\ Tell\ the\ layout\ manager\ how\ big\ we\ would\ like\ to\ be.\n\ (This\ method\ gets\ called\ by\ layout\ managers\ for\ placing\n\ the\ components.)\n\ \n\ @return\ The\ preferred\ dimension\ for\ this\ component.\n
comment3.params=g
comment3.target=void\ paintComponent(java.awt.Graphics)
comment3.text=\n\ This\ component\ needs\ to\ be\ redisplayed.\ Copy\ the\ internal\ image\ \n\ to\ screen.\ (This\ method\ gets\ called\ by\ the\ Swing\ screen\ painter\ \n\ every\ time\ it\ want\ this\ component\ displayed.)\n\ \n\ @param\ g\ The\ graphics\ context\ that\ can\ be\ used\ to\ draw\ on\ this\ component.\n
numComments=4

View File

@@ -0,0 +1,89 @@
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
/**
* An ImagePanel is a Swing component that can display an OFImage.
* It is constructed as a subclass of JComponent with the added functionality
* of setting an OFImage that will be displayed on the surface of this
* component.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class ImagePanel extends JComponent
{
// The current width and height of this panel
private int width, height;
// An internal image buffer that is used for painting. For
// actual display, this image buffer is then copied to screen.
private OFImage panelImage;
/**
* Create a new, empty ImagePanel.
*/
public ImagePanel()
{
width = 360; // arbitrary size for empty panel
height = 240;
panelImage = null;
}
/**
* Set the image that this panel should show.
*
* @param image The image to be displayed.
*/
public void setImage(OFImage image)
{
if(image != null) {
width = image.getWidth();
height = image.getHeight();
panelImage = image;
repaint();
}
}
/**
* Clear the image on this panel.
*/
public void clearImage()
{
Graphics imageGraphics = panelImage.getGraphics();
imageGraphics.setColor(Color.LIGHT_GRAY);
imageGraphics.fillRect(0, 0, width, height);
repaint();
}
// The following methods are redefinitions of methods
// inherited from superclasses.
/**
* Tell the layout manager how big we would like to be.
* (This method gets called by layout managers for placing
* the components.)
*
* @return The preferred dimension for this component.
*/
public Dimension getPreferredSize()
{
return new Dimension(width, height);
}
/**
* This component needs to be redisplayed. Copy the internal image
* to screen. (This method gets called by the Swing screen painter
* every time it want this component displayed.)
*
* @param g The graphics context that can be used to draw on this component.
*/
public void paintComponent(Graphics g)
{
Dimension size = getSize();
g.clearRect(0, 0, size.width, size.height);
if(panelImage != null) {
g.drawImage(panelImage, 0, 0, null);
}
}
}

View File

@@ -0,0 +1,35 @@
#BlueJ class context
comment0.params=
comment0.target=ImageViewer()
comment0.text=\n\ Create\ an\ ImageViewer\ show\ it\ on\ screen.\n
comment1.params=
comment1.target=void\ openFile()
comment1.text=\n\ Open\ function\:\ open\ a\ file\ chooser\ to\ select\ a\ new\ image\ file.\n
comment10.params=frame
comment10.target=void\ makeMenuBar(javax.swing.JFrame)
comment10.text=\n\ Create\ the\ main\ frame's\ menu\ bar.\n\ @param\ frame\ \ \ The\ frame\ that\ the\ menu\ bar\ should\ be\ added\ to.\n
comment2.params=
comment2.target=void\ close()
comment2.text=\n\ Close\ function\:\ close\ the\ current\ image.\n
comment3.params=
comment3.target=void\ quit()
comment3.text=\n\ Quit\ function\:\ quit\ the\ application.\n
comment4.params=filter
comment4.target=void\ applyFilter(Filter)
comment4.text=\n\ Apply\ a\ given\ filter\ to\ the\ current\ image.\n\ @param\ filter\ The\ filter\ to\ be\ applied.\n
comment5.params=
comment5.target=void\ showAbout()
comment5.text=\n\ Show\ the\ 'About...'\ dialog.\n
comment6.params=filename
comment6.target=void\ showFilename(java.lang.String)
comment6.text=\n\ Display\ a\ file\ name\ on\ the\ appropriate\ label.\n\ @param\ filename\ The\ file\ name\ to\ be\ displayed.\n
comment7.params=text
comment7.target=void\ showStatus(java.lang.String)
comment7.text=\n\ Display\ a\ status\ message\ in\ the\ frame's\ status\ bar.\n
comment8.params=
comment8.target=java.util.List\ createFilters()
comment8.text=\n\ Create\ and\ return\ a\ list\ with\ all\ the\ known\ filters.\n\ @return\ The\ list\ of\ filters.\n
comment9.params=
comment9.target=void\ makeFrame()
comment9.text=\n\ Create\ the\ Swing\ frame\ and\ its\ content.\n
numComments=11

View File

@@ -0,0 +1,248 @@
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.io.File;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
/**
* ImageViewer is the main class of the image viewer application. It builds and
* displays the application GUI and initialises all other components.
*
* To start the application, create an object of this class.
*
* @author Michael Kölling and David J. Barnes.
* @version 2.0
*/
public class ImageViewer
{
// static fields:
private static final String VERSION = "Version 2.0";
private static JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));
// fields:
private JFrame frame;
private ImagePanel imagePanel;
private JLabel filenameLabel;
private JLabel statusLabel;
private OFImage currentImage;
private List<Filter> filters;
/**
* Create an ImageViewer show it on screen.
*/
public ImageViewer()
{
currentImage = null;
filters = createFilters();
makeFrame();
}
// ---- implementation of menu functions ----
/**
* Open function: open a file chooser to select a new image file.
*/
private void openFile()
{
int returnVal = fileChooser.showOpenDialog(frame);
if(returnVal != JFileChooser.APPROVE_OPTION) {
return; // cancelled
}
File selectedFile = fileChooser.getSelectedFile();
currentImage = ImageFileManager.loadImage(selectedFile);
if(currentImage == null) { // image file was not a valid image
JOptionPane.showMessageDialog(frame,
"The file was not in a recognized image file format.",
"Image Load Error",
JOptionPane.ERROR_MESSAGE);
return;
}
imagePanel.setImage(currentImage);
showFilename(selectedFile.getPath());
showStatus("File loaded.");
frame.pack();
}
/**
* Close function: close the current image.
*/
private void close()
{
currentImage = null;
imagePanel.clearImage();
showFilename(null);
}
/**
* Quit function: quit the application.
*/
private void quit()
{
System.exit(0);
}
/**
* Apply a given filter to the current image.
* @param filter The filter to be applied.
*/
private void applyFilter(Filter filter)
{
if(currentImage != null) {
filter.apply(currentImage);
frame.repaint();
showStatus("Applied: " + filter.getName());
}
else {
showStatus("No image loaded.");
}
}
/**
* Show the 'About...' dialog.
*/
private void showAbout()
{
JOptionPane.showMessageDialog(frame,
"ImageViewer\n" + VERSION,
"About ImageViewer",
JOptionPane.INFORMATION_MESSAGE);
}
// ---- support methods ----
/**
* Display a file name on the appropriate label.
* @param filename The file name to be displayed.
*/
private void showFilename(String filename)
{
if(filename == null) {
filenameLabel.setText("No file displayed.");
}
else {
filenameLabel.setText("File: " + filename);
}
}
/**
* Display a status message in the frame's status bar.
*/
private void showStatus(String text)
{
statusLabel.setText(text);
}
/**
* Create and return a list with all the known filters.
* @return The list of filters.
*/
private List<Filter> createFilters()
{
List<Filter> filterList = new ArrayList<>();
filterList.add(new DarkerFilter("Darker"));
filterList.add(new LighterFilter("Lighter"));
filterList.add(new ThresholdFilter("Threshold"));
return filterList;
}
// ---- swing stuff to build the frame and all its components ----
/**
* Create the Swing frame and its content.
*/
private void makeFrame()
{
frame = new JFrame("ImageViewer");
Container contentPane = frame.getContentPane();
makeMenuBar(frame);
// Specify the layout manager with nice spacing
contentPane.setLayout(new BorderLayout(6, 6));
filenameLabel = new JLabel();
contentPane.add(filenameLabel, BorderLayout.NORTH);
imagePanel = new ImagePanel();
contentPane.add(imagePanel, BorderLayout.CENTER);
statusLabel = new JLabel(VERSION);
contentPane.add(statusLabel, BorderLayout.SOUTH);
// building is done - arrange the components and show
showFilename(null);
frame.pack();
// center the frame on screen
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);
frame.setVisible(true);
}
/**
* Create the main frame's menu bar.
* @param frame The frame that the menu bar should be added to.
*/
private void makeMenuBar(JFrame frame)
{
final int SHORTCUT_MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
JMenuBar menubar = new JMenuBar();
frame.setJMenuBar(menubar);
JMenu menu;
JMenuItem item;
// create the File menu
menu = new JMenu("File");
menubar.add(menu);
item = new JMenuItem("Open");
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_MASK));
item.addActionListener(e -> openFile());
menu.add(item);
item = new JMenuItem("Close");
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, SHORTCUT_MASK));
item.addActionListener(e -> close());
menu.add(item);
menu.addSeparator();
item = new JMenuItem("Quit");
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));
item.addActionListener(e -> quit());
menu.add(item);
// create the Filter menu
menu = new JMenu("Filter");
menubar.add(menu);
for(Filter filter : filters) {
item = new JMenuItem(filter.getName());
item.addActionListener(e -> applyFilter(filter));
menu.add(item);
}
// create the Help menu
menu = new JMenu("Help");
menubar.add(menu);
item = new JMenuItem("About ImageViewer...");
item.addActionListener(e -> showAbout());
menu.add(item);
}
}

View File

@@ -0,0 +1,5 @@
#BlueJ class context
comment0.params=name
comment0.target=LighterFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ LighterFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
numComments=1

View File

@@ -0,0 +1,34 @@
/**
* An image filter to make the image a bit lighter.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class LighterFilter extends Filter
{
/**
* Constructor for objects of class LighterFilter.
* @param name The name of the filter.
*/
public LighterFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
image.setPixel(x, y, image.getPixel(x, y).brighter());
}
}
}
}

View File

@@ -0,0 +1,14 @@
#BlueJ class context
comment0.params=image
comment0.target=OFImage(java.awt.image.BufferedImage)
comment0.text=\n\ Create\ an\ OFImage\ copied\ from\ a\ BufferedImage.\n\ @param\ image\ The\ image\ to\ copy.\n
comment1.params=width\ height
comment1.target=OFImage(int,\ int)
comment1.text=\n\ Create\ an\ OFImage\ with\ specified\ size\ and\ unspecified\ content.\n\ @param\ width\ The\ width\ of\ the\ image.\n\ @param\ height\ The\ height\ of\ the\ image.\n
comment2.params=x\ y\ col
comment2.target=void\ setPixel(int,\ int,\ java.awt.Color)
comment2.text=\n\ Set\ a\ given\ pixel\ of\ this\ image\ to\ a\ specified\ color.\ The\n\ color\ is\ represented\ as\ an\ (r,g,b)\ value.\n\ @param\ x\ The\ x\ position\ of\ the\ pixel.\n\ @param\ y\ The\ y\ position\ of\ the\ pixel.\n\ @param\ col\ The\ color\ of\ the\ pixel.\n
comment3.params=x\ y
comment3.target=java.awt.Color\ getPixel(int,\ int)
comment3.text=\n\ Get\ the\ color\ value\ at\ a\ specified\ pixel\ position.\n\ @param\ x\ The\ x\ position\ of\ the\ pixel.\n\ @param\ y\ The\ y\ position\ of\ the\ pixel.\n\ @return\ The\ color\ of\ the\ pixel\ at\ the\ given\ position.\n
numComments=4

View File

@@ -0,0 +1,57 @@
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
/**
* OFImage is a class that defines an image in OF (Objects First) format.
*
* @author Michael Kölling and David J. Barnes.
* @version 2.0
*/
public class OFImage extends BufferedImage
{
/**
* Create an OFImage copied from a BufferedImage.
* @param image The image to copy.
*/
public OFImage(BufferedImage image)
{
super(image.getColorModel(), image.copyData(null),
image.isAlphaPremultiplied(), null);
}
/**
* Create an OFImage with specified size and unspecified content.
* @param width The width of the image.
* @param height The height of the image.
*/
public OFImage(int width, int height)
{
super(width, height, TYPE_INT_RGB);
}
/**
* Set a given pixel of this image to a specified color. The
* color is represented as an (r,g,b) value.
* @param x The x position of the pixel.
* @param y The y position of the pixel.
* @param col The color of the pixel.
*/
public void setPixel(int x, int y, Color col)
{
int pixel = col.getRGB();
setRGB(x, y, pixel);
}
/**
* Get the color value at a specified pixel position.
* @param x The x position of the pixel.
* @param y The y position of the pixel.
* @return The color of the pixel at the given position.
*/
public Color getPixel(int x, int y)
{
int pixel = getRGB(x, y);
return new Color(pixel);
}
}

View File

@@ -0,0 +1,16 @@
Project: imageviewer, version 2.0
Authors: David Barnes and Michael Kölling
This project is part of the material for the book
Objects First with Java - A Practical Introduction using BlueJ
Sixth edition
David J. Barnes and Michael Kölling
Pearson Education, 2016
It is discussed in chapter 13.
To use this project, create an instance of class ImageViewer.
This version refactors some of the code to improve its structure.
For details, refer to the book chapter.

View File

@@ -0,0 +1,5 @@
#BlueJ class context
comment0.params=name
comment0.target=ThresholdFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ ThresholdFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
numComments=1

View File

@@ -0,0 +1,45 @@
import java.awt.Color;
/**
* An three-level gray-based threshold filter.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class ThresholdFilter extends Filter
{
/**
* Constructor for objects of class ThresholdFilter.
* @param name The name of the filter.
*/
public ThresholdFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
Color pixel = image.getPixel(x, y);
int brightness = (pixel.getRed() + pixel.getBlue() + pixel.getGreen()) / 3;
if(brightness <= 85) {
image.setPixel(x, y, Color.BLACK);
}
else if(brightness <= 170) {
image.setPixel(x, y, Color.GRAY);
}
else {
image.setPixel(x, y, Color.WHITE);
}
}
}
}
}

View File

@@ -0,0 +1,159 @@
#BlueJ package file
dependency1.from=Filter
dependency1.to=OFImage
dependency1.type=UsesDependency
dependency10.from=DarkerFilter
dependency10.to=OFImage
dependency10.type=UsesDependency
dependency11.from=ImageFileManager
dependency11.to=OFImage
dependency11.type=UsesDependency
dependency12.from=ThresholdFilter
dependency12.to=OFImage
dependency12.type=UsesDependency
dependency13.from=ImagePanel
dependency13.to=OFImage
dependency13.type=UsesDependency
dependency2.from=ImageViewer
dependency2.to=ImagePanel
dependency2.type=UsesDependency
dependency3.from=ImageViewer
dependency3.to=OFImage
dependency3.type=UsesDependency
dependency4.from=ImageViewer
dependency4.to=ImageFileManager
dependency4.type=UsesDependency
dependency5.from=ImageViewer
dependency5.to=Filter
dependency5.type=UsesDependency
dependency6.from=ImageViewer
dependency6.to=DarkerFilter
dependency6.type=UsesDependency
dependency7.from=ImageViewer
dependency7.to=LighterFilter
dependency7.type=UsesDependency
dependency8.from=ImageViewer
dependency8.to=ThresholdFilter
dependency8.type=UsesDependency
dependency9.from=LighterFilter
dependency9.to=OFImage
dependency9.type=UsesDependency
objectbench.height=76
objectbench.width=948
package.editor.height=514
package.editor.width=840
package.editor.x=70
package.editor.y=80
package.numDependencies=13
package.numTargets=8
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=560
readme.editor.width=828
readme.editor.x=53
readme.editor.y=23
target1.editor.height=734
target1.editor.width=935
target1.editor.x=50
target1.editor.y=60
target1.height=60
target1.name=ThresholdFilter
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=110
target1.x=690
target1.y=290
target2.editor.height=728
target2.editor.width=880
target2.editor.x=50
target2.editor.y=60
target2.height=60
target2.name=LighterFilter
target2.naviview.expanded=true
target2.showInterface=false
target2.type=ClassTarget
target2.typeParameters=
target2.width=100
target2.x=570
target2.y=290
target3.editor.height=700
target3.editor.width=900
target3.editor.x=0
target3.editor.y=22
target3.height=60
target3.name=OFImage
target3.naviview.expanded=true
target3.showInterface=false
target3.type=ClassTarget
target3.typeParameters=
target3.width=110
target3.x=90
target3.y=420
target4.editor.height=728
target4.editor.width=856
target4.editor.x=317
target4.editor.y=35
target4.height=60
target4.name=Filter
target4.naviview.expanded=true
target4.showInterface=false
target4.type=AbstractTarget
target4.typeParameters=
target4.width=100
target4.x=570
target4.y=180
target5.editor.height=726
target5.editor.width=851
target5.editor.x=327
target5.editor.y=36
target5.height=60
target5.name=DarkerFilter
target5.naviview.expanded=true
target5.showInterface=false
target5.type=ClassTarget
target5.typeParameters=
target5.width=100
target5.x=450
target5.y=290
target6.editor.height=732
target6.editor.width=926
target6.editor.x=50
target6.editor.y=60
target6.height=60
target6.name=ImageFileManager
target6.naviview.expanded=true
target6.showInterface=false
target6.type=ClassTarget
target6.typeParameters=
target6.width=140
target6.x=60
target6.y=130
target7.editor.height=739
target7.editor.width=875
target7.editor.x=41
target7.editor.y=23
target7.height=60
target7.name=ImageViewer
target7.naviview.expanded=true
target7.showInterface=false
target7.type=ClassTarget
target7.typeParameters=
target7.width=110
target7.x=240
target7.y=40
target8.editor.height=726
target8.editor.width=879
target8.editor.x=50
target8.editor.y=60
target8.height=60
target8.name=ImagePanel
target8.naviview.expanded=true
target8.showInterface=false
target8.type=ClassTarget
target8.typeParameters=
target8.width=140
target8.x=60
target8.y=210

View File

@@ -0,0 +1,5 @@
#BlueJ class context
comment0.params=name
comment0.target=DarkerFilter(java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ DarkerFilter.\n\ @param\ name\ The\ name\ of\ the\ filter.\n
numComments=1

View File

@@ -0,0 +1,33 @@
/**
* An image filter to make the image a bit darker.
*
* @author Michael Kölling and David J. Barnes.
* @version 1.0
*/
public class DarkerFilter extends Filter
{
/**
* Constructor for objects of class DarkerFilter.
* @param name The name of the filter.
*/
public DarkerFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
image.setPixel(x, y, image.getPixel(x, y).darker());
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More