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" ); * displayPixels( myPixels ); // Bring up a window with the image. * myPixels[13][23] = 255; // Set location (13,23) to white * displayPixels( myPixels ); // Look for the modified pixel. *

* *

* Note that once you have displayed an image, modifying the array won't * retroactively change that image; you'll have to call displayPixels 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 Colors), call displayPixels( 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 displayPixels(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