Java/2D Graphics GUI/Image
Содержание
- 1 Adding Image-Dragging Behavior
- 2 A frame that displays an image
- 3 Calculation of the mean value of an image with Raster
- 4 Convert java.awt.image.BufferedImage to java.awt.Image
- 5 Create a filter that can modify any of the RGB pixel values in an image.
- 6 Create Gradient Image
- 7 Create Gradient Mask
- 8 Create Translucent Image
- 9 Demonstrating the Drawing of an Image with a Convolve Operation
- 10 Demonstrating Use of the Image I/O Library
- 11 Double Buffered Image
- 12 Drags within the image
- 13 Filter image by multiplier its red, green and blue color
- 14 Filtering the RGB Values in an Image
- 15 Flip an image
- 16 Get the dimensions of the image; these will be non-negative
- 17 Getting the Color Model of an Image
- 18 Graband Fade: displays image and fades to black
- 19 Graband Fade with Rasters
- 20 Image Animation and Thread
- 21 Image Buffering
- 22 Image Color Gray Effect
- 23 Image crop
- 24 Image demo
- 25 Image Effect: Combine
- 26 Image Effect: Rotate Image using DataBuffer
- 27 Image Effect: Sharpen, blur
- 28 Image Operations
- 29 Image Panel
- 30 Image Processing: Brightness and Contrast
- 31 Image scale
- 32 Image size
- 33 Image Utils
- 34 Image Viewer
- 35 Image with mouse drag and move event
- 36 Load and draw image
- 37 Make Raster Writable
- 38 Optimized version of copyData designed to work on Integer packed data with a SinglePixelPackedSampleModel
- 39 Paint an Icon
- 40 Pixels from a buffered image can be modified
- 41 Rendered Image
- 42 Returns an image resource.
- 43 Rotate Image 45 Degrees
- 44 Sending Image Objects through the Clipboard
- 45 Standalone Image Viewer - works with any AWT-supported format
- 46 This filter removes all but the red values in an image
- 47 Toolkit.getImage() which works the same in either Applet or Application
- 48 TYPE_INT_RGB and TYPE_INT_ARGB are typically used
- 49 Use PixelGrabber class to acquire pixel data from an Image object
Adding Image-Dragging Behavior
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.TransferHandler;
public class DragImage {
public static void main(String args[]) {
JFrame frame = new JFrame("Clip Image");
Container contentPane = frame.getContentPane();
final Clipboard clipboard = frame.getToolkit().getSystemClipboard();
Icon icon = new ImageIcon("jaeger.jpg");
final JLabel label = new JLabel(icon);
label.setTransferHandler(new ImageSelection());
MouseListener mouseListener = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
JComponent comp = (JComponent) e.getSource();
TransferHandler handler = comp.getTransferHandler();
handler.exportAsDrag(comp, e, TransferHandler.COPY);
}
};
label.addMouseListener(mouseListener);
JScrollPane pane = new JScrollPane(label);
contentPane.add(pane, BorderLayout.CENTER);
JButton copy = new JButton("Copy");
copy.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
TransferHandler handler = label.getTransferHandler();
handler.exportToClipboard(label, clipboard,
TransferHandler.COPY);
}
});
JButton clear = new JButton("Clear");
clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
label.setIcon(null);
}
});
clear.setTransferHandler(new TransferHandler("text"));
mouseListener = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
JComponent comp = (JComponent) e.getSource();
TransferHandler handler = comp.getTransferHandler();
handler.exportAsDrag(comp, e, TransferHandler.COPY);
}
};
clear.addMouseListener(mouseListener);
JButton paste = new JButton("Paste");
paste.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
Transferable clipData = clipboard.getContents(clipboard);
if (clipData != null) {
if (clipData.isDataFlavorSupported(DataFlavor.imageFlavor)) {
TransferHandler handler = label.getTransferHandler();
handler.importData(label, clipData);
}
}
}
});
JPanel p = new JPanel();
p.add(copy);
p.add(clear);
p.add(paste);
contentPane.add(p, BorderLayout.SOUTH);
JTextField tf = new JTextField();
tf.setDragEnabled(true);
contentPane.add(tf, BorderLayout.NORTH);
frame.setSize(300, 300);
frame.show();
}
}
class ImageSelection extends TransferHandler implements Transferable {
private static final DataFlavor flavors[] = { DataFlavor.imageFlavor };
private JLabel source;
private Image image;
public int getSourceActions(JComponent c) {
return TransferHandler.COPY;
}
public boolean canImport(JComponent comp, DataFlavor flavor[]) {
if (!(comp instanceof JLabel)) {
return false;
}
for (int i = 0, n = flavor.length; i < n; i++) {
for (int j = 0, m = flavors.length; j < m; j++) {
if (flavor[i].equals(flavors[j])) {
return true;
}
}
}
return false;
}
public Transferable createTransferable(JComponent comp) {
// Clear
source = null;
image = null;
if (comp instanceof JLabel) {
JLabel label = (JLabel) comp;
Icon icon = label.getIcon();
if (icon instanceof ImageIcon) {
image = ((ImageIcon) icon).getImage();
source = label;
return this;
}
}
return null;
}
public boolean importData(JComponent comp, Transferable t) {
if (comp instanceof JLabel) {
JLabel label = (JLabel) comp;
if (t.isDataFlavorSupported(flavors[0])) {
try {
image = (Image) t.getTransferData(flavors[0]);
ImageIcon icon = new ImageIcon(image);
label.setIcon(icon);
return true;
} catch (UnsupportedFlavorException ignored) {
} catch (IOException ignored) {
}
}
}
return false;
}
// Transferable
public Object getTransferData(DataFlavor flavor) {
if (isDataFlavorSupported(flavor)) {
return image;
}
return null;
}
public DataFlavor[] getTransferDataFlavors() {
return flavors;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(DataFlavor.imageFlavor);
}
}
A frame that displays an image
/*
* @(#)ImageFrame.java 0.90 9/19/00 Adam Doppelt
*/
import java.awt.*;
import java.awt.image.MemoryImageSource;
import java.io.File;
import java.io.IOException;
/**
* A frame that displays an image. Create an ImageFrame, then use one
* of the setImage() methods to show the image.
*
* @version 0.90 19 Sep 2000
* @author
*/
public class ImageFrame extends Frame {
int left = -1;
int top;
Image image;
ImageFrame() {
setLayout(null);
setSize(100, 100);
}
/**
* Set the image from a file.
*/
public void setImage(File file) throws IOException {
// load the image
Image image = getToolkit().getImage(file.getAbsolutePath());
// wait for the image to entirely load
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(image, 0);
try {
tracker.waitForID(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tracker.statusID(0, true) != MediaTracker.ruPLETE) {
throw new IOException("Could not load: " + file + " " +
tracker.statusID(0, true));
}
setTitle(file.getName());
setImage(image);
}
/**
* Set the image from an AWT image object.
*/
public void setImage(Image image) {
this.image = image;
setVisible(true);
}
/**
* Set the image from an indexed color array.
*/
public void setImage(int palette[], int pixels[][]) {
int w = pixels.length;
int h = pixels[0].length;
int pix[] = new int[w * h];
// convert to RGB
for (int x = w; x-- > 0; ) {
for (int y = h; y-- > 0; ) {
pix[y * w + x] = palette[pixels[x][y]];
}
}
setImage(w, h, pix);
}
/**
* Set the image from a 2D RGB pixel array.
*/
public void setImage(int pixels[][]) {
int w = pixels.length;
int h = pixels[0].length;
int pix[] = new int[w * h];
// convert to RGB
for (int x = w; x-- > 0; ) {
for (int y = h; y-- > 0; ) {
pix[y * w + x] = pixels[x][y];
}
}
setImage(w, h, pix);
}
/**
* Set the image from a 1D RGB pixel array.
*/
public void setImage(int w, int h, int pix[]) {
setImage(createImage(new MemoryImageSource(w, h, pix, 0, w)));
}
/**
* Get the image.
*/
public Image getImage() {
return image;
}
/**
* Overridden for double buffering.
*/
public void update(Graphics g) {
paint(g);
}
/**
* Paint the image.
*/
public void paint(Graphics g) {
// the first time through, figure out where to draw the image
if (left == -1) {
Insets insets = getInsets();
left = insets.left;
top = insets.top;
setSize(image.getWidth(null) + left + insets.right,
image.getHeight(null) + top + insets.bottom);
}
g.drawImage(image, left, top, this);
}
public static void main(String args[]) throws IOException {
ImageFrame f = new ImageFrame();
f.setImage(new File(args[0]));
}
}
Calculation of the mean value of an image with Raster
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
public class Main {
public static void main(String[] argv) throws Exception {
}
public static double meanValue(BufferedImage image) {
Raster raster = image.getRaster();
double sum = 0.0;
for (int y = 0; y < image.getHeight(); ++y){
for (int x = 0; x < image.getWidth(); ++x){
sum += raster.getSample(x, y, 0);
}
}
return sum / (image.getWidth() * image.getHeight());
}
}
Convert java.awt.image.BufferedImage to java.awt.Image
/*
Java Media APIs: Cross-Platform Imaging, Media and Visualization
Alejandro Terrazas
Sams, Published November 2002,
ISBN 0672320940
*/
import java.awt.ruponent;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.image.BufferedImage;
/**
* BufferedImageConverter.java -- static class containing a method to convert a
* java.awt.image.BufferedImage into a java.awt.Image
*/
public class BufferedImageConverter {
// default version of createBufferedImage
static public BufferedImage createBufferedImage(Image imageIn,
Component comp) {
return createBufferedImage(imageIn, BufferedImage.TYPE_INT_ARGB, comp);
}
static public BufferedImage createBufferedImage(Image imageIn,
int imageType, Component comp) {
MediaTracker mt = new MediaTracker(comp);
mt.addImage(imageIn, 0);
try {
mt.waitForID(0);
} catch (InterruptedException ie) {
}
BufferedImage bufferedImageOut = new BufferedImage(imageIn
.getWidth(null), imageIn.getHeight(null), imageType);
Graphics g = bufferedImageOut.getGraphics();
g.drawImage(imageIn, 0, 0, null);
return bufferedImageOut;
}
}
Create a filter that can modify any of the RGB pixel values in an image.
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.RGBImageFilter;
import javax.swing.ImageIcon;
class GetRedFilter extends RGBImageFilter {
public GetRedFilter() {
canFilterIndexColorModel = true;
}
public int filterRGB(int x, int y, int rgb) {
if (x == -1) {
}
return rgb & 0xffff0000;
}
}
public class Main {
public static void main(String[] argv) throws Exception {
Image image = new ImageIcon("image.gif").getImage();
ImageFilter filter = new GetRedFilter();
FilteredImageSource filteredSrc = new FilteredImageSource(image.getSource(), filter);
image = Toolkit.getDefaultToolkit().createImage(filteredSrc);
}
}
Create Gradient Image
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
/**
*
* @author aim
*/
public class Utils {
public static BufferedImage createGradientImage(int width, int height, Color gradient1,
Color gradient2) {
BufferedImage gradientImage = createCompatibleImage(width, height);
GradientPaint gradient = new GradientPaint(0, 0, gradient1, 0, height, gradient2, false);
Graphics2D g2 = (Graphics2D) gradientImage.getGraphics();
g2.setPaint(gradient);
g2.fillRect(0, 0, width, height);
g2.dispose();
return gradientImage;
}
private static BufferedImage createCompatibleImage(int width, int height) {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()
.getDefaultConfiguration().createCompatibleImage(width, height);
}
}
Create Gradient Mask
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.SwingConstants;
/**
*
* @author aim
*/
public class Utils {
public static BufferedImage createGradientMask(int width, int height, int orientation) {
// algorithm derived from Romain Guy"s blog
BufferedImage gradient = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = gradient.createGraphics();
GradientPaint paint = new GradientPaint(0.0f, 0.0f,
new Color(1.0f, 1.0f, 1.0f, 1.0f),
orientation == SwingConstants.HORIZONTAL? width : 0.0f,
orientation == SwingConstants.VERTICAL? height : 0.0f,
new Color(1.0f, 1.0f, 1.0f, 0.0f));
g.setPaint(paint);
g.fill(new Rectangle2D.Double(0, 0, width, height));
g.dispose();
gradient.flush();
return gradient;
}
}
Create Translucent Image
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
/**
*
* @author aim
*/
public class Utils {
public static BufferedImage createTranslucentImage(int width, int height) {
return GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
}
}
Demonstrating the Drawing of an Image with a Convolve Operation
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class ConvolveIt extends JFrame {
Image image = getImage("jexp.jpg");
private static final float[] SHARP = { 0.0f, -1.0f, 0.0f, -1.0f, 5.0f,
-1.0f, 0.0f, -1.0f, 0.0f };
BufferedImage bufferedImage;
ConvolveOp convolveOp;
public Image getImage(String imageFile) {
ImageIcon icon = new ImageIcon(imageFile);
return icon.getImage();
}
public ConvolveIt() {
int width = image.getWidth(this);
int height = image.getHeight(this);
bufferedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D big = bufferedImage.createGraphics();
AffineTransform affineTransform = new AffineTransform();
big.drawImage(image, affineTransform, this);
Kernel kernel = new Kernel(3, 3, SHARP);
convolveOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
if (bufferedImage != null) {
g2d.drawImage(bufferedImage, convolveOp, 10, 30);
}
}
public static void main(String args[]) {
Frame f = new ConvolveIt();
f.setTitle("ConvolveIt");
f.setSize(300, 250);
f.show();
}
}
Demonstrating Use of the Image I/O Library
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class SaveIt {
private static final float[] SHARP = { 0.0f, -1.0f, 0.0f, -1.0f, 5.0f,
-1.0f, 0.0f, -1.0f, 0.0f };
public static void main(String args[]) throws IOException {
// Read
File inputFile = new File("jexp.jpg");
BufferedImage input = ImageIO.read(inputFile);
// Convert
Kernel kernel = new Kernel(3, 3, SHARP);
ConvolveOp convolveOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,
null);
int width = input.getWidth();
int height = input.getHeight();
BufferedImage output = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
convolveOp.filter(input, output);
// Save
File outputFile = new File("jexp.png");
ImageIO.write(output, "PNG", outputFile);
}
}
Double Buffered Image
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JApplet;
import javax.swing.JFrame;
public class DoubleBufferedImage extends JApplet {
private Image dbImage;
private Image originalImage;
private int xLocation = 0;
private int imageWidth, imageHeight;
private Graphics dbImageGraphics;
private String imageURLString = "file:/peppers.png";
public void init() {
URL url = null;
try {
url = new URL(imageURLString);
} catch (MalformedURLException me) {
showStatus("Malformed URL: " + me.getMessage());
}
originalImage = getImage(url);
MediaTracker mt = new MediaTracker(this);
mt.addImage(originalImage, 0);
try {
mt.waitForID(0);
} catch (InterruptedException ie) {
}
imageWidth = originalImage.getWidth(null);
imageHeight = originalImage.getHeight(null);
dbImage = this.createImage(imageWidth, imageHeight);
dbImageGraphics = dbImage.getGraphics();
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
if (xLocation == imageWidth)
xLocation = 0;
dbImageGraphics.clearRect(0, 0, imageWidth, imageHeight);
dbImageGraphics.drawImage(originalImage, 0, 0, this);
dbImageGraphics.setColor(Color.red);
dbImageGraphics.fillOval(xLocation, imageHeight / 2, 20, 20);
//now dbImage"s drawing area appears
g.drawImage(dbImage, 0, 0, this);
xLocation++;
repaint(10);
}
public static void main(String[] argv) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DoubleBufferedImage a = new DoubleBufferedImage();
frame.getContentPane().add(a);
frame.setSize(300, 300);
a.init();
a.start();
frame.setVisible(true);
}
}
Drags within the image
/*
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistribution of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/
/*
* SelectionDemo.java is a 1.4 application that requires one other file:
* images/starfield.gif
*/
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.event.MouseInputAdapter;
import java.awt.*;
import java.awt.event.MouseEvent;
/*
* This displays an image. When the user drags within the image, this program
* displays a rectangle and a string indicating the bounds of the rectangle.
*/
public class SelectionDemo {
JLabel label;
static String starFile = "starfield.gif";
private void buildUI(Container container, ImageIcon image) {
container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));
SelectionArea area = new SelectionArea(image, this);
container.add(area);
label = new JLabel("Drag within the image.");
label.setLabelFor(area);
container.add(label);
//Align the left edges of the components.
area.setAlignmentX(Component.LEFT_ALIGNMENT);
label.setAlignmentX(Component.LEFT_ALIGNMENT); //redundant
}
public void updateLabel(Rectangle rect) {
int width = rect.width;
int height = rect.height;
//Make the coordinates look OK if a dimension is 0.
if (width == 0) {
width = 1;
}
if (height == 0) {
height = 1;
}
label.setText("Rectangle goes from (" + rect.x + ", " + rect.y
+ ") to (" + (rect.x + width - 1) + ", "
+ (rect.y + height - 1) + ").");
}
/** Returns an ImageIcon, or null if the path was invalid. */
protected static ImageIcon createImageIcon(String path) {
java.net.URL imgURL = SelectionDemo.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn"t find file: " + path);
return null;
}
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
private static void createAndShowGUI() {
//Make sure we have nice window decorations.
JFrame.setDefaultLookAndFeelDecorated(true);
//Create and set up the window.
JFrame frame = new JFrame("SelectionDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane.
SelectionDemo controller = new SelectionDemo();
controller.buildUI(frame.getContentPane(), createImageIcon(starFile));
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application"s GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private class SelectionArea extends JLabel {
Rectangle currentRect = null;
Rectangle rectToDraw = null;
Rectangle previousRectDrawn = new Rectangle();
SelectionDemo controller;
public SelectionArea(ImageIcon image, SelectionDemo controller) {
super(image); //This component displays an image.
this.controller = controller;
setOpaque(true);
setMinimumSize(new Dimension(10, 10)); //don"t hog space
MyListener myListener = new MyListener();
addMouseListener(myListener);
addMouseMotionListener(myListener);
}
private class MyListener extends MouseInputAdapter {
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
currentRect = new Rectangle(x, y, 0, 0);
updateDrawableRect(getWidth(), getHeight());
repaint();
}
public void mouseDragged(MouseEvent e) {
updateSize(e);
}
public void mouseReleased(MouseEvent e) {
updateSize(e);
}
/*
* Update the size of the current rectangle and call repaint.
* Because currentRect always has the same origin, translate it if
* the width or height is negative.
*
* For efficiency (though that isn"t an issue for this program),
* specify the painting region using arguments to the repaint()
* call.
*
*/
void updateSize(MouseEvent e) {
int x = e.getX();
int y = e.getY();
currentRect.setSize(x - currentRect.x, y - currentRect.y);
updateDrawableRect(getWidth(), getHeight());
Rectangle totalRepaint = rectToDraw.union(previousRectDrawn);
repaint(totalRepaint.x, totalRepaint.y, totalRepaint.width,
totalRepaint.height);
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g); //paints the background and image
//If currentRect exists, paint a box on top.
if (currentRect != null) {
//Draw a rectangle on top of the image.
g.setXORMode(Color.white); //Color of line varies
//depending on image colors
g.drawRect(rectToDraw.x, rectToDraw.y, rectToDraw.width - 1,
rectToDraw.height - 1);
controller.updateLabel(rectToDraw);
}
}
private void updateDrawableRect(int compWidth, int compHeight) {
int x = currentRect.x;
int y = currentRect.y;
int width = currentRect.width;
int height = currentRect.height;
//Make the width and height positive, if necessary.
if (width < 0) {
width = 0 - width;
x = x - width + 1;
if (x < 0) {
width += x;
x = 0;
}
}
if (height < 0) {
height = 0 - height;
y = y - height + 1;
if (y < 0) {
height += y;
y = 0;
}
}
//The rectangle shouldn"t extend past the drawing area.
if ((x + width) > compWidth) {
width = compWidth - x;
}
if ((y + height) > compHeight) {
height = compHeight - y;
}
//Update rectToDraw after saving old value.
if (rectToDraw != null) {
previousRectDrawn.setBounds(rectToDraw.x, rectToDraw.y,
rectToDraw.width, rectToDraw.height);
rectToDraw.setBounds(x, y, width, height);
} else {
rectToDraw = new Rectangle(x, y, width, height);
}
}
}
}
Filter image by multiplier its red, green and blue color
/*
Java Media APIs: Cross-Platform Imaging, Media and Visualization
Alejandro Terrazas
Sams, Published November 2002,
ISBN 0672320940
*/
import java.awt.Color;
import java.awt.image.RGBImageFilter;
/**
* ColorComponentScaler -- filters an image by multiplier its red, green and
* blue color components by their given scale factors
*/
public class ColorComponentScaler extends RGBImageFilter {
private double redMultiplier, greenMultiplier, blueMultiplier;
private int newRed, newGreen, newBlue;
private Color color, newColor;
/**
* rm = red multiplier gm = green multiplier bm = blue multiplier
*/
public ColorComponentScaler(double rm, double gm, double bm) {
canFilterIndexColorModel = true;
redMultiplier = rm;
greenMultiplier = gm;
blueMultiplier = bm;
}
private int multColor(int colorComponent, double multiplier) {
colorComponent = (int) (colorComponent * multiplier);
if (colorComponent < 0)
colorComponent = 0;
else if (colorComponent > 255)
colorComponent = 255;
return colorComponent;
}
/**
* split the argb value into its color components, multiply each color
* component by its corresponding scaler factor and pack the components back
* into a single pixel
*/
public int filterRGB(int x, int y, int argb) {
color = new Color(argb);
newBlue = multColor(color.getBlue(), blueMultiplier);
newGreen = multColor(color.getGreen(), greenMultiplier);
newRed = multColor(color.getRed(), redMultiplier);
newColor = new Color(newRed, newGreen, newBlue);
return (newColor.getRGB());
}
}
Filtering the RGB Values in an Image
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.RGBImageFilter;
import javax.swing.ImageIcon;
class GetRedFilter extends RGBImageFilter {
public GetRedFilter() {
canFilterIndexColorModel = true;
}
public int filterRGB(int x, int y, int rgb) {
if (x == -1) {
}
return rgb & 0xffff0000;
}
}
public class Main {
public static void main(String[] argv) throws Exception {
Image image = new ImageIcon("image.gif").getImage();
ImageFilter filter = new GetRedFilter();
FilteredImageSource filteredSrc = new FilteredImageSource(image.getSource(), filter);
image = Toolkit.getDefaultToolkit().createImage(filteredSrc);
}
}
Flip an image
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ImageFlip extends JPanel {
public void paint(Graphics g) {
Image myImage = new ImageIcon("yourImage.jpg").getImage();
BufferedImage bufferedImage = new BufferedImage(myImage.getWidth(null), myImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) g;
Graphics gb = bufferedImage.getGraphics();
gb.drawImage(myImage, 0, 0, null);
gb.dispose();
AffineTransform tx = AffineTransform.getScaleInstance(-1, 1);
tx.translate(-myImage.getWidth(null), 0);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
bufferedImage = op.filter(bufferedImage, null);
g2d.drawImage(myImage, 10, 10, null);
g2d.drawImage(bufferedImage, null, 300, 10);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Flip image");
frame.add(new ImageFlip());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(570, 230);
frame.setVisible(true);
}
}
Get the dimensions of the image; these will be non-negative
import java.awt.Image;
import java.awt.Toolkit;
public class BasicDraw {
public static void main(String[] args) {
Image image = new ImageIcon("image.gif").getImage();
width = image.getWidth(null);
height = image.getHeight(null);
}
}
Getting the Color Model of an Image
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;
import javax.swing.ImageIcon;
public class Main {
public static void main(String[] argv) throws Exception {
Image image = new ImageIcon("a.png").getImage();
if (image instanceof BufferedImage) {
BufferedImage bimage = (BufferedImage) image;
System.out.println(bimage.getColorModel().getNumColorComponents());
}
PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
try {
pg.grabPixels();
} catch (InterruptedException e) {
}
ColorModel cm = pg.getColorModel();
System.out.println(cm.getNumColorComponents());
}
}
Graband Fade: displays image and fades to black
/*
Java Media APIs: Cross-Platform Imaging, Media and Visualization
Alejandro Terrazas
Sams, Published November 2002,
ISBN 0672320940
*/
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JFrame;
/**
* GrabandFade.java -- displays provided image and then slowly fades to black
*/
public class GrabandFade extends Applet {
private Image originalImage;
private Image newImage;
private MemoryImageSource mis;
private int width;
private int height;
private int index = 10;
private int[] originalPixelArray;
private boolean imageLoaded = false;
private String imageURLString = "file:peppers.png";
public void init() {
URL url;
try {
// set imageURLString here
url = new URL(imageURLString);
originalImage = getImage(url);
} catch (MalformedURLException me) {
showStatus("Malformed URL: " + me.getMessage());
}
/*
* Create PixelGrabber and use it to fill originalPixelArray with image
* pixel data. This array will then by used by the MemoryImageSource.
*/
try {
PixelGrabber grabber = new PixelGrabber(originalImage, 0, 0, -1,
-1, true);
if (grabber.grabPixels()) {
width = grabber.getWidth();
height = grabber.getHeight();
originalPixelArray = (int[]) grabber.getPixels();
mis = new MemoryImageSource(width, height, originalPixelArray,
0, width);
mis.setAnimated(true);
newImage = createImage(mis);
} else {
System.err.println("Grabbing Failed");
}
} catch (InterruptedException ie) {
System.err.println("Pixel Grabbing Interrupted");
}
}
/**
* overwrite update method to avoid clearing of drawing area
*/
public void update(Graphics g) {
paint(g);
}
/**
* continually draw image, then decrease color components of all pixels
* contained in the originalPixelArray array until color components are all
* 0
*/
public void paint(Graphics g) {
int value;
int alpha, sourceRed, sourceGreen, sourceBlue;
if (newImage != null) {
g.drawImage(newImage, 0, 0, this); // redraw image
// if image isn"t faded to black, continue
if (imageLoaded == false) {
imageLoaded = true;
for (int x = 0; x < width; x += 1)
for (int y = 0; y < height; y += 1) {
// find the color components
value = originalPixelArray[x * height + y];
alpha = (value >> 24) & 0x000000ff;
sourceRed = (value >> 16) & 0x000000ff;
sourceGreen = (value >> 8) & 0x000000ff;
sourceBlue = value & 0x000000ff;
// subtract index from each red component
if (sourceRed > index) {
sourceRed -= index;
imageLoaded = false;
} else
sourceRed = 0;
// subtract index from each green component
if (sourceGreen > index) {
sourceGreen -= index;
imageLoaded = false;
} else
sourceGreen = 0;
// subtract index from each blue component
if (sourceBlue > index) {
sourceBlue -= index;
imageLoaded = false;
} else
sourceBlue = 0;
/*
* when we pack new color components into integer we
* make sure the alpha (transparency) value represents
* opaque
*/
value = (alpha << 24);
value += (sourceRed << 16);
value += (sourceGreen << 8);
value += sourceBlue;
// fill pixel array
originalPixelArray[x * height + y] = value;
}
mis.newPixels(); //send pixels to ImageConsumer
}
}
}
public static void main(String[] argv) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GrabandFade a = new GrabandFade();
frame.getContentPane().add(a);
frame.setSize(300, 300);
a.init();
a.start();
frame.setVisible(true);
}
}
Graband Fade with Rasters
/*
Java Media APIs: Cross-Platform Imaging, Media and Visualization
Alejandro Terrazas
Sams, Published November 2002,
ISBN 0672320940
*/
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.WritableRaster;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JFrame;
/**
* GrabandFadewithRasters.java -- displays provided image and then slowly fades
* to black
*/
public class GrabandFadewithRasters extends Applet {
private Image originalImage;
private Image newImage;
private MemoryImageSource mis;
private int width;
private int height;
private int index = 10;
private int[] originalPixelArray;
private boolean imageLoaded = false;
private WritableRaster raster;
private String imageURLString = "file:images/peppers.png";
public void init() {
URL url;
try {
url = new URL(imageURLString);
originalImage = getImage(url);
} catch (MalformedURLException me) {
showStatus("Malformed URL: " + me.getMessage());
}
try {
PixelGrabber grabber = new PixelGrabber(originalImage, 0, 0, -1,
-1, true);
if (grabber.grabPixels()) {
width = grabber.getWidth();
height = grabber.getHeight();
originalPixelArray = (int[]) grabber.getPixels();
mis = new MemoryImageSource(width, height, originalPixelArray,
0, width);
mis.setAnimated(true);
newImage = createImage(mis);
} else {
System.err.println("Grabbing Failed");
}
} catch (InterruptedException ie) {
System.err.println("Pixel Grabbing Interrupted");
}
DataBufferInt dbi = new DataBufferInt(originalPixelArray, width
* height);
int bandmasks[] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
SampleModel sm;
sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, width,
height, bandmasks);
raster = Raster.createWritableRaster(sm, dbi, null);
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
int value;
int sourceRed, sourceGreen, sourceBlue;
if (newImage != null) {
g.drawImage(newImage, 0, 0, this);
if (imageLoaded == false) {
imageLoaded = true;
for (int x = 0; x < width; x += 1)
for (int y = 0; y < height; y += 1) {
value = originalPixelArray[x * height + y];
sourceRed = raster.getSample(x, y, 1);
sourceGreen = raster.getSample(x, y, 2);
sourceBlue = raster.getSample(x, y, 3);
if (sourceRed > index) {
sourceRed -= index;
imageLoaded = false;
} else
sourceRed = 0;
if (sourceGreen > index) {
sourceGreen -= index;
imageLoaded = false;
} else
sourceGreen = 0;
if (sourceBlue > index) {
sourceBlue -= index;
imageLoaded = false;
} else
sourceBlue = 0;
raster.setSample(x, y, 1, sourceRed);
raster.setSample(x, y, 2, sourceGreen);
raster.setSample(x, y, 3, sourceBlue);
}
mis.newPixels();
}
}
}
public static void main(String[] argv) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GrabandFadewithRasters a = new GrabandFadewithRasters();
frame.getContentPane().add(a);
frame.setSize(300, 300);
a.init();
a.start();
frame.setVisible(true);
}
}
Image Animation and Thread
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class BufferedImageThread extends JFrame {
AnimationCanvas canvas;
JButton startButton, stopButton;
public BufferedImageThread() {
super();
Container container = getContentPane();
canvas = new AnimationCanvas();
container.add(canvas);
startButton = new JButton("Start Animation");
startButton.addActionListener(new ButtonListener());
stopButton = new JButton("Stop Animation");
stopButton.addActionListener(new ButtonListener());
JPanel panel = new JPanel();
panel.add(startButton);
panel.add(stopButton);
container.add(BorderLayout.SOUTH, panel);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setSize(450, 425);
setVisible(true);
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton temp = (JButton) e.getSource();
if (temp.equals(startButton)) {
canvas.start();
} else if (temp.equals(stopButton)) {
canvas.stop();
}
}
}
public static void main(String arg[]) {
new BufferedImageThread();
}
}
class AnimationCanvas extends JLabel implements Runnable {
Thread thread;
Image image;
BufferedImage bi;
double x, y, xi, yi;
int rotate;
double scale;
int UP = 0;
int DOWN = 1;
int scaleDirection;
AnimationCanvas() {
setBackground(Color.green);
setSize(450, 400);
image = getToolkit().getImage("largejexpLogo.gif");
MediaTracker mt = new MediaTracker(this);
mt.addImage(image, 1);
try {
mt.waitForAll();
} catch (Exception e) {
System.out.println("Exception while loading image.");
}
if (image.getWidth(this) == -1) {
System.out.println("No gif file");
System.exit(0);
}
rotate = (int) (Math.random() * 360);
scale = Math.random() * 1.5;
scaleDirection = DOWN;
xi = 50.0;
yi = 50.0;
}
public void step(int w, int h) {
x += xi;
y += yi;
if (x > w) {
x = w - 1;
xi = Math.random() * -w / 32;
}
if (x < 0) {
x = 2;
xi = Math.random() * w / 32;
}
if (y > h) {
y = h - 2;
yi = Math.random() * -h / 32;
}
if (y < 0) {
y = 2;
yi = Math.random() * h / 32;
}
if ((rotate += 5) == 360) {
rotate = 0;
}
if (scaleDirection == UP) {
if ((scale += 0.5) > 1.5) {
scaleDirection = DOWN;
}
} else if (scaleDirection == DOWN) {
if ((scale -= .05) < 0.5) {
scaleDirection = UP;
}
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension d = getSize();
bi = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D big = bi.createGraphics();
step(d.width, d.height);
AffineTransform at = new AffineTransform();
at.setToIdentity();
at.translate(x, y);
at.rotate(Math.toRadians(rotate));
at.scale(scale, scale);
big.drawImage(image, at, this);
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(bi, 0, 0, null);
big.dispose();
}
public void start() {
thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
public void stop() {
if (thread != null)
thread.interrupt();
thread = null;
}
public void run() {
Thread me = Thread.currentThread();
while (thread == me) {
repaint();
}
thread = null;
}
}
Image Buffering
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.TitledBorder;
public class SimpleBufferedImageDemo extends JFrame {
DisplayCanvas canvas;
JRadioButton buffButton, nonBuffButton;
JButton displayButton, clearButton;
public SimpleBufferedImageDemo() {
super();
Container container = getContentPane();
canvas = new DisplayCanvas();
container.add(canvas);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2, 2));
panel.setBorder(new TitledBorder(
"Select an Option and Display Image..."));
buffButton = new JRadioButton("Buffered");
buffButton.addActionListener(new ButtonListener());
nonBuffButton = new JRadioButton("Non-Buffered", true);
nonBuffButton.addActionListener(new ButtonListener());
ButtonGroup group = new ButtonGroup();
group.add(buffButton);
group.add(nonBuffButton);
displayButton = new JButton("Display");
displayButton.addActionListener(new ButtonListener());
clearButton = new JButton("Clear");
clearButton.addActionListener(new ButtonListener());
panel.add(nonBuffButton);
panel.add(buffButton);
panel.add(displayButton);
panel.add(clearButton);
container.add(BorderLayout.SOUTH, panel);
addWindowListener(new WindowEventHandler());
pack();
setVisible(true);
}
class WindowEventHandler extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
public static void main(String arg[]) {
new SimpleBufferedImageDemo();
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj instanceof JRadioButton) {
JRadioButton button = (JRadioButton) obj;
if (button.equals(buffButton)) {
canvas.buffered = true;
} else if (button.equals(nonBuffButton)) {
canvas.buffered = false;
}
}
if (obj instanceof JButton) {
JButton button = (JButton) obj;
if (button.equals(displayButton)) {
canvas.display = true;
canvas.repaint();
} else if (button.equals(clearButton)) {
canvas.clear = true;
canvas.repaint();
}
}
}
}
}
class DisplayCanvas extends Canvas {
boolean display = false;
boolean clear = false;
boolean buffered = false;
Image displayImage;
DisplayCanvas() {
displayImage = Toolkit.getDefaultToolkit().getImage("largejexpLogo.jpg");
MediaTracker mt = new MediaTracker(this);
mt.addImage(displayImage, 1);
try {
mt.waitForAll();
} catch (Exception e) {
System.out.println("Exception while loading.");
}
if (displayImage.getWidth(this) == -1) {
System.out.println("No *.jpg file");
System.exit(0);
}
setBackground(Color.white);
setSize(400, 225);
}
public void paint(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
if (display) {
if (buffered) {
BufferedImage bi = (BufferedImage) createImage(getWidth(),
getHeight());
// Draw into the memory buffer.
for (int i = 0; i < getWidth(); i = i
+ displayImage.getWidth(this)) {
for (int j = 0; j < getHeight(); j = j
+ displayImage.getHeight(this)) {
bi.createGraphics().drawImage(displayImage, i, j, this);
}
}
// Draw the buffered Image on to the screen
g2D.drawImage(bi, 0, 0, this);
}
// This block of code draws the texture directly onto the screen.
else if (!buffered) {
for (int i = 0; i < getWidth(); i = i
+ displayImage.getWidth(this)) {
for (int j = 0; j < getHeight(); j = j
+ displayImage.getHeight(this)) {
g2D.drawImage(displayImage, i, j, this);
}
}
}
display = false;
}else if (clear) {
g2D.setColor(Color.white);
g2D.clearRect(0, 0, getWidth(), getHeight());
clear = false;
}
}
}
Image Color Gray Effect
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.color.ColorSpace;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
public class ColorConvertDemo extends JFrame {
ColorPanel displayPanel;
JButton grayButton, resetButton;
public ColorConvertDemo() {
super();
Container container = getContentPane();
displayPanel = new ColorPanel();
container.add(displayPanel);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1, 2));
panel.setBorder(new TitledBorder(
"Click the Gray Scale Button to Create Gray Scale Image..."));
grayButton = new JButton("Gray Scale");
grayButton.addActionListener(new ButtonListener());
resetButton = new JButton("Reset");
resetButton.addActionListener(new ButtonListener());
panel.add(grayButton);
panel.add(resetButton);
container.add(BorderLayout.SOUTH, panel);
addWindowListener(new WindowEventHandler());
setSize(displayPanel.getWidth(), displayPanel.getHeight() + 15);
setVisible(true);
}
class WindowEventHandler extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
public static void main(String arg[]) {
new ColorConvertDemo();
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
if (button.equals(grayButton)) {
displayPanel.grayOut();
displayPanel.repaint();
} else if (button.equals(resetButton)) {
displayPanel.reset();
displayPanel.repaint();
}
}
}
}
class ColorPanel extends JLabel {
Image displayImage;
BufferedImage bi;
Graphics2D big;
ColorPanel() {
setBackground(Color.black);
loadImage();
setSize(displayImage.getWidth(this), displayImage.getWidth(this));
createBufferedImage();
}
public void loadImage() {
displayImage = Toolkit.getDefaultToolkit().getImage(
"largejexpLogo.jpg");
MediaTracker mt = new MediaTracker(this);
mt.addImage(displayImage, 1);
try {
mt.waitForAll();
} catch (Exception e) {
System.out.println("Exception while loading.");
}
if (displayImage.getWidth(this) == -1) {
System.out.println("No jpg ");
System.exit(0);
}
}
public void createBufferedImage() {
bi = new BufferedImage(displayImage.getWidth(this), displayImage
.getHeight(this), BufferedImage.TYPE_INT_RGB);
big = bi.createGraphics();
big.drawImage(displayImage, 0, 0, this);
}
public void grayOut() {
ColorConvertOp colorConvert = new ColorConvertOp(ColorSpace
.getInstance(ColorSpace.CS_GRAY), null);
colorConvert.filter(bi, bi);
}
public void reset() {
big.setColor(Color.black);
big.clearRect(0, 0, bi.getWidth(this), bi.getHeight(this));
big.drawImage(displayImage, 0, 0, this);
}
public void update(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
paintComponent(g);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(bi, 0, 0, this);
}
}
Image crop
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class Crop extends JFrame {
Image image;
Insets insets;
public Crop() {
super();
ImageIcon icon = new ImageIcon("jexp.PNG");
image = icon.getImage();
image = createImage(new FilteredImageSource(image.getSource(),
new CropImageFilter(73, 63, 141, 131)));
}
public void paint(Graphics g) {
super.paint(g);
if (insets == null) {
insets = getInsets();
}
g.drawImage(image, insets.left, insets.top, this);
}
public static void main(String args[]) {
JFrame f = new Crop();
f.setSize(200, 200);
f.show();
}
}
Image demo
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Checkbox;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Label;
import java.awt.MediaTracker;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.color.ColorSpace;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ColorConvertOp;
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.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.JPanel;
import javax.swing.text.Utilities;
public class Sampler extends Frame {
private Frame mImageFrame;
private SplitImageComponent mSplitImageComponent;
private Hashtable mOps;
public static void main(String[] args) {
String imageFile = "largejexpLogo.jpg";
if (args.length > 0)
imageFile = args[0];
new Sampler(imageFile);
}
public Sampler(String imageFile) {
super();
createOps();
createImageFrame(imageFile);
createUI();
setVisible(true);
}
private void createOps() {
mOps = new Hashtable();
createConvolutions();
createTransformations();
createLookups();
createRescales();
createColorOps();
}
private void createConvolutions() {
float ninth = 1.0f / 9.0f;
float[] blurKernel = { ninth, ninth, ninth, ninth, ninth, ninth, ninth,
ninth, ninth };
mOps.put("Blur", new ConvolveOp(new Kernel(3, 3, blurKernel),
ConvolveOp.EDGE_NO_OP, null));
float[] edge = { 0f, -1f, 0f, -1f, 4f, -1f, 0f, -1f, 0f };
mOps.put("Edge detector", new ConvolveOp(new Kernel(3, 3, edge),
ConvolveOp.EDGE_NO_OP, null));
float[] sharp = { 0f, -1f, 0f, -1f, 5f, -1f, 0f, -1f, 0f };
mOps.put("Sharpen", new ConvolveOp(new Kernel(3, 3, sharp)));
}
private void createTransformations() {
AffineTransform at;
at = AffineTransform.getRotateInstance(Math.PI / 6, 0, 285);
mOps.put("Rotate nearest neighbor", new AffineTransformOp(at, null));
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
mOps.put("Rotate bilinear", new AffineTransformOp(at, rh));
at = AffineTransform.getScaleInstance(.5, .5);
mOps.put("Scale .5, .5", new AffineTransformOp(at, null));
at = AffineTransform.getRotateInstance(Math.PI / 6);
mOps.put("Rotate bilinear (origin)", new AffineTransformOp(at, rh));
}
private void createLookups() {
short[] brighten = new short[256];
short[] betterBrighten = new short[256];
short[] posterize = new short[256];
short[] invert = new short[256];
short[] straight = new short[256];
short[] zero = new short[256];
for (int i = 0; i < 256; i++) {
brighten[i] = (short) (128 + i / 2);
betterBrighten[i] = (short) (Math.sqrt((double) i / 255.0) * 255.0);
posterize[i] = (short) (i - (i % 32));
invert[i] = (short) (255 - i);
straight[i] = (short) i;
zero[i] = (short) 0;
}
mOps.put("Brighten", new LookupOp(new ShortLookupTable(0, brighten),
null));
mOps.put("Better Brighten", new LookupOp(new ShortLookupTable(0,
betterBrighten), null));
mOps.put("Posterize", new LookupOp(new ShortLookupTable(0, posterize),
null));
mOps.put("Invert", new LookupOp(new ShortLookupTable(0, invert), null));
short[][] redOnly = { invert, straight, straight };
short[][] greenOnly = { straight, invert, straight };
short[][] blueOnly = { straight, straight, invert };
mOps.put("Red invert", new LookupOp(new ShortLookupTable(0, redOnly),
null));
mOps.put("Green invert", new LookupOp(
new ShortLookupTable(0, greenOnly), null));
mOps.put("Blue invert", new LookupOp(new ShortLookupTable(0, blueOnly),
null));
short[][] redRemove = { zero, straight, straight };
short[][] greenRemove = { straight, zero, straight };
short[][] blueRemove = { straight, straight, zero };
mOps.put("Red remove", new LookupOp(new ShortLookupTable(0, redRemove),
null));
mOps.put("Green remove", new LookupOp(new ShortLookupTable(0,
greenRemove), null));
mOps.put("Blue remove", new LookupOp(
new ShortLookupTable(0, blueRemove), null));
}
private void createRescales() {
mOps.put("Rescale .5, 0", new RescaleOp(.5f, 0, null));
mOps.put("Rescale .5, 64", new RescaleOp(.5f, 64, null));
mOps.put("Rescale 1.2, 0", new RescaleOp(1.2f, 0, null));
mOps.put("Rescale 1.5, 0", new RescaleOp(1.5f, 0, null));
}
private void createColorOps() {
mOps.put("Grayscale", new ColorConvertOp(ColorSpace
.getInstance(ColorSpace.CS_GRAY), null));
}
private void createImageFrame(String imageFile) {
// Create the image frame.
mSplitImageComponent = new SplitImageComponent(imageFile);
mImageFrame = new Frame(imageFile);
mImageFrame.setLayout(new BorderLayout());
mImageFrame.add(mSplitImageComponent, BorderLayout.CENTER);
// Utilities.sizeContainerToComponent(mImageFrame, mSplitImageComponent);
// Utilities.centerFrame(mImageFrame);
mImageFrame.setVisible(true);
}
private void createUI() {
setFont(new Font("Serif", Font.PLAIN, 12));
setLayout(new BorderLayout());
// Set our location to the left of the image frame.
setSize(200, 350);
Point pt = mImageFrame.getLocation();
setLocation(pt.x - getSize().width, pt.y);
final Checkbox accumulateCheckbox = new Checkbox("Accumulate", false);
final Label statusLabel = new Label("");
// Make a sorted list of the operators.
Enumeration e = mOps.keys();
Vector names = new Vector();
while (e.hasMoreElements())
names.addElement(e.nextElement());
Collections.sort(names);
final java.awt.List list = new java.awt.List();
for (int i = 0; i < names.size(); i++)
list.add((String) names.elementAt(i));
add(list, BorderLayout.CENTER);
// When an item is selected, do the corresponding transformation.
list.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent ie) {
if (ie.getStateChange() != ItemEvent.SELECTED)
return;
String key = list.getSelectedItem();
BufferedImageOp op = (BufferedImageOp) mOps.get(key);
BufferedImage source = mSplitImageComponent.getSecondImage();
boolean accumulate = accumulateCheckbox.getState();
if (source == null || accumulate == false)
source = mSplitImageComponent.getImage();
String previous = mImageFrame.getTitle() + " + ";
if (accumulate == false)
previous = "";
mImageFrame.setTitle(previous + key);
statusLabel.setText("Performing " + key + "...");
list.setEnabled(false);
accumulateCheckbox.setEnabled(false);
BufferedImage destination = op.filter(source, null);
mSplitImageComponent.setSecondImage(destination);
mSplitImageComponent.setSize(mSplitImageComponent
.getPreferredSize());
mImageFrame.setSize(mImageFrame.getPreferredSize());
list.setEnabled(true);
accumulateCheckbox.setEnabled(true);
statusLabel.setText("Performing " + key + "...done.");
}
});
Button loadButton = new Button("Load...");
loadButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
FileDialog fd = new FileDialog(Sampler.this);
fd.show();
if (fd.getFile() == null)
return;
String path = fd.getDirectory() + fd.getFile();
mSplitImageComponent.setImage(path);
mSplitImageComponent.setSecondImage(null);
// Utilities.sizeContainerToComponent(mImageFrame,
// mSplitImageComponent);
mImageFrame.validate();
mImageFrame.repaint();
}
});
Panel bottom = new Panel(new GridLayout(2, 1));
Panel topBottom = new Panel();
topBottom.add(accumulateCheckbox);
topBottom.add(loadButton);
bottom.add(topBottom);
bottom.add(statusLabel);
add(bottom, BorderLayout.SOUTH);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
mImageFrame.dispose();
dispose();
System.exit(0);
}
});
}
class SplitImageComponent extends JPanel {
private BufferedImage mImage;
private BufferedImage mSecondImage;
private int mSplitX;
public SplitImageComponent(String path) {
setImage(path);
init();
}
public SplitImageComponent(BufferedImage image) {
setImage(image);
init();
}
public void setImage(String path) {
Image image = blockingLoad(path);
mImage = makeBufferedImage(image);
}
public void setImage(BufferedImage image) {
mImage = image;
}
public void setSecondImage(BufferedImage image) {
mSecondImage = image;
repaint();
}
public BufferedImage getImage() {
return mImage;
}
public BufferedImage getSecondImage() {
return mSecondImage;
}
private void init() {
setBackground(Color.white);
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
mSplitX = me.getX();
repaint();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent me) {
mSplitX = me.getX();
repaint();
}
});
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
int width = getSize().width;
int height = getSize().height;
// Explicitly clear the window.
Rectangle clear = new Rectangle(0, 0, width, height);
g2.setPaint(getBackground());
g2.fill(clear);
// Clip the first image, if appropriate,
// to be on the right side of the split.
if (mSplitX != 0 && mSecondImage != null) {
Rectangle firstClip = new Rectangle(mSplitX, 0, width - mSplitX,
height);
g2.setClip(firstClip);
}
g2.drawImage(getImage(), 0, 0, null);
if (mSplitX == 0 || mSecondImage == null)
return;
Rectangle secondClip = new Rectangle(0, 0, mSplitX, height);
g2.setClip(secondClip);
g2.drawImage(mSecondImage, 0, 0, null);
Line2D splitLine = new Line2D.Float(mSplitX, 0, mSplitX, height);
g2.setClip(null);
g2.setColor(Color.white);
g2.draw(splitLine);
}
public Dimension getPreferredSize() {
int width = getImage().getWidth();
int height = getImage().getHeight();
if (mSecondImage != null) {
width = Math.max(width, mSecondImage.getWidth());
height = Math.max(height, mSecondImage.getHeight());
}
return new Dimension(width, height);
}
}
private Component sComponent = new Component() {
};
private final MediaTracker sTracker = new MediaTracker(sComponent);
private int sID = 0;
public boolean waitForImage(Image image) {
int id;
synchronized (sComponent) {
id = sID++;
}
sTracker.addImage(image, id);
try {
sTracker.waitForID(id);
} catch (InterruptedException ie) {
return false;
}
if (sTracker.isErrorID(id))
return false;
return true;
}
public Image blockingLoad(String path) {
Image image = Toolkit.getDefaultToolkit().getImage(path);
if (waitForImage(image) == false)
return null;
return image;
}
public Image blockingLoad(URL url) {
Image image = Toolkit.getDefaultToolkit().getImage(url);
if (waitForImage(image) == false)
return null;
return image;
}
public BufferedImage makeBufferedImage(Image image) {
return makeBufferedImage(image, BufferedImage.TYPE_INT_RGB);
}
public BufferedImage makeBufferedImage(Image image, int imageType) {
if (waitForImage(image) == false)
return null;
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null),
image.getHeight(null), imageType);
Graphics2D g2 = bufferedImage.createGraphics();
g2.drawImage(image, null, null);
return bufferedImage;
}
}
Image Effect: Combine
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BandCombineOp;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
public class CombineApp extends JFrame {
CombinePanel displayPanel;
JButton redBandButton, greenBandButton, blueBandButton, inverseBandButton,
middleBandButton, resetButton;
public CombineApp() {
super("TBandCombineOp");
Container container = getContentPane();
displayPanel = new CombinePanel();
container.add(displayPanel);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 2));
panel
.setBorder(new TitledBorder(
"Click a Button to Perform the Associated Operation and Reset..."));
redBandButton = new JButton("Show Red Band");
redBandButton.addActionListener(new ButtonListener());
greenBandButton = new JButton("Show Green Band");
greenBandButton.addActionListener(new ButtonListener());
blueBandButton = new JButton("Show Blue Band");
blueBandButton.addActionListener(new ButtonListener());
inverseBandButton = new JButton("Invert All Bands");
inverseBandButton.addActionListener(new ButtonListener());
middleBandButton = new JButton("Average Each Band");
middleBandButton.addActionListener(new ButtonListener());
resetButton = new JButton("Reset");
resetButton.addActionListener(new ButtonListener());
panel.add(redBandButton);
panel.add(blueBandButton);
panel.add(greenBandButton);
panel.add(inverseBandButton);
panel.add(middleBandButton);
panel.add(resetButton);
container.add(BorderLayout.SOUTH, panel);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setSize(displayPanel.getWidth(), displayPanel.getHeight());
setVisible(true);
}
public static void main(String arg[]) {
new CombineApp();
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
if (button.equals(redBandButton)) {
displayPanel.bandCombine(CombinePanel.RED_BAND_MATRIX);
displayPanel.repaint();
} else if (button.equals(greenBandButton)) {
displayPanel.bandCombine(CombinePanel.GREEN_BAND_MATRIX);
displayPanel.repaint();
} else if (button.equals(blueBandButton)) {
displayPanel.bandCombine(CombinePanel.BLUE_BAND_MATRIX);
displayPanel.repaint();
} else if (button.equals(inverseBandButton)) {
displayPanel.bandCombine(CombinePanel.INVERSE_BAND_MATRIX);
displayPanel.repaint();
} else if (button.equals(middleBandButton)) {
displayPanel.bandCombine(CombinePanel.AVERAGE_BAND_MATRIX);
displayPanel.repaint();
} else if (button.equals(resetButton)) {
displayPanel.reset();
displayPanel.repaint();
}
}
}
}
class CombinePanel extends JLabel {
// red band Matrix
static final float RED_BAND_MATRIX[][] = { { 1.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
// green band Matrix
static final float GREEN_BAND_MATRIX[][] = { { 0.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
// blue band Matrix
static final float BLUE_BAND_MATRIX[][] = { { 0.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };
// Matrix that inverts all the bands
// the nagative of the image.
static final float INVERSE_BAND_MATRIX[][] = { { -1.0f, 0.0f, 0.0f },
{ 0.0f, -1.0f, 0.0f }, { 0.0f, 0.0f, -1.0f } };
// Matrix that reduces the intensities of all bands
static final float AVERAGE_BAND_MATRIX[][] = { { 0.5f, 0.0f, 0.0f },
{ 0.0f, 0.5f, 0.0f }, { 0.0f, 0.0f, 0.5f } };
Image displayImage;
// The source and destination images
BufferedImage biSrc;
BufferedImage biDest;
// The source and destination rasters
Raster srcRaster;
WritableRaster dstRaster;
BufferedImage bi;
Graphics2D big;
CombinePanel() {
setBackground(Color.black);
loadImage();
setSize(displayImage.getWidth(this), displayImage.getWidth(this));
createBufferedImages();
bi = biSrc;
}
public void loadImage() {
displayImage = Toolkit.getDefaultToolkit().getImage(
"largejexpLogo.jpg");
MediaTracker mt = new MediaTracker(this);
mt.addImage(displayImage, 1);
try {
mt.waitForAll();
} catch (Exception e) {
System.out.println("Exception while loading.");
}
if (displayImage.getWidth(this) == -1) {
System.out.println("No jpg) file");
System.exit(0);
}
}
public void createBufferedImages() {
biSrc = new BufferedImage(displayImage.getWidth(this), displayImage
.getHeight(this), BufferedImage.TYPE_INT_RGB);
big = biSrc.createGraphics();
big.drawImage(displayImage, 0, 0, this);
srcRaster = biSrc.getRaster();
biDest = new BufferedImage(displayImage.getWidth(this), displayImage
.getHeight(this), BufferedImage.TYPE_INT_RGB);
dstRaster = (WritableRaster) biDest.getRaster();
}
public void bandCombine(float[][] bandCombineMatrix) {
BandCombineOp bandCombineOp = new BandCombineOp(bandCombineMatrix, null);
bandCombineOp.filter(srcRaster, dstRaster);
bi = biDest;
}
public void reset() {
big.setColor(Color.black);
big.clearRect(0, 0, bi.getWidth(this), bi.getHeight(this));
big.drawImage(displayImage, 0, 0, this);
bi = biSrc;
}
public void update(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
paintComponent(g);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(bi, 0, 0, this);
}
}
Image Effect: Rotate Image using DataBuffer
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
public class RasterDemo extends JFrame {
RasterPanel displayPanel;
JToggleButton flipButton;
public RasterDemo() {
super();
Container container = getContentPane();
displayPanel = new RasterPanel();
container.add(displayPanel);
Box box = Box.createHorizontalBox();
flipButton = new JToggleButton("Flip the Image");
flipButton.addActionListener(new ButtonListener());
box.add(Box.createHorizontalGlue());
box.add(flipButton);
box.add(Box.createHorizontalGlue());
container.add(box, BorderLayout.SOUTH);
addWindowListener(new WindowEventHandler());
setSize(450, 400);
show();
}
class WindowEventHandler extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
public static void main(String arg[]) {
new RasterDemo();
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (!displayPanel.flipped) {
displayPanel.flipBufferedImage();
displayPanel.bi = displayPanel.bi2;
displayPanel.flipped = true;
}
// If the image has already been flipped
else {
// Prepare to display the normal image
displayPanel.bi = displayPanel.bi1;
displayPanel.flipped = false;
}
// Update the display panel
displayPanel.repaint();
}
}
}
class RasterPanel extends JPanel {
BufferedImage bi, bi1, bi2;
boolean flipped = false;
RasterPanel() {
setBackground(Color.white);
setSize(450, 400);
Image image = getToolkit().getImage("largejexpLogo.jpg");
MediaTracker mt = new MediaTracker(this);
mt.addImage(image, 1);
try {
mt.waitForAll();
} catch (Exception e) {
System.out.println("Exception while loading image.");
}
if (image.getWidth(this) == -1) {
System.out.println("No jpg file");
System.exit(0);
}
bi1 = new BufferedImage(image.getWidth(this), image.getHeight(this),
BufferedImage.TYPE_INT_ARGB);
Graphics2D big = bi1.createGraphics();
big.drawImage(image, 0, 0, this);
bi = bi1;
}
public void flipBufferedImage() {
bi2 = new BufferedImage(bi1.getWidth(), bi1.getHeight(), bi1.getType());
DataBuffer db1 = bi1.getRaster().getDataBuffer();
DataBuffer db2 = bi2.getRaster().getDataBuffer();
for (int i = db1.getSize() - 1, j = 0; i >= 0; --i, j++) {
db2.setElem(j, db1.getElem(i));
}
}
public void update(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
paintComponent(g);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(bi, 0, 0, this);
}
}
Image Effect: Sharpen, blur
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
public class ConvolveApp extends JFrame {
CPanel displayPanel;
JButton sharpenButton, blurringButton, edButton, resetButton;
public ConvolveApp() {
super();
Container container = getContentPane();
displayPanel = new CPanel();
container.add(displayPanel);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2, 2));
panel
.setBorder(new TitledBorder(
"Click a Button to Perform the Associated Operation and Reset..."));
sharpenButton = new JButton("Sharpen");
sharpenButton.addActionListener(new ButtonListener());
blurringButton = new JButton("Blur");
blurringButton.addActionListener(new ButtonListener());
edButton = new JButton("Edge Detect");
edButton.addActionListener(new ButtonListener());
resetButton = new JButton("Reset");
resetButton.addActionListener(new ButtonListener());
panel.add(sharpenButton);
panel.add(blurringButton);
panel.add(edButton);
panel.add(resetButton);
container.add(BorderLayout.SOUTH, panel);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setSize(displayPanel.getWidth(), displayPanel.getHeight() + 10);
setVisible(true);
}
public static void main(String arg[]) {
new ConvolveApp();
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
if (button.equals(sharpenButton)) {
displayPanel.sharpen();
displayPanel.repaint();
} else if (button.equals(blurringButton)) {
displayPanel.blur();
displayPanel.repaint();
} else if (button.equals(edButton)) {
displayPanel.edgeDetect();
displayPanel.repaint();
} else if (button.equals(resetButton)) {
displayPanel.reset();
displayPanel.repaint();
}
}
}
}
class CPanel extends JLabel {
Image displayImage;
BufferedImage biSrc;
BufferedImage biDest; // Destination image is mandetory.
BufferedImage bi; // Only an additional reference.
Graphics2D big;
CPanel() {
setBackground(Color.black);
loadImage();
setSize(displayImage.getWidth(this), displayImage.getWidth(this));
createBufferedImages();
bi = biSrc;
}
public void loadImage() {
displayImage = Toolkit.getDefaultToolkit().getImage("largejexpLogo.jpg");
MediaTracker mt = new MediaTracker(this);
mt.addImage(displayImage, 1);
try {
mt.waitForAll();
} catch (Exception e) {
System.out.println("Exception while loading.");
}
if (displayImage.getWidth(this) == -1) {
System.out.println("No jpg file");
System.exit(0);
}
}
public void createBufferedImages() {
biSrc = new BufferedImage(displayImage.getWidth(this), displayImage
.getHeight(this), BufferedImage.TYPE_INT_RGB);
big = biSrc.createGraphics();
big.drawImage(displayImage, 0, 0, this);
biDest = new BufferedImage(displayImage.getWidth(this), displayImage
.getHeight(this), BufferedImage.TYPE_INT_RGB);
}
public void sharpen() {
float data[] = { -1.0f, -1.0f, -1.0f, -1.0f, 9.0f, -1.0f, -1.0f, -1.0f,
-1.0f };
Kernel kernel = new Kernel(3, 3, data);
ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,
null);
convolve.filter(biSrc, biDest);
bi = biDest;
}
public void blur() {
float data[] = { 0.0625f, 0.125f, 0.0625f, 0.125f, 0.25f, 0.125f,
0.0625f, 0.125f, 0.0625f };
Kernel kernel = new Kernel(3, 3, data);
ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,
null);
convolve.filter(biSrc, biDest);
bi = biDest;
}
public void edgeDetect() {
float data[] = { 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f,
-1.0f };
Kernel kernel = new Kernel(3, 3, data);
ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,
null);
convolve.filter(biSrc, biDest);
bi = biDest;
}
public void reset() {
big.setColor(Color.black);
big.clearRect(0, 0, bi.getWidth(this), bi.getHeight(this));
big.drawImage(displayImage, 0, 0, this);
bi = biSrc;
}
public void update(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
paintComponent(g);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(bi, 0, 0, this);
}
}
Image Operations
/*
* Copyright (c) 2000 David Flanagan. All rights reserved.
* This code is from the book Java Examples in a Nutshell, 2nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book (recommended),
* visit http://www.davidflanagan.ru/javaexamples2.
*/
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ByteLookupTable;
import java.awt.image.ColorConvertOp;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.LookupOp;
import java.awt.image.RescaleOp;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** A demonstration of various image processing filters */
public class ImageOps extends JPanel{
static final int WIDTH = 600, HEIGHT = 675; // Size of our example
public String getName() {
return "Image Processing";
}
public int getWidth() {
return WIDTH;
}
public int getHeight() {
return HEIGHT;
}
Image image;
/** This constructor loads the image we will manipulate */
public ImageOps() {
java.net.URL imageurl = this.getClass().getResource("cover.gif");
image = new javax.swing.ImageIcon(imageurl).getImage();
}
// These arrays of bytes are used by the LookupImageOp image filters below
static byte[] brightenTable = new byte[256];
static byte[] thresholdTable = new byte[256];
static { // Initialize the arrays
for (int i = 0; i < 256; i++) {
brightenTable[i] = (byte) (Math.sqrt(i / 255.0) * 255);
thresholdTable[i] = (byte) ((i < 225) ? 0 : i);
}
}
// This AffineTransform is used by one of the image filters below
static AffineTransform mirrorTransform;
static { // Create and initialize the AffineTransform
mirrorTransform = AffineTransform.getTranslateInstance(127, 0);
mirrorTransform.scale(-1.0, 1.0); // flip horizontally
}
// These are the labels we"ll display for each of the filtered images
static String[] filterNames = new String[] { "Original", "Gray Scale",
"Negative", "Brighten (linear)", "Brighten (sqrt)", "Threshold",
"Blur", "Sharpen", "Edge Detect", "Mirror", "Rotate (center)",
"Rotate (lower left)" };
// The following BufferedImageOp image filter objects perform
// different types of image processing operations.
static BufferedImageOp[] filters = new BufferedImageOp[] {
// 1) No filter here. We"ll display the original image
null,
// 2) Convert to Grayscale color space
new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null),
// 3) Image negative. Multiply each color value by -1.0 and add 255
new RescaleOp(-1.0f, 255f, null),
// 4) Brighten using a linear formula that increases all color
// values
new RescaleOp(1.25f, 0, null),
// 5) Brighten using the lookup table defined above
new LookupOp(new ByteLookupTable(0, brightenTable), null),
// 6) Threshold using the lookup table defined above
new LookupOp(new ByteLookupTable(0, thresholdTable), null),
// 7) Blur by "convolving" the image with a matrix
new ConvolveOp(new Kernel(3, 3, new float[] { .1111f, .1111f,
.1111f, .1111f, .1111f, .1111f, .1111f, .1111f, .1111f, })),
// 8) Sharpen by using a different matrix
new ConvolveOp(new Kernel(3, 3, new float[] { 0.0f, -0.75f, 0.0f,
-0.75f, 4.0f, -0.75f, 0.0f, -0.75f, 0.0f })),
// 9) Edge detect using yet another matrix
new ConvolveOp(new Kernel(3, 3, new float[] { 0.0f, -0.75f, 0.0f,
-0.75f, 3.0f, -0.75f, 0.0f, -0.75f, 0.0f })),
// 10) Compute a mirror image using the transform defined above
new AffineTransformOp(mirrorTransform,
AffineTransformOp.TYPE_BILINEAR),
// 11) Rotate the image 180 degrees about its center point
new AffineTransformOp(AffineTransform.getRotateInstance(Math.PI,
64, 95), AffineTransformOp.TYPE_NEAREST_NEIGHBOR),
// 12) Rotate the image 15 degrees about the bottom left
new AffineTransformOp(AffineTransform.getRotateInstance(
Math.PI / 12, 0, 190),
AffineTransformOp.TYPE_NEAREST_NEIGHBOR), };
/** Draw the example */
public void paint(Graphics g1) {
Graphics2D g = (Graphics2D)g1;
// Create a BufferedImage big enough to hold the Image loaded
// in the constructor. Then copy that image into the new
// BufferedImage object so that we can process it.
BufferedImage bimage = new BufferedImage(image.getWidth(this), image
.getHeight(this), BufferedImage.TYPE_INT_RGB);
Graphics2D ig = bimage.createGraphics();
ig.drawImage(image, 0, 0, this); // copy the image
// Set some default graphics attributes
g.setFont(new Font("SansSerif", Font.BOLD, 12)); // 12pt bold text
g.setColor(Color.green); // Draw in green
g.translate(10, 10); // Set some margins
// Loop through the filters
for (int i = 0; i < filters.length; i++) {
// If the filter is null, draw the original image, otherwise,
// draw the image as processed by the filter
if (filters[i] == null)
g.drawImage(bimage, 0, 0, this);
else
g.drawImage(filters[i].filter(bimage, null), 0, 0, this);
g.drawString(filterNames[i], 0, 205); // Label the image
g.translate(137, 0); // Move over
if (i % 4 == 3)
g.translate(-137 * 4, 215); // Move down after 4
}
}
public static void main(String[] a) {
JFrame f = new JFrame();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setContentPane(new ImageOps());
f.pack();
f.setVisible(true);
}
}
Image Panel
// ImagePanel
//
// Copyright (C) by Andrea Carboni.
// This file may be distributed under the terms of the LGPL license.
//
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class ImagePanel extends JPanel
{
private ImageIcon image = new ImageIcon();
private int margin = 0;
//---------------------------------------------------------------------------
public ImagePanel()
{
}
//---------------------------------------------------------------------------
public ImagePanel(String imageFile)
{
setImage(imageFile);
}
//---------------------------------------------------------------------------
public void setImage(String imageFile)
{
image = new ImageIcon(imageFile);
updatePrefSize();
}
//---------------------------------------------------------------------------
public void setMargin(int m)
{
margin = m;
updatePrefSize();
}
//---------------------------------------------------------------------------
//---
//--- Internal methods
//---
//---------------------------------------------------------------------------
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if (image.getImage() != null)
g.drawImage(image.getImage(), margin, margin, this);
}
//---------------------------------------------------------------------------
private void updatePrefSize()
{
int iw = image.getIconWidth();
int ih = image.getIconHeight();
setPreferredSize(new Dimension(iw + margin*2, ih + margin*2));
}
}
Image Processing: Brightness and Contrast
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
public class TRescaleOp extends JFrame {
DisplayPanel displayPanel;
JButton brightenButton, darkenButton,
contIncButton, contDecButton;
public TRescaleOp() {
super();
Container container = getContentPane();
displayPanel = new DisplayPanel();
container.add(displayPanel);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2, 2));
panel.setBorder(new TitledBorder(
"Click a Button to Perform the Associated Operation..."));
brightenButton = new JButton("Brightness >>");
brightenButton.addActionListener(new ButtonListener());
darkenButton = new JButton("Brightness <<");
darkenButton.addActionListener(new ButtonListener());
contIncButton = new JButton("Contrast >>");
contIncButton.addActionListener(new ButtonListener());
contDecButton = new JButton("Contrast <<");
contDecButton.addActionListener(new ButtonListener());
panel.add(brightenButton);
panel.add(darkenButton);
panel.add(contIncButton);
panel.add(contDecButton);
container.add(BorderLayout.SOUTH, panel);
addWindowListener(new WindowEventHandler());
setSize(displayPanel.getWidth(), displayPanel.getHeight() + 10);
show(); // Display the frame
}
class WindowEventHandler extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
public static void main(String arg[]) {
new TRescaleOp();
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton temp = (JButton) e.getSource();
if (temp.equals(brightenButton)) {
displayPanel.brighten = true;
displayPanel.changeOffSet();
System.out.println(displayPanel.offset + "=offset");
displayPanel.rescale();
displayPanel.repaint();
}
else if (temp.equals(darkenButton)) {
displayPanel.brighten = false;
displayPanel.changeOffSet();
System.out.println(displayPanel.offset + "=offset");
displayPanel.rescale();
displayPanel.repaint();
}
else if (temp.equals(contIncButton)) {
displayPanel.contrastInc = true;
displayPanel.changeScaleFactor();
System.out.println(displayPanel.scaleFactor + "=scaleF");
displayPanel.rescale();
displayPanel.repaint();
}
else if (temp.equals(contDecButton)) {
displayPanel.contrastInc = false;
displayPanel.changeScaleFactor();
System.out.println(displayPanel.scaleFactor + "=scaleF");
displayPanel.rescale();
displayPanel.repaint();
}
}
}
}
class DisplayPanel extends JPanel {
Image displayImage;
BufferedImage biSrc, biDest, bi;
Graphics2D big;
RescaleOp rescale;
float scaleFactor = 1.0f;
float offset = 10;
boolean brighten, contrastInc;
DisplayPanel() {
setBackground(Color.black);
loadImage();
setSize(displayImage.getWidth(this),
displayImage.getWidth(this));
createBufferedImages();
}
public void loadImage() {
displayImage = Toolkit.getDefaultToolkit().getImage("largejexpLogo.jpg");
MediaTracker mt = new MediaTracker(this);
mt.addImage(displayImage, 1);
try {
mt.waitForAll();
} catch (Exception e) {
System.out.println("Exception while loading.");
}
if (displayImage.getWidth(this) == -1) {
System.out.println("No jpg file");
System.exit(0);
}
}
public void createBufferedImages() {
biSrc = new BufferedImage(displayImage.getWidth(this),
displayImage.getHeight(this),
BufferedImage.TYPE_INT_RGB);
big = biSrc.createGraphics();
big.drawImage(displayImage, 0, 0, this);
biDest = new BufferedImage(displayImage.getWidth(this),
displayImage.getHeight(this),
BufferedImage.TYPE_INT_RGB);
bi = biSrc;
}
public void changeOffSet() {
if (brighten) {
if (offset < 255)
offset = offset+5.0f;
}
else {
if (offset > 0)
offset = offset-5.0f;
}
}
public void changeScaleFactor() {
if (contrastInc) {
if (scaleFactor < 2)
scaleFactor = scaleFactor+0.1f;
}
else {
if (scaleFactor > 0)
scaleFactor = scaleFactor-0.1f;
}
}
public void rescale() {
rescale = new RescaleOp(scaleFactor, offset, null);
rescale.filter(biSrc, biDest);
bi = biDest;
}
public void update(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
paintComponent(g);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(bi, 0, 0, this);
}
}
Image scale
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class Scale extends JFrame {
Image image;
Insets insets;
public Scale() {
super();
ImageIcon icon = new ImageIcon("jexp.GIF");
image = icon.getImage();
}
public void paint(Graphics g) {
super.paint(g);
if (insets == null) {
insets = getInsets();
}
g.drawImage(image, insets.left, insets.top, this);
}
public void go() {
// Sleep first to see original
rest();
Image original = image;
// Down fast
image = original.getScaledInstance(200, -1, Image.SCALE_FAST);
repaint();
rest();
// Down slow
image = original.getScaledInstance(200, -1, Image.SCALE_SMOOTH);
repaint();
rest();
// Up fast
image = original.getScaledInstance(400, -1, Image.SCALE_FAST);
repaint();
rest();
// Up slow
image = original.getScaledInstance(400, -1, Image.SCALE_SMOOTH);
repaint();
rest();
System.exit(0);
}
private void rest() {
try {
Thread.sleep(5000);
} catch (InterruptedException ignored) {
}
}
public static void main(String args[]) {
Scale f = new Scale();
f.setSize(400, 400);
f.show();
f.go();
}
}
Image size
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.image.ImageObserver;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ImageSize extends JPanel{
private static Image image;
public ImageSize(URL url) {
image = Toolkit.getDefaultToolkit().getImage(url);
rightSize();
}
private void rightSize() {
int width = image.getWidth(this);
int height = image.getHeight(this);
if (width == -1 || height == -1)
return;
addNotify();
System.out.println("Image width: "+width);
System.out.println("Image height"+height);
}
public boolean imageUpdate(Image img, int infoflags, int x, int y,
int width, int height) {
if ((infoflags & ImageObserver.ERROR) != 0) {
System.out.println("Error loading image!");
System.exit(-1);
}
if ((infoflags & ImageObserver.WIDTH) != 0
&& (infoflags & ImageObserver.HEIGHT) != 0)
rightSize();
if ((infoflags & ImageObserver.SOMEBITS) != 0)
repaint();
if ((infoflags & ImageObserver.ALLBITS) != 0) {
rightSize();
repaint();
return false;
}
return true;
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
Insets insets = getInsets();
g.drawImage(image, insets.left, insets.top, this);
}
public static void main(String[] args) throws Exception {
String url = "http://www.jexp.ru/style/logo.png";
new ImageSize(new URL(url));
}
}
Image Utils
/**
* Balloontip - Balloon tips for Java Swing applications
* Copyright 2007, 2008 Bernhard Pauler, Tim Molderez
*
* This file is part of Balloontip.
*
* Balloontip is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Balloontip 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Balloontip. If not, see <http://www.gnu.org/licenses/>.
*/
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;
import javax.swing.ImageIcon;
/**
* Some methods for use with an Image
* @author Tim Molderez
*/
public class ImageUtils {
/*
* Disallow instantiating this class
*/
private ImageUtils() {};
/**
* This method returns true if the specified image has transparent pixels
* This snippet was taken from: http://www.exampledepot.ru/egs/java.awt.image/HasAlpha.html
* @param image
* @return True if the image has any transparency
*/
public static boolean hasAlpha(Image image) {
// If buffered image, the color model is readily available
if (image instanceof BufferedImage) {
BufferedImage bimage = (BufferedImage)image;
return bimage.getColorModel().hasAlpha();
}
// Use a pixel grabber to retrieve the image"s color model;
// grabbing a single pixel is usually sufficient
PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
try {
pg.grabPixels();
} catch (InterruptedException e) {
}
// Get the image"s color model
ColorModel cm = pg.getColorModel();
return cm.hasAlpha();
}
/**
* This method returns a buffered image with the contents of an image
* This snippet was taken from: http://www.exampledepot.ru/egs/java.awt.image/Image2Buf.html
* @param image
* @return The buffered image
*/
public static BufferedImage toBufferedImage(Image image) {
if (image instanceof BufferedImage) {
return (BufferedImage)image;
}
// This code ensures that all the pixels in the image are loaded
image = new ImageIcon(image).getImage();
// Determine if the image has transparent pixels; for this method"s
// implementation, see e661 Determining If an Image Has Transparent Pixels
boolean hasAlpha = hasAlpha(image);
// Create a buffered image with a format that"s compatible with the screen
BufferedImage bimage = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
try {
// Determine the type of transparency of the new buffered image
int transparency = Transparency.OPAQUE;
if (hasAlpha) {
transparency = Transparency.BITMASK;
}
// Create the buffered image
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
bimage = gc.createCompatibleImage(
image.getWidth(null), image.getHeight(null), transparency);
} catch (HeadlessException e) {
// The system does not have a screen
}
if (bimage == null) {
// Create a buffered image using the default color model
int type = BufferedImage.TYPE_INT_RGB;
if (hasAlpha) {
type = BufferedImage.TYPE_INT_ARGB;
}
bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
}
// Copy image to buffered image
Graphics g = bimage.createGraphics();
// Paint the image onto the buffered image
g.drawImage(image, 0, 0, null);
g.dispose();
return bimage;
}
}
Image Viewer
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class ImageViewer extends JFrame implements ActionListener {
public ImageViewer() {
setTitle("ImageViewer");
setSize(300, 400);
JMenuBar mbar = new JMenuBar();
JMenu m = new JMenu("File");
openItem = new JMenuItem("Open");
openItem.addActionListener(this);
m.add(openItem);
exitItem = new JMenuItem("Exit");
exitItem.addActionListener(this);
m.add(exitItem);
mbar.add(m);
setJMenuBar(mbar);
label = new JLabel();
Container contentPane = getContentPane();
contentPane.add(label, "Center");
}
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
if (source == openItem) {
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("."));
chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
return f.getName().toLowerCase().endsWith(".gif")
|| f.isDirectory();
}
public String getDescription() {
return "GIF Images";
}
});
int r = chooser.showOpenDialog(this);
if (r == JFileChooser.APPROVE_OPTION) {
String name = chooser.getSelectedFile().getName();
label.setIcon(new ImageIcon(name));
}
} else if (source == exitItem)
System.exit(0);
}
public static void main(String[] args) {
JFrame frame = new ImageViewer();
frame.show();
}
private JLabel label;
private JMenuItem openItem;
private JMenuItem exitItem;
}
Image with mouse drag and move event
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
public class BufferedImageMouseDrag extends JFrame {
DisplayCanvas canvas;
public BufferedImageMouseDrag() {
super();
Container container = getContentPane();
canvas = new DisplayCanvas();
container.add(canvas);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setSize(450, 400);
setVisible(true);
}
public static void main(String arg[]) {
new BufferedImageMouseDrag();
}
}
class DisplayCanvas extends JPanel {
int x, y;
BufferedImage bi;
DisplayCanvas() {
setBackground(Color.white);
setSize(450, 400);
addMouseMotionListener(new MouseMotionHandler());
Image image = getToolkit().getImage("largejexpLogo.gif");
MediaTracker mt = new MediaTracker(this);
mt.addImage(image, 1);
try {
mt.waitForAll();
} catch (Exception e) {
System.out.println("Exception while loading image.");
}
if (image.getWidth(this) == -1) {
System.out.println("no gif file");
System.exit(0);
}
bi = new BufferedImage(image.getWidth(this), image.getHeight(this),
BufferedImage.TYPE_INT_ARGB);
Graphics2D big = bi.createGraphics();
big.drawImage(image, 0, 0, this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(bi, x, y, this);
}
class MouseMotionHandler extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
}
}
Load and draw image
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JPanel {
public Main() {
setBackground(Color.white);
}
public void paint(Graphics g) {
try {
Graphics2D g2D;
g2D = (Graphics2D) g;
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
String fileName = "a.jpg";
Image img = getToolkit().getImage(fileName);
AffineTransform aTran = new AffineTransform();
aTran.translate(50.0f, 20.0f);
g2D.transform(aTran);
g2D.drawImage(img, new AffineTransform(), this);
} catch (Exception e) {
}
}
public static void main(String s[]) {
JFrame frame1 = new JFrame("2D Images ");
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.getContentPane().add("Center", new Main());
frame1.pack();
frame1.setSize(new Dimension(300, 300));
frame1.setVisible(true);
}
}
Make Raster Writable
/*
Copyright 2001-2004 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import java.awt.ruposite;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ruponentSampleModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.awt.image.DataBufferShort;
import java.awt.image.DataBufferUShort;
import java.awt.image.DirectColorModel;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.WritableRaster;
import java.awt.image.renderable.RenderContext;
import java.awt.image.renderable.RenderableImage;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
/*
import org.apache.batik.ext.awt.RenderingHintsKeyExt;
import org.apache.batik.ext.awt.image.renderable.PaintRable;
import org.apache.batik.ext.awt.image.rendered.AffineRed;
import org.apache.batik.ext.awt.image.rendered.Any2LsRGBRed;
import org.apache.batik.ext.awt.image.rendered.Any2sRGBRed;
import org.apache.batik.ext.awt.image.rendered.BufferedImageCachableRed;
import org.apache.batik.ext.awt.image.rendered.CachableRed;
import org.apache.batik.ext.awt.image.rendered.FormatRed;
import org.apache.batik.ext.awt.image.rendered.RenderedImageCachableRed;
import org.apache.batik.ext.awt.image.rendered.TranslateRed;
*/
/**
* Set of utility methods for Graphics.
* These generally bypass broken methods in Java2D or provide tweaked
* implementations.
*
* @author
* @version $Id: GraphicsUtil.java,v 1.36 2005/03/27 08:58:32 cam Exp $
*/
public class GraphicsUtil {
public static AffineTransform IDENTITY = new AffineTransform();
/**
* Standard prebuilt Linear_sRGB color model with no alpha.
*/
public final static ColorModel Linear_sRGB =
new DirectColorModel(ColorSpace.getInstance
(ColorSpace.CS_LINEAR_RGB), 24,
0x00FF0000, 0x0000FF00,
0x000000FF, 0x0, false,
DataBuffer.TYPE_INT);
/**
* Standard prebuilt Linear_sRGB color model with premultiplied alpha.
*/
public final static ColorModel Linear_sRGB_Pre =
new DirectColorModel(ColorSpace.getInstance
(ColorSpace.CS_LINEAR_RGB), 32,
0x00FF0000, 0x0000FF00,
0x000000FF, 0xFF000000, true,
DataBuffer.TYPE_INT);
/**
* Standard prebuilt Linear_sRGB color model with unpremultiplied alpha.
*/
public final static ColorModel Linear_sRGB_Unpre =
new DirectColorModel(ColorSpace.getInstance
(ColorSpace.CS_LINEAR_RGB), 32,
0x00FF0000, 0x0000FF00,
0x000000FF, 0xFF000000, false,
DataBuffer.TYPE_INT);
/**
* Standard prebuilt sRGB color model with no alpha.
*/
public final static ColorModel sRGB =
new DirectColorModel(ColorSpace.getInstance
(ColorSpace.CS_sRGB), 24,
0x00FF0000, 0x0000FF00,
0x000000FF, 0x0, false,
DataBuffer.TYPE_INT);
/**
* Standard prebuilt sRGB color model with premultiplied alpha.
*/
public final static ColorModel sRGB_Pre =
new DirectColorModel(ColorSpace.getInstance
(ColorSpace.CS_sRGB), 32,
0x00FF0000, 0x0000FF00,
0x000000FF, 0xFF000000, true,
DataBuffer.TYPE_INT);
/**
* Standard prebuilt sRGB color model with unpremultiplied alpha.
*/
public final static ColorModel sRGB_Unpre =
new DirectColorModel(ColorSpace.getInstance
(ColorSpace.CS_sRGB), 32,
0x00FF0000, 0x0000FF00,
0x000000FF, 0xFF000000, false,
DataBuffer.TYPE_INT);
/**
* Method that returns either Linear_sRGB_Pre or Linear_sRGB_UnPre
* based on premult flag.
* @param premult True if the ColorModel should have premultiplied alpha.
* @return a ColorMdoel with Linear sRGB colorSpace and
* the alpha channel set in accordance with
* <tt>premult</tt>
*/
public static ColorModel makeLinear_sRGBCM(boolean premult) {
if (premult)
return Linear_sRGB_Pre;
return Linear_sRGB_Unpre;
}
/**
* Constructs a BufferedImage with a linear sRGB colorModel, and alpha.
* @param width The desired width of the BufferedImage
* @param height The desired height of the BufferedImage
* @param premult The desired state of alpha premultiplied
* @return The requested BufferedImage.
*/
public static BufferedImage makeLinearBufferedImage(int width,
int height,
boolean premult) {
ColorModel cm = makeLinear_sRGBCM(premult);
WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
return new BufferedImage(cm, wr, premult, null);
}
/**
* Creates a new raster that has a <b>copy</b> of the data in
* <tt>ras</tt>. This is highly optimized for speed. There is
* no provision for changing any aspect of the SampleModel.
*
* This method should be used when you need to change the contents
* of a Raster that you do not "own" (ie the result of a
* <tt>getData</tt> call).
* @param ras The Raster to copy.
* @return A writable copy of <tt>ras</tt>
*/
public static WritableRaster copyRaster(Raster ras) {
return copyRaster(ras, ras.getMinX(), ras.getMinY());
}
/**
* Creates a new raster that has a <b>copy</b> of the data in
* <tt>ras</tt>. This is highly optimized for speed. There is
* no provision for changing any aspect of the SampleModel.
* However you can specify a new location for the returned raster.
*
* This method should be used when you need to change the contents
* of a Raster that you do not "own" (ie the result of a
* <tt>getData</tt> call).
*
* @param ras The Raster to copy.
*
* @param minX The x location for the upper left corner of the
* returned WritableRaster.
*
* @param minY The y location for the upper left corner of the
* returned WritableRaster.
*
* @return A writable copy of <tt>ras</tt>
*/
public static WritableRaster copyRaster(Raster ras, int minX, int minY) {
WritableRaster ret = Raster.createWritableRaster
(ras.getSampleModel(),
new Point(0,0));
ret = ret.createWritableChild
(ras.getMinX()-ras.getSampleModelTranslateX(),
ras.getMinY()-ras.getSampleModelTranslateY(),
ras.getWidth(), ras.getHeight(),
minX, minY, null);
// Use System.arraycopy to copy the data between the two...
DataBuffer srcDB = ras.getDataBuffer();
DataBuffer retDB = ret.getDataBuffer();
if (srcDB.getDataType() != retDB.getDataType()) {
throw new IllegalArgumentException
("New DataBuffer doesn"t match original");
}
int len = srcDB.getSize();
int banks = srcDB.getNumBanks();
int [] offsets = srcDB.getOffsets();
for (int b=0; b< banks; b++) {
switch (srcDB.getDataType()) {
case DataBuffer.TYPE_BYTE: {
DataBufferByte srcDBT = (DataBufferByte)srcDB;
DataBufferByte retDBT = (DataBufferByte)retDB;
System.arraycopy(srcDBT.getData(b), offsets[b],
retDBT.getData(b), offsets[b], len);
}
case DataBuffer.TYPE_INT: {
DataBufferInt srcDBT = (DataBufferInt)srcDB;
DataBufferInt retDBT = (DataBufferInt)retDB;
System.arraycopy(srcDBT.getData(b), offsets[b],
retDBT.getData(b), offsets[b], len);
}
case DataBuffer.TYPE_SHORT: {
DataBufferShort srcDBT = (DataBufferShort)srcDB;
DataBufferShort retDBT = (DataBufferShort)retDB;
System.arraycopy(srcDBT.getData(b), offsets[b],
retDBT.getData(b), offsets[b], len);
}
case DataBuffer.TYPE_USHORT: {
DataBufferUShort srcDBT = (DataBufferUShort)srcDB;
DataBufferUShort retDBT = (DataBufferUShort)retDB;
System.arraycopy(srcDBT.getData(b), offsets[b],
retDBT.getData(b), offsets[b], len);
}
}
}
return ret;
}
/**
* Coerces <tt>ras</tt> to be writable. The returned Raster continues to
* reference the DataBuffer from ras, so modifications to the returned
* WritableRaster will be seen in ras.<p>
*
* This method should only be used if you need a WritableRaster due to
* an interface (such as to construct a BufferedImage), but have no
* intention of modifying the contents of the returned Raster. If
* you have any doubt about other users of the data in <tt>ras</tt>,
* use copyRaster (above).
* @param ras The raster to make writable.
* @return A Writable version of ras (shares DataBuffer with
* <tt>ras</tt>).
*/
public static WritableRaster makeRasterWritable(Raster ras) {
return makeRasterWritable(ras, ras.getMinX(), ras.getMinY());
}
/**
* Coerces <tt>ras</tt> to be writable. The returned Raster continues to
* reference the DataBuffer from ras, so modifications to the returned
* WritableRaster will be seen in ras.<p>
*
* You can specify a new location for the returned WritableRaster, this
* is especially useful for constructing BufferedImages which require
* the Raster to be at (0,0).
*
* This method should only be used if you need a WritableRaster due to
* an interface (such as to construct a BufferedImage), but have no
* intention of modifying the contents of the returned Raster. If
* you have any doubt about other users of the data in <tt>ras</tt>,
* use copyRaster (above).
*
* @param ras The raster to make writable.
*
* @param minX The x location for the upper left corner of the
* returned WritableRaster.
*
* @param minY The y location for the upper left corner of the
* returned WritableRaster.
*
* @return A Writable version of <tT>ras</tt> with it"s upper left
* hand coordinate set to minX, minY (shares it"s DataBuffer
* with <tt>ras</tt>).
*/
public static WritableRaster makeRasterWritable(Raster ras,
int minX, int minY) {
WritableRaster ret = Raster.createWritableRaster
(ras.getSampleModel(),
ras.getDataBuffer(),
new Point(0,0));
ret = ret.createWritableChild
(ras.getMinX()-ras.getSampleModelTranslateX(),
ras.getMinY()-ras.getSampleModelTranslateY(),
ras.getWidth(), ras.getHeight(),
minX, minY, null);
return ret;
}
/**
* Create a new ColorModel with it"s alpha premultiplied state matching
* newAlphaPreMult.
* @param cm The ColorModel to change the alpha premult state of.
* @param newAlphaPreMult The new state of alpha premult.
* @return A new colorModel that has isAlphaPremultiplied()
* equal to newAlphaPreMult.
*/
public static ColorModel
coerceColorModel(ColorModel cm, boolean newAlphaPreMult) {
if (cm.isAlphaPremultiplied() == newAlphaPreMult)
return cm;
// Easiest way to build proper colormodel for new Alpha state...
// Eventually this should switch on known ColorModel types and
// only fall back on this hack when the CM type is unknown.
WritableRaster wr = cm.createCompatibleWritableRaster(1,1);
return cm.coerceData(wr, newAlphaPreMult);
}
/**
* Coerces data within a bufferedImage to match newAlphaPreMult,
* Note that this can not change the colormodel of bi so you
*
* @param wr The raster to change the state of.
* @param cm The colormodel currently associated with data in wr.
* @param newAlphaPreMult The desired state of alpha Premult for raster.
* @return A new colormodel that matches newAlphaPreMult.
*/
public static ColorModel
coerceData(WritableRaster wr, ColorModel cm, boolean newAlphaPreMult) {
// System.out.println("CoerceData: " + cm.isAlphaPremultiplied() +
// " Out: " + newAlphaPreMult);
if (cm.hasAlpha()== false)
// Nothing to do no alpha channel
return cm;
if (cm.isAlphaPremultiplied() == newAlphaPreMult)
// nothing to do alpha state matches...
return cm;
// System.out.println("CoerceData: " + wr.getSampleModel());
if (newAlphaPreMult) {
multiplyAlpha(wr);
} else {
divideAlpha(wr);
}
return coerceColorModel(cm, newAlphaPreMult);
}
public static void multiplyAlpha(WritableRaster wr) {
if (is_BYTE_COMP_Data(wr.getSampleModel()))
mult_BYTE_COMP_Data(wr);
else if (is_INT_PACK_Data(wr.getSampleModel(), true))
mult_INT_PACK_Data(wr);
else {
int [] pixel = null;
int bands = wr.getNumBands();
float norm = 1f/255f;
int x0, x1, y0, y1, a, b;
float alpha;
x0 = wr.getMinX();
x1 = x0+wr.getWidth();
y0 = wr.getMinY();
y1 = y0+wr.getHeight();
for (int y=y0; y<y1; y++)
for (int x=x0; x<x1; x++) {
pixel = wr.getPixel(x,y,pixel);
a = pixel[bands-1];
if ((a >= 0) && (a < 255)) {
alpha = a*norm;
for (b=0; b<bands-1; b++)
pixel[b] = (int)(pixel[b]*alpha+0.5f);
wr.setPixel(x,y,pixel);
}
}
}
}
public static void divideAlpha(WritableRaster wr) {
if (is_BYTE_COMP_Data(wr.getSampleModel()))
divide_BYTE_COMP_Data(wr);
else if (is_INT_PACK_Data(wr.getSampleModel(), true))
divide_INT_PACK_Data(wr);
else {
int x0, x1, y0, y1, a, b;
float ialpha;
int bands = wr.getNumBands();
int [] pixel = null;
x0 = wr.getMinX();
x1 = x0+wr.getWidth();
y0 = wr.getMinY();
y1 = y0+wr.getHeight();
for (int y=y0; y<y1; y++)
for (int x=x0; x<x1; x++) {
pixel = wr.getPixel(x,y,pixel);
a = pixel[bands-1];
if ((a > 0) && (a < 255)) {
ialpha = 255/(float)a;
for (b=0; b<bands-1; b++)
pixel[b] = (int)(pixel[b]*ialpha+0.5f);
wr.setPixel(x,y,pixel);
}
}
}
}
public static boolean is_INT_PACK_Data(SampleModel sm,
boolean requireAlpha) {
// Check ColorModel is of type DirectColorModel
if(!(sm instanceof SinglePixelPackedSampleModel)) return false;
// Check transfer type
if(sm.getDataType() != DataBuffer.TYPE_INT) return false;
SinglePixelPackedSampleModel sppsm;
sppsm = (SinglePixelPackedSampleModel)sm;
int [] masks = sppsm.getBitMasks();
if (masks.length == 3) {
if (requireAlpha) return false;
} else if (masks.length != 4)
return false;
if(masks[0] != 0x00ff0000) return false;
if(masks[1] != 0x0000ff00) return false;
if(masks[2] != 0x000000ff) return false;
if ((masks.length == 4) &&
(masks[3] != 0xff000000)) return false;
return true;
}
public static boolean is_BYTE_COMP_Data(SampleModel sm) {
// Check ColorModel is of type DirectColorModel
if(!(sm instanceof ComponentSampleModel)) return false;
// Check transfer type
if(sm.getDataType() != DataBuffer.TYPE_BYTE) return false;
return true;
}
protected static void divide_INT_PACK_Data(WritableRaster wr) {
// System.out.println("Divide Int");
SinglePixelPackedSampleModel sppsm;
sppsm = (SinglePixelPackedSampleModel)wr.getSampleModel();
final int width = wr.getWidth();
final int scanStride = sppsm.getScanlineStride();
DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
final int base
= (db.getOffset() +
sppsm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
wr.getMinY()-wr.getSampleModelTranslateY()));
int pixel, a, aFP;
// Access the pixel data array
final int pixels[] = db.getBankData()[0];
for (int y=0; y<wr.getHeight(); y++) {
int sp = base + y*scanStride;
final int end = sp + width;
while (sp < end) {
pixel = pixels[sp];
a = pixel>>>24;
if (a<=0) {
pixels[sp] = 0x00FFFFFF;
}
else if (a<255) {
aFP = (0x00FF0000/a);
pixels[sp] =
((a << 24) |
(((((pixel&0xFF0000)>>16)*aFP)&0xFF0000) ) |
(((((pixel&0x00FF00)>>8) *aFP)&0xFF0000)>>8 ) |
(((((pixel&0x0000FF)) *aFP)&0xFF0000)>>16));
}
sp++;
}
}
}
protected static void mult_INT_PACK_Data(WritableRaster wr) {
// System.out.println("Multiply Int: " + wr);
SinglePixelPackedSampleModel sppsm;
sppsm = (SinglePixelPackedSampleModel)wr.getSampleModel();
final int width = wr.getWidth();
final int scanStride = sppsm.getScanlineStride();
DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
final int base
= (db.getOffset() +
sppsm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
wr.getMinY()-wr.getSampleModelTranslateY()));
// Access the pixel data array
final int pixels[] = db.getBankData()[0];
for (int y=0; y<wr.getHeight(); y++) {
int sp = base + y*scanStride;
final int end = sp + width;
while (sp < end) {
int pixel = pixels[sp];
int a = pixel>>>24;
if ((a>=0) && (a<255)) {
pixels[sp] = ((a << 24) |
((((pixel&0xFF0000)*a)>>8)&0xFF0000) |
((((pixel&0x00FF00)*a)>>8)&0x00FF00) |
((((pixel&0x0000FF)*a)>>8)&0x0000FF));
}
sp++;
}
}
}
protected static void divide_BYTE_COMP_Data(WritableRaster wr) {
// System.out.println("Multiply Int: " + wr);
ComponentSampleModel csm;
csm = (ComponentSampleModel)wr.getSampleModel();
final int width = wr.getWidth();
final int scanStride = csm.getScanlineStride();
final int pixStride = csm.getPixelStride();
final int [] bandOff = csm.getBandOffsets();
DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
final int base
= (db.getOffset() +
csm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
wr.getMinY()-wr.getSampleModelTranslateY()));
int a=0;
int aOff = bandOff[bandOff.length-1];
int bands = bandOff.length-1;
int b, i;
// Access the pixel data array
final byte pixels[] = db.getBankData()[0];
for (int y=0; y<wr.getHeight(); y++) {
int sp = base + y*scanStride;
final int end = sp + width*pixStride;
while (sp < end) {
a = pixels[sp+aOff]&0xFF;
if (a==0) {
for (b=0; b<bands; b++)
pixels[sp+bandOff[b]] = (byte)0xFF;
} else if (a<255) {
int aFP = (0x00FF0000/a);
for (b=0; b<bands; b++) {
i = sp+bandOff[b];
pixels[i] = (byte)(((pixels[i]&0xFF)*aFP)>>>16);
}
}
sp+=pixStride;
}
}
}
protected static void mult_BYTE_COMP_Data(WritableRaster wr) {
// System.out.println("Multiply Int: " + wr);
ComponentSampleModel csm;
csm = (ComponentSampleModel)wr.getSampleModel();
final int width = wr.getWidth();
final int scanStride = csm.getScanlineStride();
final int pixStride = csm.getPixelStride();
final int [] bandOff = csm.getBandOffsets();
DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
final int base
= (db.getOffset() +
csm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
wr.getMinY()-wr.getSampleModelTranslateY()));
int a=0;
int aOff = bandOff[bandOff.length-1];
int bands = bandOff.length-1;
int b, i;
// Access the pixel data array
final byte pixels[] = db.getBankData()[0];
for (int y=0; y<wr.getHeight(); y++) {
int sp = base + y*scanStride;
final int end = sp + width*pixStride;
while (sp < end) {
a = pixels[sp+aOff]&0xFF;
if (a!=0xFF)
for (b=0; b<bands; b++) {
i = sp+bandOff[b];
pixels[i] = (byte)(((pixels[i]&0xFF)*a)>>8);
}
sp+=pixStride;
}
}
}
/*
This is skanky debugging code that might be useful in the future:
if (count == 33) {
String label = "sub [" + x + ", " + y + "]: ";
org.ImageDisplay.showImage
(label, subBI);
org.ImageDisplay.printImage
(label, subBI,
new Rectangle(75-iR.x, 90-iR.y, 32, 32));
}
// if ((count++ % 50) == 10)
// org.ImageDisplay.showImage("foo: ", subBI);
Graphics2D realG2D = g2d;
while (realG2D instanceof sun.java2d.ProxyGraphics2D) {
realG2D = ((sun.java2d.ProxyGraphics2D)realG2D).getDelegate();
}
if (realG2D instanceof sun.awt.image.BufferedImageGraphics2D) {
count++;
if (count == 34) {
RenderedImage ri;
ri = ((sun.awt.image.BufferedImageGraphics2D)realG2D).bufImg;
// g2d.setComposite(SVGComposite.OVER);
// org.ImageDisplay.showImage("Bar: " + count, cr);
org.ImageDisplay.printImage("Bar: " + count, cr,
new Rectangle(75, 90, 32, 32));
org.ImageDisplay.showImage ("Foo: " + count, ri);
org.ImageDisplay.printImage("Foo: " + count, ri,
new Rectangle(75, 90, 32, 32));
System.out.println("BI: " + ri);
System.out.println("BISM: " + ri.getSampleModel());
System.out.println("BICM: " + ri.getColorModel());
System.out.println("BICM class: " + ri.getColorModel().getClass());
System.out.println("BICS: " + ri.getColorModel().getColorSpace());
System.out.println
("sRGB CS: " +
ColorSpace.getInstance(ColorSpace.CS_sRGB));
System.out.println("G2D info");
System.out.println("\tComposite: " + g2d.getComposite());
System.out.println("\tTransform" + g2d.getTransform());
java.awt.RenderingHints rh = g2d.getRenderingHints();
java.util.Set keys = rh.keySet();
java.util.Iterator iter = keys.iterator();
while (iter.hasNext()) {
Object o = iter.next();
System.out.println("\t" + o.toString() + " -> " +
rh.get(o).toString());
}
ri = cr;
System.out.println("RI: " + ri);
System.out.println("RISM: " + ri.getSampleModel());
System.out.println("RICM: " + ri.getColorModel());
System.out.println("RICM class: " + ri.getColorModel().getClass());
System.out.println("RICS: " + ri.getColorModel().getColorSpace());
}
}
*/
}
Optimized version of copyData designed to work on Integer packed data with a SinglePixelPackedSampleModel
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id: GraphicsUtil.java 603243 2007-12-11 13:49:04Z jeremias $ */
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ruponentSampleModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.awt.image.DataBufferShort;
import java.awt.image.DataBufferUShort;
import java.awt.image.DirectColorModel;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.WritableRaster;
/**
* Set of utility methods for Graphics.
* These generally bypass broken methods in Java2D or provide tweaked
* implementations.
*
* @author
* @version $Id: GraphicsUtil.java 603243 2007-12-11 13:49:04Z jeremias $
*/
public class GraphicsUtil {
public static AffineTransform IDENTITY = new AffineTransform();
/**
* Standard prebuilt Linear_sRGB color model with no alpha */
public static final ColorModel Linear_sRGB =
new DirectColorModel(ColorSpace.getInstance
(ColorSpace.CS_LINEAR_RGB), 24,
0x00FF0000, 0x0000FF00,
0x000000FF, 0x0, false,
DataBuffer.TYPE_INT);
/**
* Standard prebuilt Linear_sRGB color model with premultiplied alpha.
*/
public static final ColorModel Linear_sRGB_Pre =
new DirectColorModel(ColorSpace.getInstance
(ColorSpace.CS_LINEAR_RGB), 32,
0x00FF0000, 0x0000FF00,
0x000000FF, 0xFF000000, true,
DataBuffer.TYPE_INT);
/**
* Standard prebuilt Linear_sRGB color model with unpremultiplied alpha.
*/
public static final ColorModel Linear_sRGB_Unpre =
new DirectColorModel(ColorSpace.getInstance
(ColorSpace.CS_LINEAR_RGB), 32,
0x00FF0000, 0x0000FF00,
0x000000FF, 0xFF000000, false,
DataBuffer.TYPE_INT);
/**
* Standard prebuilt sRGB color model with no alpha.
*/
public static final ColorModel sRGB =
new DirectColorModel(ColorSpace.getInstance
(ColorSpace.CS_sRGB), 24,
0x00FF0000, 0x0000FF00,
0x000000FF, 0x0, false,
DataBuffer.TYPE_INT);
/**
* Standard prebuilt sRGB color model with premultiplied alpha.
*/
public static final ColorModel sRGB_Pre =
new DirectColorModel(ColorSpace.getInstance
(ColorSpace.CS_sRGB), 32,
0x00FF0000, 0x0000FF00,
0x000000FF, 0xFF000000, true,
DataBuffer.TYPE_INT);
/**
* Standard prebuilt sRGB color model with unpremultiplied alpha.
*/
public static final ColorModel sRGB_Unpre =
new DirectColorModel(ColorSpace.getInstance
(ColorSpace.CS_sRGB), 32,
0x00FF0000, 0x0000FF00,
0x000000FF, 0xFF000000, false,
DataBuffer.TYPE_INT);
/**
* Method that returns either Linear_sRGB_Pre or Linear_sRGB_UnPre
* based on premult flag.
* @param premult True if the ColorModel should have premultiplied alpha.
* @return a ColorMdoel with Linear sRGB colorSpace and
* the alpha channel set in accordance with
* <tt>premult</tt>
*/
public static ColorModel makeLinear_sRGBCM(boolean premult) {
return premult ? Linear_sRGB_Pre : Linear_sRGB_Unpre;
}
/**
* Constructs a BufferedImage with a linear sRGB colorModel, and alpha.
* @param width The desired width of the BufferedImage
* @param height The desired height of the BufferedImage
* @param premult The desired state of alpha premultiplied
* @return The requested BufferedImage.
*/
public static BufferedImage makeLinearBufferedImage(int width,
int height,
boolean premult) {
ColorModel cm = makeLinear_sRGBCM(premult);
WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
return new BufferedImage(cm, wr, premult, null);
}
/**
* An internal optimized version of copyData designed to work on
* Integer packed data with a SinglePixelPackedSampleModel. Only
* the region of overlap between src and dst is copied.
*
* Calls to this should be preflighted with is_INT_PACK_Data
* on both src and dest (requireAlpha can be false).
*
* @param src The source of the data
* @param dst The destination for the data.
*/
public static void copyData_INT_PACK(Raster src, WritableRaster dst) {
// System.out.println("Fast copyData");
int x0 = dst.getMinX();
if (x0 < src.getMinX()) x0 = src.getMinX();
int y0 = dst.getMinY();
if (y0 < src.getMinY()) y0 = src.getMinY();
int x1 = dst.getMinX()+dst.getWidth()-1;
if (x1 > src.getMinX()+src.getWidth()-1)
x1 = src.getMinX()+src.getWidth()-1;
int y1 = dst.getMinY()+dst.getHeight()-1;
if (y1 > src.getMinY()+src.getHeight()-1)
y1 = src.getMinY()+src.getHeight()-1;
int width = x1-x0+1;
int height = y1-y0+1;
SinglePixelPackedSampleModel srcSPPSM;
srcSPPSM = (SinglePixelPackedSampleModel)src.getSampleModel();
final int srcScanStride = srcSPPSM.getScanlineStride();
DataBufferInt srcDB = (DataBufferInt)src.getDataBuffer();
final int [] srcPixels = srcDB.getBankData()[0];
final int srcBase =
(srcDB.getOffset() +
srcSPPSM.getOffset(x0-src.getSampleModelTranslateX(),
y0-src.getSampleModelTranslateY()));
SinglePixelPackedSampleModel dstSPPSM;
dstSPPSM = (SinglePixelPackedSampleModel)dst.getSampleModel();
final int dstScanStride = dstSPPSM.getScanlineStride();
DataBufferInt dstDB = (DataBufferInt)dst.getDataBuffer();
final int [] dstPixels = dstDB.getBankData()[0];
final int dstBase =
(dstDB.getOffset() +
dstSPPSM.getOffset(x0-dst.getSampleModelTranslateX(),
y0-dst.getSampleModelTranslateY()));
if ((srcScanStride == dstScanStride) &&
(srcScanStride == width)) {
// System.out.println("VERY Fast copyData");
System.arraycopy(srcPixels, srcBase, dstPixels, dstBase,
width*height);
} else if (width > 128) {
int srcSP = srcBase;
int dstSP = dstBase;
for (int y=0; y<height; y++) {
System.arraycopy(srcPixels, srcSP, dstPixels, dstSP, width);
srcSP += srcScanStride;
dstSP += dstScanStride;
}
} else {
for (int y=0; y<height; y++) {
int srcSP = srcBase+y*srcScanStride;
int dstSP = dstBase+y*dstScanStride;
for (int x=0; x<width; x++)
dstPixels[dstSP++] = srcPixels[srcSP++];
}
}
}
public static void copyData_FALLBACK(Raster src, WritableRaster dst) {
// System.out.println("Fallback copyData");
int x0 = dst.getMinX();
if (x0 < src.getMinX()) x0 = src.getMinX();
int y0 = dst.getMinY();
if (y0 < src.getMinY()) y0 = src.getMinY();
int x1 = dst.getMinX()+dst.getWidth()-1;
if (x1 > src.getMinX()+src.getWidth()-1)
x1 = src.getMinX()+src.getWidth()-1;
int y1 = dst.getMinY()+dst.getHeight()-1;
if (y1 > src.getMinY()+src.getHeight()-1)
y1 = src.getMinY()+src.getHeight()-1;
int width = x1-x0+1;
int [] data = null;
for (int y = y0; y <= y1 ; y++) {
data = src.getPixels(x0,y,width,1,data);
dst.setPixels (x0,y,width,1,data);
}
}
/**
* Copies data from one raster to another. Only the region of
* overlap between src and dst is copied. <tt>Src</tt> and
* <tt>Dst</tt> must have compatible SampleModels.
*
* @param src The source of the data
* @param dst The destination for the data.
*/
public static void copyData(Raster src, WritableRaster dst) {
if (is_INT_PACK_Data(src.getSampleModel(), false) &&
is_INT_PACK_Data(dst.getSampleModel(), false)) {
copyData_INT_PACK(src, dst);
return;
}
copyData_FALLBACK(src, dst);
}
/**
* Creates a new raster that has a <b>copy</b> of the data in
* <tt>ras</tt>. This is highly optimized for speed. There is
* no provision for changing any aspect of the SampleModel.
*
* This method should be used when you need to change the contents
* of a Raster that you do not "own" (ie the result of a
* <tt>getData</tt> call).
* @param ras The Raster to copy.
* @return A writable copy of <tt>ras</tt>
*/
public static WritableRaster copyRaster(Raster ras) {
return copyRaster(ras, ras.getMinX(), ras.getMinY());
}
/**
* Creates a new raster that has a <b>copy</b> of the data in
* <tt>ras</tt>. This is highly optimized for speed. There is
* no provision for changing any aspect of the SampleModel.
* However you can specify a new location for the returned raster.
*
* This method should be used when you need to change the contents
* of a Raster that you do not "own" (ie the result of a
* <tt>getData</tt> call).
*
* @param ras The Raster to copy.
*
* @param minX The x location for the upper left corner of the
* returned WritableRaster.
*
* @param minY The y location for the upper left corner of the
* returned WritableRaster.
*
* @return A writable copy of <tt>ras</tt>
*/
public static WritableRaster copyRaster(Raster ras, int minX, int minY) {
WritableRaster ret = Raster.createWritableRaster
(ras.getSampleModel(),
new Point(0,0));
ret = ret.createWritableChild
(ras.getMinX()-ras.getSampleModelTranslateX(),
ras.getMinY()-ras.getSampleModelTranslateY(),
ras.getWidth(), ras.getHeight(),
minX, minY, null);
// Use System.arraycopy to copy the data between the two...
DataBuffer srcDB = ras.getDataBuffer();
DataBuffer retDB = ret.getDataBuffer();
if (srcDB.getDataType() != retDB.getDataType()) {
throw new IllegalArgumentException
("New DataBuffer doesn"t match original");
}
int len = srcDB.getSize();
int banks = srcDB.getNumBanks();
int [] offsets = srcDB.getOffsets();
for (int b=0; b< banks; b++) {
switch (srcDB.getDataType()) {
case DataBuffer.TYPE_BYTE: {
DataBufferByte srcDBT = (DataBufferByte)srcDB;
DataBufferByte retDBT = (DataBufferByte)retDB;
System.arraycopy(srcDBT.getData(b), offsets[b],
retDBT.getData(b), offsets[b], len);
break;
}
case DataBuffer.TYPE_INT: {
DataBufferInt srcDBT = (DataBufferInt)srcDB;
DataBufferInt retDBT = (DataBufferInt)retDB;
System.arraycopy(srcDBT.getData(b), offsets[b],
retDBT.getData(b), offsets[b], len);
break;
}
case DataBuffer.TYPE_SHORT: {
DataBufferShort srcDBT = (DataBufferShort)srcDB;
DataBufferShort retDBT = (DataBufferShort)retDB;
System.arraycopy(srcDBT.getData(b), offsets[b],
retDBT.getData(b), offsets[b], len);
break;
}
case DataBuffer.TYPE_USHORT: {
DataBufferUShort srcDBT = (DataBufferUShort)srcDB;
DataBufferUShort retDBT = (DataBufferUShort)retDB;
System.arraycopy(srcDBT.getData(b), offsets[b],
retDBT.getData(b), offsets[b], len);
break;
}
}
}
return ret;
}
/**
* Coerces <tt>ras</tt> to be writable. The returned Raster continues to
* reference the DataBuffer from ras, so modifications to the returned
* WritableRaster will be seen in ras.<p>
*
* This method should only be used if you need a WritableRaster due to
* an interface (such as to construct a BufferedImage), but have no
* intention of modifying the contents of the returned Raster. If
* you have any doubt about other users of the data in <tt>ras</tt>,
* use copyRaster (above).
* @param ras The raster to make writable.
* @return A Writable version of ras (shares DataBuffer with
* <tt>ras</tt>).
*/
public static WritableRaster makeRasterWritable(Raster ras) {
return makeRasterWritable(ras, ras.getMinX(), ras.getMinY());
}
/**
* Coerces <tt>ras</tt> to be writable. The returned Raster continues to
* reference the DataBuffer from ras, so modifications to the returned
* WritableRaster will be seen in ras.<p>
*
* You can specify a new location for the returned WritableRaster, this
* is especially useful for constructing BufferedImages which require
* the Raster to be at (0,0).
*
* This method should only be used if you need a WritableRaster due to
* an interface (such as to construct a BufferedImage), but have no
* intention of modifying the contents of the returned Raster. If
* you have any doubt about other users of the data in <tt>ras</tt>,
* use copyRaster (above).
*
* @param ras The raster to make writable.
*
* @param minX The x location for the upper left corner of the
* returned WritableRaster.
*
* @param minY The y location for the upper left corner of the
* returned WritableRaster.
*
* @return A Writable version of <tT>ras</tt> with it"s upper left
* hand coordinate set to minX, minY (shares it"s DataBuffer
* with <tt>ras</tt>).
*/
public static WritableRaster makeRasterWritable(Raster ras,
int minX, int minY) {
WritableRaster ret = Raster.createWritableRaster
(ras.getSampleModel(),
ras.getDataBuffer(),
new Point(0,0));
ret = ret.createWritableChild
(ras.getMinX()-ras.getSampleModelTranslateX(),
ras.getMinY()-ras.getSampleModelTranslateY(),
ras.getWidth(), ras.getHeight(),
minX, minY, null);
return ret;
}
/**
* Create a new ColorModel with it"s alpha premultiplied state matching
* newAlphaPreMult.
* @param cm The ColorModel to change the alpha premult state of.
* @param newAlphaPreMult The new state of alpha premult.
* @return A new colorModel that has isAlphaPremultiplied()
* equal to newAlphaPreMult.
*/
public static ColorModel
coerceColorModel(ColorModel cm, boolean newAlphaPreMult) {
if (cm.isAlphaPremultiplied() == newAlphaPreMult)
return cm;
// Easiest way to build proper colormodel for new Alpha state...
// Eventually this should switch on known ColorModel types and
// only fall back on this hack when the CM type is unknown.
WritableRaster wr = cm.createCompatibleWritableRaster(1,1);
return cm.coerceData(wr, newAlphaPreMult);
}
/**
* Coerces data within a bufferedImage to match newAlphaPreMult,
* Note that this can not change the colormodel of bi so you
*
* @param wr The raster to change the state of.
* @param cm The colormodel currently associated with data in wr.
* @param newAlphaPreMult The desired state of alpha Premult for raster.
* @return A new colormodel that matches newAlphaPreMult.
*/
public static ColorModel
coerceData(WritableRaster wr, ColorModel cm, boolean newAlphaPreMult) {
// System.out.println("CoerceData: " + cm.isAlphaPremultiplied() +
// " Out: " + newAlphaPreMult);
if (!cm.hasAlpha())
// Nothing to do no alpha channel
return cm;
if (cm.isAlphaPremultiplied() == newAlphaPreMult)
// nothing to do alpha state matches...
return cm;
// System.out.println("CoerceData: " + wr.getSampleModel());
if (newAlphaPreMult) {
multiplyAlpha(wr);
} else {
divideAlpha(wr);
}
return coerceColorModel(cm, newAlphaPreMult);
}
public static void multiplyAlpha(WritableRaster wr) {
if (is_BYTE_COMP_Data(wr.getSampleModel()))
mult_BYTE_COMP_Data(wr);
else if (is_INT_PACK_Data(wr.getSampleModel(), true))
mult_INT_PACK_Data(wr);
else {
int [] pixel = null;
int bands = wr.getNumBands();
float norm = 1f/255f;
int x0, x1, y0, y1, a, b;
float alpha;
x0 = wr.getMinX();
x1 = x0+wr.getWidth();
y0 = wr.getMinY();
y1 = y0+wr.getHeight();
for (int y=y0; y<y1; y++)
for (int x=x0; x<x1; x++) {
pixel = wr.getPixel(x,y,pixel);
a = pixel[bands-1];
if ((a >= 0) && (a < 255)) {
alpha = a*norm;
for (b=0; b<bands-1; b++)
pixel[b] = (int)(pixel[b]*alpha+0.5f);
wr.setPixel(x,y,pixel);
}
}
}
}
public static void divideAlpha(WritableRaster wr) {
if (is_BYTE_COMP_Data(wr.getSampleModel()))
divide_BYTE_COMP_Data(wr);
else if (is_INT_PACK_Data(wr.getSampleModel(), true))
divide_INT_PACK_Data(wr);
else {
int x0, x1, y0, y1, a, b;
float ialpha;
int bands = wr.getNumBands();
int [] pixel = null;
x0 = wr.getMinX();
x1 = x0+wr.getWidth();
y0 = wr.getMinY();
y1 = y0+wr.getHeight();
for (int y=y0; y<y1; y++)
for (int x=x0; x<x1; x++) {
pixel = wr.getPixel(x,y,pixel);
a = pixel[bands-1];
if ((a > 0) && (a < 255)) {
ialpha = 255/(float)a;
for (b=0; b<bands-1; b++)
pixel[b] = (int)(pixel[b]*ialpha+0.5f);
wr.setPixel(x,y,pixel);
}
}
}
}
/**
* Copies data from one bufferedImage to another paying attention
* to the state of AlphaPreMultiplied.
*
* @param src The source
* @param dst The destination
*/
public static void
copyData(BufferedImage src, BufferedImage dst) {
Rectangle srcRect = new Rectangle(0, 0,
src.getWidth(), src.getHeight());
copyData(src, srcRect, dst, new Point(0,0));
}
/**
* Copies data from one bufferedImage to another paying attention
* to the state of AlphaPreMultiplied.
*
* @param src The source
* @param srcRect The Rectangle of source data to be copied
* @param dst The destination
* @param destP The Place for the upper left corner of srcRect in dst.
*/
public static void
copyData(BufferedImage src, Rectangle srcRect,
BufferedImage dst, Point destP) {
/*
if (srcCS != dstCS)
throw new IllegalArgumentException
("Images must be in the same ColorSpace in order "+
"to copy Data between them");
*/
boolean srcAlpha = src.getColorModel().hasAlpha();
boolean dstAlpha = dst.getColorModel().hasAlpha();
// System.out.println("Src has: " + srcAlpha +
// " is: " + src.isAlphaPremultiplied());
//
// System.out.println("Dst has: " + dstAlpha +
// " is: " + dst.isAlphaPremultiplied());
if (srcAlpha == dstAlpha)
if (!srcAlpha ||
src.isAlphaPremultiplied() == dst.isAlphaPremultiplied()) {
// They match one another so just copy everything...
copyData(src.getRaster(), dst.getRaster());
return;
}
// System.out.println("Using Slow CopyData");
int [] pixel = null;
Raster srcR = src.getRaster();
WritableRaster dstR = dst.getRaster();
int bands = dstR.getNumBands();
int dx = destP.x-srcRect.x;
int dy = destP.y-srcRect.y;
int w = srcRect.width;
int x0 = srcRect.x;
int y0 = srcRect.y;
int y1 = y0+srcRect.height-1;
if (!srcAlpha) {
// Src has no alpha dest does so set alpha to 1.0 everywhere.
// System.out.println("Add Alpha");
int [] oPix = new int[bands*w];
int out = (w*bands)-1; // The 2 skips alpha channel
while(out >= 0) {
// Fill alpha channel with 255"s
oPix[out] = 255;
out -= bands;
}
int b, in;
for (int y=y0; y<=y1; y++) {
pixel = srcR.getPixels(x0,y,w,1,pixel);
in = w*(bands-1)-1;
out = (w*bands)-2; // The 2 skips alpha channel on last pix
switch (bands) {
case 4:
while(in >= 0) {
oPix[out--] = pixel[in--];
oPix[out--] = pixel[in--];
oPix[out--] = pixel[in--];
out--;
}
break;
default:
while(in >= 0) {
for (b=0; b<bands-1; b++)
oPix[out--] = pixel[in--];
out--;
}
}
dstR.setPixels(x0+dx, y+dy, w, 1, oPix);
}
} else if (dstAlpha && dst.isAlphaPremultiplied()) {
// Src and dest have Alpha but we need to multiply it for dst.
// System.out.println("Mult Case");
int a, b, alpha, in, fpNorm = (1<<24)/255, pt5 = 1<<23;
for (int y=y0; y<=y1; y++) {
pixel = srcR.getPixels(x0,y,w,1,pixel);
in=bands*w-1;
switch (bands) {
case 4:
while(in >= 0) {
a = pixel[in];
if (a == 255)
in -= 4;
else {
in--;
alpha = fpNorm*a;
pixel[in] = (pixel[in]*alpha+pt5)>>>24; in--;
pixel[in] = (pixel[in]*alpha+pt5)>>>24; in--;
pixel[in] = (pixel[in]*alpha+pt5)>>>24; in--;
}
}
break;
default:
while(in >= 0) {
a = pixel[in];
if (a == 255)
in -= bands;
else {
in--;
alpha = fpNorm*a;
for (b=0; b<bands-1; b++) {
pixel[in] = (pixel[in]*alpha+pt5)>>>24;
in--;
}
}
}
}
dstR.setPixels(x0+dx, y+dy, w, 1, pixel);
}
} else if (dstAlpha && !dst.isAlphaPremultiplied()) {
// Src and dest have Alpha but we need to divide it out for dst.
// System.out.println("Div Case");
int a, b, ialpha, in, fpNorm = 0x00FF0000, pt5 = 1<<15;
for (int y=y0; y<=y1; y++) {
pixel = srcR.getPixels(x0,y,w,1,pixel);
in=(bands*w)-1;
switch(bands) {
case 4:
while(in >= 0) {
a = pixel[in];
if ((a <= 0) || (a >= 255))
in -= 4;
else {
in--;
ialpha = fpNorm/a;
pixel[in] = (pixel[in]*ialpha+pt5)>>>16; in--;
pixel[in] = (pixel[in]*ialpha+pt5)>>>16; in--;
pixel[in] = (pixel[in]*ialpha+pt5)>>>16; in--;
}
}
break;
default:
while(in >= 0) {
a = pixel[in];
if ((a <= 0) || (a >= 255))
in -= bands;
else {
in--;
ialpha = fpNorm/a;
for (b=0; b<bands-1; b++) {
pixel[in] = (pixel[in]*ialpha+pt5)>>>16;
in--;
}
}
}
}
dstR.setPixels(x0+dx, y+dy, w, 1, pixel);
}
} else if (src.isAlphaPremultiplied()) {
int [] oPix = new int[bands*w];
// Src has alpha dest does not so unpremult and store...
// System.out.println("Remove Alpha, Div Case");
int a, b, ialpha, in, out, fpNorm = 0x00FF0000, pt5 = 1<<15;
for (int y=y0; y<=y1; y++) {
pixel = srcR.getPixels(x0,y,w,1,pixel);
in = (bands+1)*w -1;
out = (bands*w)-1;
while(in >= 0) {
a = pixel[in]; in--;
if (a > 0) {
if (a < 255) {
ialpha = fpNorm/a;
for (b=0; b<bands; b++)
oPix[out--] = (pixel[in--]*ialpha+pt5)>>>16;
} else
for (b=0; b<bands; b++)
oPix[out--] = pixel[in--];
} else {
in -= bands;
for (b=0; b<bands; b++)
oPix[out--] = 255;
}
}
dstR.setPixels(x0+dx, y+dy, w, 1, oPix);
}
} else {
// Src has unpremult alpha, dest does not have alpha,
// just copy the color channels over.
Rectangle dstRect = new Rectangle(destP.x, destP.y,
srcRect.width, srcRect.height);
for (int b=0; b<bands; b++)
copyBand(srcR, srcRect, b,
dstR, dstRect, b);
}
}
public static void copyBand(Raster src, int srcBand,
WritableRaster dst, int dstBand) {
Rectangle sR = src.getBounds();
Rectangle dR = dst.getBounds();
Rectangle cpR = sR.intersection(dR);
copyBand(src, cpR, srcBand, dst, cpR, dstBand);
}
public static void copyBand(Raster src, Rectangle sR, int sBand,
WritableRaster dst, Rectangle dR, int dBand) {
int dy = dR.y -sR.y;
int dx = dR.x -sR.x;
sR = sR.intersection(src.getBounds());
dR = dR.intersection(dst.getBounds());
int width, height;
if (dR.width < sR.width) width = dR.width;
else width = sR.width;
if (dR.height < sR.height) height = dR.height;
else height = sR.height;
int x = sR.x+dx;
int [] samples = null;
for (int y=sR.y; y< sR.y+height; y++) {
samples = src.getSamples(sR.x, y, width, 1, sBand, samples);
dst.setSamples(x, y+dy, width, 1, dBand, samples);
}
}
public static boolean is_INT_PACK_Data(SampleModel sm,
boolean requireAlpha) {
// Check ColorModel is of type DirectColorModel
if(!(sm instanceof SinglePixelPackedSampleModel)) return false;
// Check transfer type
if(sm.getDataType() != DataBuffer.TYPE_INT) return false;
SinglePixelPackedSampleModel sppsm;
sppsm = (SinglePixelPackedSampleModel)sm;
int [] masks = sppsm.getBitMasks();
if (masks.length == 3) {
if (requireAlpha) return false;
} else if (masks.length != 4)
return false;
if(masks[0] != 0x00ff0000) return false;
if(masks[1] != 0x0000ff00) return false;
if(masks[2] != 0x000000ff) return false;
if ((masks.length == 4) &&
(masks[3] != 0xff000000)) return false;
return true;
}
public static boolean is_BYTE_COMP_Data(SampleModel sm) {
// Check ColorModel is of type DirectColorModel
if(!(sm instanceof ComponentSampleModel)) return false;
// Check transfer type
if(sm.getDataType() != DataBuffer.TYPE_BYTE) return false;
return true;
}
protected static void divide_INT_PACK_Data(WritableRaster wr) {
// System.out.println("Divide Int");
SinglePixelPackedSampleModel sppsm;
sppsm = (SinglePixelPackedSampleModel)wr.getSampleModel();
final int width = wr.getWidth();
final int scanStride = sppsm.getScanlineStride();
DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
final int base
= (db.getOffset() +
sppsm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
wr.getMinY()-wr.getSampleModelTranslateY()));
// Access the pixel data array
final int[] pixels = db.getBankData()[0];
for (int y=0; y<wr.getHeight(); y++) {
int sp = base + y*scanStride;
final int end = sp + width;
while (sp < end) {
int pixel = pixels[sp];
int a = pixel>>>24;
if (a<=0) {
pixels[sp] = 0x00FFFFFF;
} else if (a<255) {
int aFP = (0x00FF0000/a);
pixels[sp] =
((a << 24) |
(((((pixel&0xFF0000)>>16)*aFP)&0xFF0000) ) |
(((((pixel&0x00FF00)>>8) *aFP)&0xFF0000)>>8 ) |
(((((pixel&0x0000FF)) *aFP)&0xFF0000)>>16));
}
sp++;
}
}
}
protected static void mult_INT_PACK_Data(WritableRaster wr) {
// System.out.println("Multiply Int: " + wr);
SinglePixelPackedSampleModel sppsm;
sppsm = (SinglePixelPackedSampleModel)wr.getSampleModel();
final int width = wr.getWidth();
final int scanStride = sppsm.getScanlineStride();
DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
final int base
= (db.getOffset() +
sppsm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
wr.getMinY()-wr.getSampleModelTranslateY()));
// Access the pixel data array
final int[] pixels = db.getBankData()[0];
for (int y=0; y<wr.getHeight(); y++) {
int sp = base + y*scanStride;
final int end = sp + width;
while (sp < end) {
int pixel = pixels[sp];
int a = pixel>>>24;
if ((a>=0) && (a<255)) { // this does NOT include a == 255 (0xff) !
pixels[sp] = ((a << 24) |
((((pixel&0xFF0000)*a)>>8)&0xFF0000) |
((((pixel&0x00FF00)*a)>>8)&0x00FF00) |
((((pixel&0x0000FF)*a)>>8)&0x0000FF));
}
sp++;
}
}
}
protected static void divide_BYTE_COMP_Data(WritableRaster wr) {
// System.out.println("Multiply Int: " + wr);
ComponentSampleModel csm;
csm = (ComponentSampleModel)wr.getSampleModel();
final int width = wr.getWidth();
final int scanStride = csm.getScanlineStride();
final int pixStride = csm.getPixelStride();
final int [] bandOff = csm.getBandOffsets();
DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
final int base
= (db.getOffset() +
csm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
wr.getMinY()-wr.getSampleModelTranslateY()));
int aOff = bandOff[bandOff.length-1];
int bands = bandOff.length-1;
// Access the pixel data array
final byte[] pixels = db.getBankData()[0];
for (int y=0; y<wr.getHeight(); y++) {
int sp = base + y*scanStride;
final int end = sp + width*pixStride;
while (sp < end) {
int a = pixels[sp+aOff]&0xFF;
if (a==0) {
for (int b = 0; b < bands; b++)
pixels[sp+bandOff[b]] = (byte)0xFF;
} else if (a<255) { // this does NOT include a == 255 (0xff) !
int aFP = (0x00FF0000/a);
for (int b = 0; b < bands; b++) {
int i = sp+bandOff[b];
pixels[i] = (byte)(((pixels[i]&0xFF)*aFP)>>>16);
}
}
sp+=pixStride;
}
}
}
protected static void mult_BYTE_COMP_Data(WritableRaster wr) {
// System.out.println("Multiply Int: " + wr);
ComponentSampleModel csm;
csm = (ComponentSampleModel)wr.getSampleModel();
final int width = wr.getWidth();
final int scanStride = csm.getScanlineStride();
final int pixStride = csm.getPixelStride();
final int [] bandOff = csm.getBandOffsets();
DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
final int base
= (db.getOffset() +
csm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
wr.getMinY()-wr.getSampleModelTranslateY()));
int aOff = bandOff[bandOff.length-1];
int bands = bandOff.length-1;
// Access the pixel data array
final byte[] pixels = db.getBankData()[0];
for (int y=0; y<wr.getHeight(); y++) {
int sp = base + y*scanStride;
final int end = sp + width*pixStride;
while (sp < end) {
int a = pixels[sp+aOff]&0xFF;
if (a!=0xFF)
for (int b = 0; b < bands; b++) {
int i = sp+bandOff[b];
pixels[i] = (byte)(((pixels[i]&0xFF)*a)>>8);
}
sp+=pixStride;
}
}
}
/*
This is skanky debugging code that might be useful in the future:
if (count == 33) {
String label = "sub [" + x + ", " + y + "]: ";
org.ImageDisplay.showImage
(label, subBI);
org.ImageDisplay.printImage
(label, subBI,
new Rectangle(75-iR.x, 90-iR.y, 32, 32));
}
// if ((count++ % 50) == 10)
// org.ImageDisplay.showImage("foo: ", subBI);
Graphics2D realG2D = g2d;
while (realG2D instanceof sun.java2d.ProxyGraphics2D) {
realG2D = ((sun.java2d.ProxyGraphics2D)realG2D).getDelegate();
}
if (realG2D instanceof sun.awt.image.BufferedImageGraphics2D) {
count++;
if (count == 34) {
RenderedImage ri;
ri = ((sun.awt.image.BufferedImageGraphics2D)realG2D).bufImg;
// g2d.setComposite(SVGComposite.OVER);
// org.ImageDisplay.showImage("Bar: " + count, cr);
org.ImageDisplay.printImage("Bar: " + count, cr,
new Rectangle(75, 90, 32, 32));
org.ImageDisplay.showImage ("Foo: " + count, ri);
org.ImageDisplay.printImage("Foo: " + count, ri,
new Rectangle(75, 90, 32, 32));
System.out.println("BI: " + ri);
System.out.println("BISM: " + ri.getSampleModel());
System.out.println("BICM: " + ri.getColorModel());
System.out.println("BICM class: " + ri.getColorModel().getClass());
System.out.println("BICS: " + ri.getColorModel().getColorSpace());
System.out.println
("sRGB CS: " +
ColorSpace.getInstance(ColorSpace.CS_sRGB));
System.out.println("G2D info");
System.out.println("\tComposite: " + g2d.getComposite());
System.out.println("\tTransform" + g2d.getTransform());
java.awt.RenderingHints rh = g2d.getRenderingHints();
java.util.Set keys = rh.keySet();
java.util.Iterator iter = keys.iterator();
while (iter.hasNext()) {
Object o = iter.next();
System.out.println("\t" + o.toString() + " -> " +
rh.get(o).toString());
}
ri = cr;
System.out.println("RI: " + ri);
System.out.println("RISM: " + ri.getSampleModel());
System.out.println("RICM: " + ri.getColorModel());
System.out.println("RICM class: " + ri.getColorModel().getClass());
System.out.println("RICS: " + ri.getColorModel().getColorSpace());
}
}
*/
/**
* Extracts an alpha raster from a RenderedImage. The method tries to avoid copying data
* unnecessarily by checking if the RenderedImage is a BufferedImage which offers suitable
* direct methods.
* @param image the image
* @return the alpha raster
*/
public static Raster getAlphaRaster(RenderedImage image) {
ColorModel cm = image.getColorModel();
if (!cm.hasAlpha() || cm.getTransparency() != ColorModel.TRANSLUCENT) {
throw new IllegalStateException("Image doesn"t have an alpha channel");
}
Raster alpha;
if (image instanceof BufferedImage) {
//Optimization possible with BufferedImage (No copying)
alpha = ((BufferedImage)image).getAlphaRaster();
} else {
WritableRaster wraster = GraphicsUtil.makeRasterWritable(image.getData());
alpha = image.getColorModel().getAlphaRaster(wraster);
}
return alpha;
}
}
Paint an Icon
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.net.URL;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class IconPaint extends JApplet {
static String iconFile = "largejexpLogo.gif";
public void init() {
Image starry = getImage(getURL(iconFile));
IconPanel starPanel = new IconPanel(starry);
getContentPane().add(starPanel, BorderLayout.CENTER);
}
protected URL getURL(String filename) {
URL codeBase = this.getCodeBase();
URL url = null;
try {
url = new URL(codeBase, filename);
} catch (java.net.MalformedURLException e) {
System.out.println("Couldn"t create image: "
+ "badly specified URL");
return null;
}
return url;
}
public static void main(String[] args) {
Image starImage = Toolkit.getDefaultToolkit().getImage(
IconPaint.iconFile);
IconPanel starPanel = new IconPanel(starImage);
JFrame f = new JFrame("Icon");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.getContentPane().add(starPanel, BorderLayout.CENTER);
f.setSize(new Dimension(550, 200));
f.setVisible(true);
}
}
class IconPanel extends JPanel {
Image img;
public IconPanel(Image img) {
this.img = img;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.white);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2.drawImage(img, 10, 10, 100, 100, this);
}
}
Pixels from a buffered image can be modified
import java.awt.image.BufferedImage;
public class Main {
public static void main(String[] argv) throws Exception {
int width = 100;
int height = 100;
BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
}
Rendered Image
//-----------------------------------------------------------------------//
// //
// T e s t I m a g e 2 //
// //
// Copyright (C) Herve Bitteur 2000-2007. All rights reserved. //
// This software is released under the terms of the GNU General Public //
// License. Please contact the author at herve.bitteur@laposte.net //
// to report bugs & suggestions. //
//-----------------------------------------------------------------------//
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.WritableRaster;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestImage2
extends JPanel
{
//RenderedImage image;
RenderedImage image;
// Affine tranform
final float ratio = 1f;
AffineTransform scaleXform = AffineTransform.getScaleInstance(ratio, ratio);
private static char WHITE = "-"; // And transparent
private static char[] charTable = new char[]
{
"#", // 0 Black
"$", // 1
"*", // 2
"0", // 3
"o", // 4
"+", // 5
".", // 6
WHITE // 7
};
//------------//
// TestImage2 //
//------------//
public TestImage2()
{
JFrame frame = new JFrame(getClass().getName());
Container pane = frame.getContentPane();
pane.setLayout(new BorderLayout());
pane.add(this);
image = toRenderedImage(new String[] {
"-##########################################################################-",
"----------------------------------------------------------------------------",
"-##########################################################################-",
"----------------------------------------------------------------------------",
"-##########################################################################-",
"----------------------------------------------------------------------------",
"-##########################################################################-",
"----------------------------------------------------------------------------",
"-##########################################################################-",
"----------------------------------------------------------------------------",
"-##########################################################################-",
"----------------------------------------------------------------------------",
"----------------------------------------------------------------------------",
"----------------------------------------------------------------------------",
"----####---------------####---------------####---------------####-----------",
"--------##-----------------##-----------------##-----------------##---------",
"----------####---------------####---------------####---------------####-----",
"--------------#------------------#------------------#------------------#----",
"--------------#------------------#------------------#------------------#----",
"----------------------------------------------------------------------------",
"---#############------#############------#############------#############---",
"---#############------#############------#############------#############---",
"---#############------#############------#############------#############---",
"---#############------#############------#############------#############---",
"---#############------#############------#############------#############---",
"---#############------#############------#############------#############---",
"---#############------#############------#############------#############---",
"---#############------#############------#############------#############---",
"---#############------#############------#############------#############---",
"---#############------#############------#############------#############---",
"---#############------#############------#############------#############---",
"----------------------------------------------------------------------------",
"----------------------------------------------------------------------------",
"----####---------------####---------------####---------------####-----------",
"--------##-----------------##-----------------##-----------------##---------",
"----------####---------------####---------------####---------------####-----",
"--------------#------------------#------------------#------------------#----",
"--------------#------------------#------------------#------------------#----",
"----------------------------------------------------------------------------",
"---#############------#############------#############------#############---",
"---#############------#############------#############------#############---",
"----------------------------------------------------------------------------",
"----------------------------------------------------------------------------"
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(100, 100);
frame.pack();
frame.setSize(200, 200);
frame.setVisible(true);
}
//------//
// main //
//------//
public static void main(String... args)
{
new TestImage2();
}
//----------------//
// paintComponent //
//----------------//
public void paintComponent(Graphics g)
{
// For background
super.paintComponent(g);
// Meant for visual check
if (image != null) {
Graphics2D g2 = (Graphics2D) g;
g2.drawRenderedImage (image, scaleXform);
//g2.drawImage (image, 1, 1, this);
}
}
//-----------------//
// toRenderedImage //
//-----------------//
public static RenderedImage toRenderedImage (String[] rows)
{
// Create the DataBuffer to hold the pixel samples
final int width = rows[0].length();
final int height = rows.length;
final int size = width * height;
byte[] pixels = new byte[size];
int index = 0;
for (String row : rows) {
for (int x = 0; x < width; x++) {
pixels[index++] = (byte) decodeGray(row.charAt(x));
}
}
DataBuffer dataBuffer = new DataBufferByte(pixels, size);
// Create Raster
WritableRaster writableRaster = Raster.createBandedRaster
(dataBuffer, width, height,
width, // scanlineStride
new int[] {0}, // bankIndices,
new int[] {0}, // bandOffsets,
null); // location
// Create the image
BufferedImage bufferedImage = new BufferedImage
(width, height, BufferedImage.TYPE_BYTE_GRAY);
bufferedImage.setData(writableRaster);
return bufferedImage;
}
//------------//
// decodeGray //
//------------//
private static int decodeGray(char c)
{
// Check the char
if (c == WHITE) {
return 255;
} else {
for (int i = charTable.length -1; i >= 0; i--) {
if (charTable[i] == c) {
int level = 2 + i * 36; // Range 2 .. 254 (not too bad)
return level;
}
}
}
// Unknown -> white
return 255;
}
}
Returns an image resource.
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.RGBImageFilter;
import java.io.IOException;
import java.net.URL;
public class ImageUtil {
/**
* Returns an image resource.
*
* @param filename the filename of the image to load
* @return the loaded image
*/
public static Image getImage(String filename) {
URL url = ImageUtil.class.getResource(filename);
if (url == null) {
return null;
}
try {
final BufferedImage result = ImageIO.read(url);
if (result == null) {
final String message = "Could not load image: " + filename;
throw new Error();
}
return result;
} catch (IOException e) {
return null;
}
}
}
Rotate Image 45 Degrees
/*
Java Media APIs: Cross-Platform Imaging, Media and Visualization
Alejandro Terrazas
Sams, Published November 2002,
ISBN 0672320940
*/
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import javax.swing.JFrame;
/**
* RotateImage45Degrees.java - 1. scales an image"s dimensions by a factor of
* two 2. rotates it 45 degrees around the image center 3. displays the
* processed image
*/
public class RotateImage45Degrees extends JFrame {
private Image inputImage;
private BufferedImage sourceBI;
private BufferedImage destinationBI = null;
private Insets frameInsets;
private boolean sizeSet = false;
public RotateImage45Degrees(String imageFile) {
addNotify();
frameInsets = getInsets();
inputImage = Toolkit.getDefaultToolkit().getImage(imageFile);
MediaTracker mt = new MediaTracker(this);
mt.addImage(inputImage, 0);
try {
mt.waitForID(0);
} catch (InterruptedException ie) {
}
sourceBI = new BufferedImage(inputImage.getWidth(null), inputImage
.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) sourceBI.getGraphics();
g.drawImage(inputImage, 0, 0, null);
AffineTransform at = new AffineTransform();
// scale image
at.scale(2.0, 2.0);
// rotate 45 degrees around image center
at.rotate(45.0 * Math.PI / 180.0, sourceBI.getWidth() / 2.0, sourceBI
.getHeight() / 2.0);
/*
* translate to make sure the rotation doesn"t cut off any image data
*/
AffineTransform translationTransform;
translationTransform = findTranslation(at, sourceBI);
at.preConcatenate(translationTransform);
// instantiate and apply affine transformation filter
BufferedImageOp bio;
bio = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
destinationBI = bio.filter(sourceBI, null);
int frameInsetsHorizontal = frameInsets.right + frameInsets.left;
int frameInsetsVertical = frameInsets.top + frameInsets.bottom;
setSize(destinationBI.getWidth() + frameInsetsHorizontal, destinationBI
.getHeight()
+ frameInsetsVertical);
show();
}
/*
* find proper translations to keep rotated image correctly displayed
*/
private AffineTransform findTranslation(AffineTransform at, BufferedImage bi) {
Point2D p2din, p2dout;
p2din = new Point2D.Double(0.0, 0.0);
p2dout = at.transform(p2din, null);
double ytrans = p2dout.getY();
p2din = new Point2D.Double(0, bi.getHeight());
p2dout = at.transform(p2din, null);
double xtrans = p2dout.getX();
AffineTransform tat = new AffineTransform();
tat.translate(-xtrans, -ytrans);
return tat;
}
public void paint(Graphics g) {
if (destinationBI != null)
g.drawImage(destinationBI, frameInsets.left, frameInsets.top, this);
}
public static void main(String[] args) {
new RotateImage45Degrees("fruits.png");
}
}
Sending Image Objects through the Clipboard
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.TransferHandler;
public class ClipImage {
public static void main(String args[]) {
JFrame frame = new JFrame("Clip Image");
Container contentPane = frame.getContentPane();
final Clipboard clipboard = frame.getToolkit().getSystemClipboard();
Icon icon = new ImageIcon("jaeger.jpg");
final JLabel label = new JLabel(icon);
label.setTransferHandler(new ImageSelection());
JScrollPane pane = new JScrollPane(label);
contentPane.add(pane, BorderLayout.CENTER);
JButton copy = new JButton("Copy");
copy.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
TransferHandler handler = label.getTransferHandler();
handler.exportToClipboard(label, clipboard,
TransferHandler.COPY);
}
});
JButton clear = new JButton("Clear");
clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
label.setIcon(null);
}
});
JButton paste = new JButton("Paste");
paste.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
Transferable clipData = clipboard.getContents(clipboard);
if (clipData != null) {
if (clipData.isDataFlavorSupported(DataFlavor.imageFlavor)) {
TransferHandler handler = label.getTransferHandler();
handler.importData(label, clipData);
}
}
}
});
JPanel p = new JPanel();
p.add(copy);
p.add(clear);
p.add(paste);
contentPane.add(p, BorderLayout.SOUTH);
frame.setSize(300, 300);
frame.show();
}
}
class ImageSelection extends TransferHandler implements Transferable {
private static final DataFlavor flavors[] = { DataFlavor.imageFlavor };
private JLabel source;
private Image image;
public int getSourceActions(JComponent c) {
return TransferHandler.COPY;
}
public boolean canImport(JComponent comp, DataFlavor flavor[]) {
if (!(comp instanceof JLabel)) {
return false;
}
for (int i = 0, n = flavor.length; i < n; i++) {
for (int j = 0, m = flavors.length; j < m; j++) {
if (flavor[i].equals(flavors[j])) {
return true;
}
}
}
return false;
}
public Transferable createTransferable(JComponent comp) {
// Clear
source = null;
image = null;
if (comp instanceof JLabel) {
JLabel label = (JLabel) comp;
Icon icon = label.getIcon();
if (icon instanceof ImageIcon) {
image = ((ImageIcon) icon).getImage();
source = label;
return this;
}
}
return null;
}
public boolean importData(JComponent comp, Transferable t) {
if (comp instanceof JLabel) {
JLabel label = (JLabel) comp;
if (t.isDataFlavorSupported(flavors[0])) {
try {
image = (Image) t.getTransferData(flavors[0]);
ImageIcon icon = new ImageIcon(image);
label.setIcon(icon);
return true;
} catch (UnsupportedFlavorException ignored) {
} catch (IOException ignored) {
}
}
}
return false;
}
// Transferable
public Object getTransferData(DataFlavor flavor) {
if (isDataFlavorSupported(flavor)) {
return image;
}
return null;
}
public DataFlavor[] getTransferDataFlavors() {
return flavors;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(DataFlavor.imageFlavor);
}
}
Standalone Image Viewer - works with any AWT-supported format
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java
* language and environment is gratefully acknowledged.
*
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/
import java.awt.*;
import javax.swing.*;
import java.net.*;
/**
* Standalone Image Viewer - works with any AWT-supported format.
*/
public class ImageView extends JComponent {
/** The Image object */
protected Image im;
/** Size of the image */
protected int width, height;
/** The graphical component */
protected Container cp;
/** The name of the image file */
protected String fileName;
/** Construct an ImageView viewer, given a filename. */
public ImageView(String fileName) {
this.fileName = fileName;
cp = this;
}
public void loadImage() {
URL url = getClass().getResource(fileName);
im = Toolkit.getDefaultToolkit().getImage(url);
// ----- This part omitted from course notes for brevity -----
// Use a MediaTracker to show the "best"? way of waiting
// for an image to load, and how to check for errors.
MediaTracker mt = new MediaTracker(this);
mt.addImage(im, 0);
try {
mt.waitForID(0);
} catch(InterruptedException e) {
System.err.println("Unexpected interrupt in waitForID!");
return;
}
if (mt.isErrorID(0)) {
System.err.println("Couldn"t load image file " + fileName);
return;
}
// Now that we know the image has been loaded,
// it is safe to take its width and height.
// ----- End of part omitted from course notes for brevity -----
width = im.getWidth(this);
height = im.getHeight(this);
setSize(width, height);
}
public void paint(Graphics g) {
g.drawImage(im, 0, 0, this);
}
public static void main(String[] arg) {
if (arg.length == 0) {
System.err.println("Usage: ImageView file [...]");
} else {
for (int i=0; i<arg.length; i++) {
JFrame jf = new JFrame("ImageView: " + arg[i]);
ImageView iv = new ImageView(arg[i]);
jf.getContentPane().add(iv);
iv.loadImage();
jf.setSize(iv.getSize());
jf.setVisible(true);
}
}
}
}
This filter removes all but the red values in an image
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.RGBImageFilter;
import javax.swing.ImageIcon;
class GetRedFilter extends RGBImageFilter {
public GetRedFilter() {
canFilterIndexColorModel = true;
}
public int filterRGB(int x, int y, int rgb) {
if (x == -1) {
}
return rgb & 0xffff0000;
}
}
public class Main {
public static void main(String[] argv) throws Exception {
Image image = new ImageIcon("image.gif").getImage();
ImageFilter filter = new GetRedFilter();
FilteredImageSource filteredSrc = new FilteredImageSource(image.getSource(), filter);
image = Toolkit.getDefaultToolkit().createImage(filteredSrc);
}
}
Toolkit.getImage() which works the same in either Applet or Application
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java
* language and environment is gratefully acknowledged.
*
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/
/*
* For Applet, invoke as:
* <applet code="GetImage" width="100" height="100">
* </applet>
* For Application, just run it (has own main).
*/
import java.awt.Graphics;
import java.awt.Image;
import java.net.URL;
import javax.swing.JApplet;
import javax.swing.JFrame;
/**
* This program, which can be an Applet or an Application, shows a form of
* Toolkit.getImage() which works the same in either Applet or Application!
*/
public class GetImage extends JApplet {
Image image;
public void init() {
loadImage();
}
public void loadImage() {
// Applet-only version:
// Image = getImage(getCodeBase(), "Duke.gif");
// Portable version: getClass().getResource() works in either
// applet or application, 1.1 or 1.3, returns URL for file name.
URL url = getClass().getResource("Duke.gif");
image = getToolkit().getImage(url);
// Shorter portable version: same but avoids temporary variables
// image = getToolkit().getImage(getClass().getResource("Duke.gif"));
}
public void paint(Graphics g) {
g.drawImage(image, 20, 20, this);
}
public static void main(String[] args) {
JFrame f = new JFrame("GetImage");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GetImage myApplet = new GetImage();
f.getContentPane().add(myApplet);
myApplet.init();
f.setSize(100, 100);
f.setVisible(true);
myApplet.start();
}
}
TYPE_INT_RGB and TYPE_INT_ARGB are typically used
import java.awt.image.BufferedImage;
public class Main {
public static void main(String[] argv) throws Exception {
int width = 100;
int height = 100;
BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
}
Use PixelGrabber class to acquire pixel data from an Image object
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.PixelGrabber;
public class Main {
static boolean isGreyscaleImage(PixelGrabber pg) {
return pg.getPixels() instanceof byte[];
}
public static void main(String args[]) throws Exception {
Image image = Toolkit.getDefaultToolkit().getImage("inFile.png");
PixelGrabber grabber = new PixelGrabber(image, 0, 0, -1, -1, false);
if (grabber.grabPixels()) {
int width = grabber.getWidth();
int height = grabber.getHeight();
if (isGreyscaleImage(grabber)) {
byte[] data = (byte[]) grabber.getPixels();
} else {
int[] data = (int[]) grabber.getPixels();
}
}
}
}