001package cnslab.image;
002// imageIO.java
003// This class provides routines for image input and output.
004
005import java.util.*;
006import java.awt.*;
007import java.awt.image.*;
008import java.awt.MediaTracker.*;
009import java.io.*;
010
011
012public class imageIO {
013
014
015// ****************************** loadImage **********************************
016// The loadImage method asks the user for the name of a file that contains
017// an image.  It reads the contents of this file, returning the
018// data as a three dimensional array (row, column, colour).  Colour
019// is 0 for red, 1 for green, 2 for blue, 3 for offset.
020// The file name may be for a local file (such as "Camel.jpg") or it may
021// be a path (such as "/home/turing/alan.bmp").
022//
023// private static int[][][] loadImage()
024// Parameters:
025//    none
026//
027// Precondition:
028//    none
029//
030// Postcondition:
031//    Provided that the user gives a legal file name (the file exists and
032//    ends in .gif, .jpg, .jpeg or .bmp), a 3D array containing the image
033//    data is returned.
034
035    public static int[][][] loadImage(String openName) {
036        Image img = (Image)null;  // create a null Image
037
038        
039        try{
040            while (img == null) {
041                // Ask for the name of a file that contains an image.
042//                System.out.print("What image file do you want to open? (gif, jpeg or bmp)  ");
043        
044                // Check that the file name has a legal extension
045                if (openName.endsWith(".gif") || openName.endsWith(".jpg")
046                                          || openName.endsWith(".jpeg")) {
047                img = Toolkit.getDefaultToolkit().getImage(openName);
048                }
049                else if (openName.endsWith(".bmp")) {
050                    img = utils.loadbitmap("./", openName);
051                }
052                else {
053                  img=(Image)null;  // we can't read the file
054                }
055
056                if (img != null) {
057                     // Make sure the entire image is loaded before continuing 
058/*
059                     Button b = new Button();  // Create a button to use as a paraemter
060                                              // to the constructor for MediaTracker.
061                    MediaTracker tracker = new MediaTracker(b);
062                    tracker.addImage(img,0);
063                    tracker.waitForID(0);
064
065                */
066                    // Create "observer", an object that allows us to
067                      // use getWidth and getHeight.
068                    iObserver observer = new iObserver();
069                    int width = img.getWidth(observer);
070                    int height = img.getHeight(observer);
071        
072                    if(width==-1 || height==-1){
073                        // the image has not loaded.
074                        img = (Image)null;
075                    }
076                }  // if img != null
077
078                // If the image did not load, print an explanatory
079                // message to the user and ask him/her to try again.
080                /*
081                if (img == null) {
082                    System.out.println("Could not read an image from file "
083                        +openName);
084                    System.out.println("Make sure that you supply the name of an image file, \nand that you include the bmp, gif, jpg or jpeg extension.");
085                }  // if (img==null)
086                */
087            } // while img==null
088        } // end of "try"
089
090        // Catch InterruptedException for tracker.waitfor(), and catch
091        // IOException for the console operations.
092        catch(Exception e) {
093            System.out.println(e);
094            System.exit(1);
095        }
096         // Translate from Image img to a 3D array "imagePixels".
097        // Using this 3D array, imagePixels[r][c][w] gives the value
098        // of row r, column c, colour w.
099        int[][][] imagePixels = getImagePixels(img);
100        return imagePixels;
101    } // end of method loadImage  
102
103
104    public static int[][] loadBWImage(String openName) {
105        Image img = (Image)null;  // create a null Image
106        
107        try{
108            while (img == null) {
109                // Ask for the name of a file that contains an image.
110//                System.out.print("What image file do you want to open? (gif, jpeg or bmp)  ");
111        
112                // Check that the file name has a legal extension
113                if (openName.endsWith(".gif") || openName.endsWith(".jpg")
114                                          || openName.endsWith(".jpeg")) {
115                img = Toolkit.getDefaultToolkit().getImage(openName);
116                }
117                else if (openName.endsWith(".bmp")) {
118                    img = utils.loadbitmap("./", openName);
119                }
120                else {
121                  img=(Image)null;  // we can't read the file
122                }
123                if (img != null) {
124                     // Make sure the entire image is loaded before continuing 
125                     /*
126                     Button b = new Button();  // Create a button to use as a paraemter
127                                              // to the constructor for MediaTracker.
128                    MediaTracker tracker = new MediaTracker(b);
129                    tracker.addImage(img,0);
130                    tracker.waitForID(0);
131                    */
132
133                    // Create "observer", an object that allows us to
134                      // use getWidth and getHeight.
135                    iObserver observer = new iObserver();
136                    int width = img.getWidth(observer);
137                    int height = img.getHeight(observer);
138        
139                    if(width==-1 || height==-1){
140                        // the image has not loaded.
141                        img = (Image)null;
142                    }
143                }  // if img != null
144
145                // If the image did not load, print an explanatory
146                // message to the user and ask him/her to try again.
147   //             if (img == null) {
148//                    System.out.println("Could not read an image from file "
149  //                      +openName);
150 //                   System.out.println("Make sure that you supply the name of an image file, \nand that you include the bmp, gif, jpg or jpeg extension.");
151    //            }  // if (img==null)
152            } // while img==null
153        } // end of "try"
154
155        // Catch InterruptedException for tracker.waitfor(), and catch
156        // IOException for the console operations.
157        catch(Exception e) {
158            System.out.println(e);
159            System.exit(1);
160        }
161         // Translate from Image img to a 3D array "imagePixels".
162        // Using this 3D array, imagePixels[r][c][w] gives the value
163        // of row r, column c, colour w.
164        int[][] imagePixels = getBWImagePixels(img);
165        return imagePixels;
166    }
167
168
169
170
171// **************************** getImagePixels ****************************
172// The getImagePixels method converts an image object into a 3D array
173// representing pixels (rows, columns, pixel value (red, green, blue, offset))
174//
175// private static int[][][] getImagePixels(Image image)
176//
177// Parameters:
178//    img - the image which is to be converted
179//
180// Precondition:
181//    image img should be fully loaded
182//
183// Postcondition:
184//    a 3D array representing the pixels of image is returned
185
186    private static int[][][] getImagePixels(Image img) {
187
188        // Get the raw pixel data 
189        iObserver observer = new iObserver();
190        int width1 = img.getWidth(observer);
191        int height1 = img.getHeight(observer);
192        int[] rawPixels = utils.getPixels(img,width1,height1);
193
194        // Each pixel is represented by 32 bits.  Separate the tH32 bits into
195        // four 8-bit values (red, green, blue, offset).
196        int[][] rgbPixels = new int[rawPixels.length][4];
197        for(int j=0; j<rawPixels.length; j++) {
198            rgbPixels[j][0] = ((rawPixels[j]>>16)&0xff);
199            rgbPixels[j][1] = ((rawPixels[j]>>8)&0xff);
200            rgbPixels[j][2] = (rawPixels[j]&0xff);
201            rgbPixels[j][3] =((rawPixels[j]>>24)&0xff);
202        }  // for j
203
204        // Arrange the data by rows and columns
205        int[][][] imagePixels = new int[height1][width1][4];
206        int index=0;
207        for(int row=0; row<imagePixels.length; row++) {
208            for(int col=0; col<imagePixels[0].length; col++) {
209                for(int rgbo=0; rgbo<4; rgbo++) {
210                    imagePixels[row][col][rgbo]=rgbPixels[index][rgbo];
211                } // for rgbo
212                index++;
213            } // for col
214        }  // for row
215        return imagePixels;
216    } // end of method getImagePixels
217
218    private static int[][] getBWImagePixels(Image img) {
219
220        // Get the raw pixel data 
221        iObserver observer = new iObserver();
222        int width1 = img.getWidth(observer);
223        int height1 = img.getHeight(observer);
224        int[] rawPixels = utils.getPixels(img,width1,height1);
225
226        // Each pixel is represented by 32 bits.  Separate the tH32 bits into
227        // four 8-bit values (red, green, blue, offset).
228        int[][] rgbPixels = new int[rawPixels.length][4];
229        for(int j=0; j<rawPixels.length; j++) {
230            rgbPixels[j][0] = ((rawPixels[j]>>16)&0xff);
231            rgbPixels[j][1] = ((rawPixels[j]>>8)&0xff);
232            rgbPixels[j][2] = (rawPixels[j]&0xff);
233            rgbPixels[j][3] =((rawPixels[j]>>24)&0xff);
234        }  // for j
235
236        // Arrange the data by rows and columns
237//      System.out.println("h:"+height1+" w:"+width1);
238        int[][] imagePixels = new int[height1][width1];
239        int index=0;
240        for(int row=0; row<imagePixels.length; row++) {
241            for(int col=0; col<imagePixels[0].length; col++) {
242                    double tmp=0.0;
243                for(int rgbo=0; rgbo<3; rgbo++) {
244                        tmp = tmp+(double)rgbPixels[index][rgbo];
245                } // for rgbo
246                imagePixels[row][col]= (int)(tmp/3.0); //average rgb 
247                index++;
248            } // for col
249        }  // for row
250        return imagePixels;
251    }
252
253
254
255// ******************************* saveImage *******************************
256// The saveImage method saves imagePiexls as a windows bitmap (.bmp).
257// The user is asked to provide the file name..
258//
259// private static void saveImage(int[][][] imagePixels)
260//
261// Parameters:
262//    imagePixels - a 3D array of pixel data
263//
264// Precondition:
265//    imagePixels != null
266//
267// Postcondition:
268//    imagePixels has been converted to a windows bitmap, and saved with
269//    the filename provided by the user.  (.bmp is appended to the file
270//     name in case the user does not type this extension)
271
272    public static void saveImage(int[][][] imagePixels, String saveName){
273        int height = imagePixels.length;
274        int width = imagePixels[0].length;
275        int[][] flat = new int[width*height][4];
276
277         // If saveName does not already end in .bmp, then add .bmp to saveName.
278        saveName=bmpTack(saveName);
279
280        // Flatten the image into a 2D array.
281        int index=0;
282        for(int row=0; row<height; row++) {
283            for(int col=0; col<width; col++) {
284                for(int rgbo=0; rgbo<4; rgbo++) {
285                    flat[index][rgbo]=imagePixels[row][col][rgbo];
286                }
287                index++;
288            }  // for col
289        }  // for row
290
291        // Combine the 8-bit red, green, blue, offset values into 32-bit words.
292        int[] outPixels = new int[flat.length];
293        for(int j=0; j<flat.length; j++) {
294            outPixels[j] = ((flat[j][0]&0xff)<<16) | ((flat[j][1]&0xff)<<8)
295                            | (flat[j][2]&0xff) | ((flat[j][3]&0xff)<<24);
296        } // for j
297
298        // Write the data out to file with the name given by string saveName.
299        BMPFile bmpf = new BMPFile();
300        bmpf.saveBitmap("pics/"+saveName, outPixels, width, height);
301    }  // end of method saveImage
302
303
304
305
306
307// ******************************* bmpTack ************************************
308// The bmpTack method checks whether the name parameter ends in ".bmp".
309// If it doesn't then ".bmp" is appended to the name.
310//
311// private static String bmpTack(String name)
312// Parameters:
313//    name - a string
314//
315// Precondition:
316//    name != null
317//
318// Postcondition:
319//    If name ended in .bmp before being passed into bmpTack, name is returned.
320//    If name did not end in .bmp before being passed into bmpTack, name+.bmp 
321//    is returned
322    private static String bmpTack(String name) {
323        if (name.endsWith(".bmp"))
324            return name;
325        else
326            return name+".bmp";
327    }  // end of method bmpTack
328                
329} // end of class imageIOm
330
331
332
333
334
335
336
337
338
339
340