Working with Images in Java 1.1 Java provides some facilities to manipulate images. These are contained in the java.awt.Image class and in the java.awt.image package. These classes are VERY confusing. In this text, we try to present some of the main features in an easy to understand way. ****************************************************** ****************************************************** Opening an Image Java has some very neat methods to read an image from the disk from an url: //opening an image from a file, String filename Image my_image = Toolkit.getDefaultToolkit().getImage(filename); //opening an image from the Internet, URL url Image my_image = Toolkit.getDefaultToolkit().getImage(url); ****************************************************** ****************************************************** The java.awt.Image class This is object where Java stores an image. It is very easy to display this image on the screen: Graphics g = my_frame.getGraphics(); g.drawImage(my_image,x,y,my_frame); In the same way, the image can be printed (g would be a printer page, see Printing in Java). You can get a larger or smaller copy: Image scaled_image = my_image.getScaledInstance(new_width,new_height,scalling_algorithm) where scalling_algorithm is one of the algorithms defined in the java.awt.Image class. If you want to draw on your image, you can get a graphics object and do anything: Graphics g = my_image.getGraphics(); g.setFont(new Font("Dialog",Font.BOLD,20)); g.setColor(Color.red); g.drawString("This is a cool picture",100,100); When you want to know the image size the problems start. Basically, there are the obvious methods: int width = my_image.getWidth(image_observer); int height = my_image.getHeight(image_observer); image_observer can be set to null or to a Container (usually the one where the image is drawn). Java was designed to load the image while the program is running. Thus, you may call these methods before Java knows the image size. In this case, the image size will be set to -1. This is a major problem for most programs that need to know the image size. The way around this is to make your program wait until the image is loaded (see Waiting for Image to be Loaded). ****************************************************** ****************************************************** Waiting for Image to be Loaded Java was designed to load the image while the program is running. Thus, you may have problems calling any method that needs accesses the image data if the image has not been loaded. Therefore, after you open an image, create a scaled instance or create an image from an array and before you get its size, grab its pixels, call a filter on it, you should make your program wait for the image to be loaded. This code should work for most cases: // create a media tracker to track the loading of // my_image. my_component cannot be null, set it // to the component where you will draw the image // or to the main Frame in your application MediaTracker media_tracker = new MediaTracker(my_component); // add your image to the tracker with an arbitrary id int id = 0; media_tracker.addImage(my_image,id); // try to wait for image to be loaded // catch if loading was interrupted try { media_tracker.waitForID(id); } catch(InterruptedException e) { System.out.println("Image loading interrupted : " + e); } ****************************************************** ****************************************************** Obtaining an Array of Image Pixels For many real image processing tasks, it is necessary to obtain an array with the image pixels. The code bellow allow you to do this (ATTENTION: in this code we assume that the image has been fully loaded, see Waiting for Image to Load) : //get image dimension int w = ti.projected_image.getWidth(null); int h = ti.projected_image.getHeight(null); // the rectangle (x,y) to (x+w,y+h) will be grabbed int x=0, y=0; // offset into the array of the top left corner of the grabbed // rectagle int off = 0; // horizontal size of the array int scansize = w; // pixels[] MUST BE ALLOCATED int[] pixels = new int[h*w]; // allocate a larger array if offset is not zero // create a pixel grabber object // pixels are stored in the default RGB color model PixelGrabber pixel_grabber = new PixelGrabber(my_image, x, y, w, h, pixels, off, scansize); // grab pixels try{ pixel_grabber.grabPixels(); }catch(InterruptedException e) { System.out.println("Couldn't grab pixels " + e); } The pixels will be stored in the pixels[] array in the default RGB color model, use ColorModel.getRGBdefault() to get an instance of this color model. The image can be processed in any desired way, for example: // code to turn image into a pink image :-) int pink = Color.pink.getRGB(); for(int j=0;j= this.min_red)? red : 0; green = (gren >= this.min_green)? green : 0; blue = (blue >= this.min_blue)? blue : 0; alpha = alpha << 24; red = red << 16; green = green << 8; return alpha | red | green | blue; } }// end of class ThresholdImageFilter