/*
This program is a part of the companion code for Core Java 8th ed.
(http://horstmann.com/corejava)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.LookupOp;
import java.awt.image.RescaleOp;
import java.awt.image.ShortLookupTable;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
/**
* This program demonstrates various image processing operations.
* @version 1.03 2007-08-16
* @author Cay Horstmann
*/
public class ImageProcessingTest
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new ImageProcessingFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
/**
* This frame has a menu to load an image and to specify various transformations, and a component to
* show the resulting image.
*/
class ImageProcessingFrame extends JFrame
{
public ImageProcessingFrame()
{
setTitle("ImageProcessingTest");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
add(new JComponent()
{
public void paintComponent(Graphics g)
{
if (image != null) g.drawImage(image, 0, 0, null);
}
});
JMenu fileMenu = new JMenu("File");
JMenuItem openItem = new JMenuItem("Open");
openItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
openFile();
}
});
fileMenu.add(openItem);
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
System.exit(0);
}
});
fileMenu.add(exitItem);
JMenu editMenu = new JMenu("Edit");
JMenuItem blurItem = new JMenuItem("Blur");
blurItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
float weight = 1.0f / 9.0f;
float[] elements = new float[9];
for (int i = 0; i < 9; i++)
elements[i] = weight;
convolve(elements);
}
});
editMenu.add(blurItem);
JMenuItem sharpenItem = new JMenuItem("Sharpen");
sharpenItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
float[] elements = { 0.0f, -1.0f, 0.0f, -1.0f, 5.f, -1.0f, 0.0f, -1.0f, 0.0f };
convolve(elements);
}
});
editMenu.add(sharpenItem);
JMenuItem brightenItem = new JMenuItem("Brighten");
brightenItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
float a = 1.1f;
// float b = 20.0f;
float b = 0;
RescaleOp op = new RescaleOp(a, b, null);
filter(op);
}
});
editMenu.add(brightenItem);
JMenuItem edgeDetectItem = new JMenuItem("Edge detect");
edgeDetectItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
float[] elements = { 0.0f, -1.0f, 0.0f, -1.0f, 4.f, -1.0f, 0.0f, -1.0f, 0.0f };
convolve(elements);
}
});
editMenu.add(edgeDetectItem);
JMenuItem negativeItem = new JMenuItem("Negative");
negativeItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
short[] negative = new short[256 * 1];
for (int i = 0; i < 256; i++)
negative[i] = (short) (255 - i);
ShortLookupTable table = new ShortLookupTable(0, negative);
LookupOp op = new LookupOp(table, null);
filter(op);
}
});
editMenu.add(negativeItem);
JMenuItem rotateItem = new JMenuItem("Rotate");
rotateItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if (image == null) return;
AffineTransform transform = AffineTransform.getRotateInstance(Math.toRadians(5),
image.getWidth() / 2, image.getHeight() / 2);
AffineTransformOp op = new AffineTransformOp(transform,
AffineTransformOp.TYPE_BICUBIC);
filter(op);
}
});
editMenu.add(rotateItem);
JMenuBar menuBar = new JMenuBar();
menuBar.add(fileMenu);
menuBar.add(editMenu);
setJMenuBar(menuBar);
}
/**
* Open a file and load the image.
*/
public void openFile()
{
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("."));
String[] extensions = ImageIO.getReaderFileSuffixes();
chooser.setFileFilter(new FileNameExtensionFilter("Image files", extensions));
int r = chooser.showOpenDialog(this);
if (r != JFileChooser.APPROVE_OPTION) return;
try
{
Image img = ImageIO.read(chooser.getSelectedFile());
image = new BufferedImage(img.getWidth(null), img.getHeight(null),
BufferedImage.TYPE_INT_RGB);
image.getGraphics().drawImage(img, 0, 0, null);
}
catch (IOException e)
{
JOptionPane.showMessageDialog(this, e);
}
repaint();
}
/**
* Apply a filter and repaint.
* @param op the image operation to apply
*/
private void filter(BufferedImageOp op)
{
if (image == null) return;
image = op.filter(image, null);
repaint();
}
/**
* Apply a convolution and repaint.
* @param elements the convolution kernel (an array of 9 matrix elements)
*/
private void convolve(float[] elements)
{
Kernel kernel = new Kernel(3, 3, elements);
ConvolveOp op = new ConvolveOp(kernel);
filter(op);
}
private BufferedImage image;
private static final int DEFAULT_WIDTH = 400;
private static final int DEFAULT_HEIGHT = 400;
}
|