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

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