import java.awt.image.BufferedImage;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.JScrollPane;
/** This utility class contains static methods to translate between images and 2-D arrays.
*
*
* To convert a image's filename or URL to an array of int:
* int[][] myPixels = imageToPixelsBW( "http://www.radford.edu/~itec120/2007fall-ibarland/Lectures/lect01-ufo/muse.jpeg" );
*
*
*
* You can then modify that array as you please, to do image processing.
* Then, to draw a 2-D array of int as a black-and-white picture:
* displayAsImage( myPixels );
*
*
*
* Note that once you have displayed an image, modifying the array won't
* retroactively change that image; you'll have to call displayAsImage
again
* after making any modifications to see a new image.
*
*
*
* Optional/Challenge:
* If you want to deal with color images, you can use imageToPixelsColor
,
* which will return an array of java.awt.Color
objects. See the Java API
* for details, but the most useful color methods are getRed()
, setRed(int)
,
* and similarly for green and blue. To display a color image (if you have
* a 2-D array of Color
s), call displayAsImage( Color[][] )
.
*
*/
public class Pict {
private static int displayCount = 0;
private static final int MAX_WINDOW_WIDTH = 500;
private static final int MAX_WINDOW_HEIGHT = 500;
/** Given an array of grayscale values in [0,256),
* draw it as a black-and-white image.
* (Of course, subsequent changes to the array won't
* retroactively change this image.)
* @param pixels A 2-D array of grayscale values in [0,256).
*/
public static void displayPixels( int[][] pixels ) {
// To show an image:
// the image is inside of a Icon which is inside of a label inside of a frame
// (sigh, why must it be so roundabout?)
++displayCount;
javax.swing.JFrame f = new javax.swing.JFrame( "image #" + displayCount );
//f.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
// Bug: rather than use the image's width and height,
// we should also account for the frame's title bar etc.
//
f.setSize( Math.min(pixels.length,MAX_WINDOW_WIDTH),
Math.min(pixels[0].length,MAX_WINDOW_HEIGHT) );
JLabel l = new JLabel();
l.setIcon(new ImageIcon(pixelsToImage(pixels)));
f.add( new JScrollPane(l) );
f.setVisible(true);
}
/** Given an array of Colors, draw it as a Color image.
* (Of course, subsequent changes to the array won't
* retroactively change this image.)
* @param pixels A 2-D array of java.awt.Colors.
*/
public static void displayPixels( Color[][] pixels ) {
// Ugh -- this is EXACTLY the same code as displayAsImage(int[][]).
// To show an image:
// the image is in a Icon in a label in a frame
// (sigh, why must it be so roundabout?)
++displayCount;
javax.swing.JFrame f = new javax.swing.JFrame( "image #" + displayCount );
//f.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
// Bug: rather than use the image's width and height,
// we should also account for the frame's title bar etc.
//
f.setSize( Math.min(pixels.length,MAX_WINDOW_WIDTH),
Math.min(pixels[0].length,MAX_WINDOW_HEIGHT) );
JLabel l = new JLabel();
l.setIcon(new ImageIcon(pixelsToImage(pixels)));
f.add( new JScrollPane(l) );
f.setVisible(true);
}
/** Return a java.awt.Image.BufferedImage from a given array of grayscale values,
* suitable for interacting with other Java awt classes.
* @param pixels A 2-D array of grayscale values in [0,256).
* @return the image corresponding to the array of pixels.
*/
private static BufferedImage pixelsToImage( int[][] pixels ) {
int width = pixels.length > 0 ? pixels[0].length : 0;
BufferedImage img = new BufferedImage( width, pixels.length, BufferedImage.TYPE_INT_ARGB );
for (int r=0; r 0 ? pixels[0].length : 0;
BufferedImage img = new BufferedImage( width, pixels.length, BufferedImage.TYPE_INT_ARGB );
for (int r=0; r