KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > PixelArray


1 import java.awt.*;
2 import java.awt.image.*;
3 import java.net.URL JavaDoc;
4 import JSci.maths.*;
5 import JSci.maths.matrices.DoubleMatrix;
6 import JSci.maths.matrices.DoubleSparseMatrix;
7 import JSci.maths.vectors.DoubleSparseVector;
8 import JSci.maths.wavelet.*;
9 import JSci.util.ArrayCaster;
10
11 /**
12 * This is a simple implementation of the PixelGrabber class
13 * to allow for easier image processing.
14 * Basically, it reads a graphic file and allows you to get
15 * integer arrays from it for convenient processing.
16 * The name of the class comes from the fact that the image
17 * is stored as an internal int[][] array.
18 *
19 * This might seem inefficient since the JDK stores images
20 * as an int[] array and that we must go back and forth
21 * between the two formats.
22 * It is indeed slower, but as far as image processing is concerned,
23 * it is much simpler to work with an int[][] array.
24 * Moreover, if the processing is moderatly involved,
25 * it won't make much difference.
26 * @author Daniel Lemire
27 */

28 public final class PixelArray implements ImageObserver {
29     private int width=-1;
30     private int height=-1;
31   /********************************************
32   * The RGB model is assumed
33   *********************************************/

34     ColorModel cm=ColorModel.getRGBdefault();
35         private boolean loaded=false;
36         private int[][] array;
37
38         private PixelArray() {}
39
40   /****************************************************
41   * Constructor
42   * @param filename file containing the image
43   * @exception IllegalArgumentException if the file
44   * can't be open. Either the format is wrong or the
45   * file cannot be found.
46   *****************************************************/

47   public PixelArray(String JavaDoc filename) {
48     waitForImage(Toolkit.getDefaultToolkit().getImage(filename));
49   }
50   /****************************************************
51   * Constructor
52   * @param filename file containing the image
53   * @exception IllegalArgumentException if the file
54   * can't be open. Either the format is wrong or the
55   * file cannot be found.
56   *****************************************************/

57   public PixelArray(URL JavaDoc url) {
58     waitForImage(Toolkit.getDefaultToolkit().getImage(url));
59   }
60
61   public PixelArray (int[][] I) {
62     width=I[0].length;
63     height=I.length;
64     array=ArrayMath.copy(I);
65   }
66   public PixelArray (double[][] D) {
67     width=D[0].length;
68     height=D.length;
69     array=ArrayMath.copy(ArrayCaster.toInt(D));
70   }
71
72   public Object JavaDoc clone() {
73     PixelArray pa=new PixelArray();
74     pa.loaded=true;
75     pa.array=new int[this.height][this.width];
76     for(int k=0;k<width;k++) {
77       for(int l=0;l<height;l++) {
78         pa.array[l][k]=this.array[l][k];
79       }
80     }
81     pa.cm=this.cm;
82     pa.height=this.height;
83     pa.width=this.width;
84     return(pa);
85   }
86
87
88         public int getWidth() {
89                 return(width);
90         }
91         public int getHeight() {
92                 return(height);
93         }
94
95   private void computeArray (int[] p) {
96     array=new int[height][width];
97     for(int k=0;k<width;k++) {
98       for(int l=0;l<height;l++) {
99         array[l][k]=p[k+l*width];
100       }
101     }
102   }
103
104
105   public void setRedArray(int[][] I) {
106     int g,b,a;
107     width=I[0].length;
108     height=I.length;
109     array=new int[height][width];
110     for(int k=0;k<width;k++) {
111       for(int l=0;l<height;l++) {
112         g=getGreen(l,k);
113         b=getBlue(l,k);
114         a=getAlpha(l,k);
115         array[l][k]=RGBtoInt(I[l][k],g,b,a);
116       }
117     }
118   }
119   public void setGreenArray(int[][] I) {
120     int r,b,a;
121     width=I[0].length;
122     height=I.length;
123     array=new int[height][width];
124     for(int k=0;k<width;k++) {
125       for(int l=0;l<height;l++) {
126         r=getRed(l,k);
127         b=getBlue(l,k);
128         a=getAlpha(l,k);
129         array[l][k]=RGBtoInt(r,I[l][k],b,a);
130       }
131     }
132   }
133   public void setBlueArray(int[][] I) {
134     int r,g,a;
135     width=I[0].length;
136     height=I.length;
137     array=new int[height][width];
138     for(int k=0;k<width;k++) {
139       for(int l=0;l<height;l++) {
140         r=getGreen(l,k);
141         g=getBlue(l,k);
142         a=getAlpha(l,k);
143         array[l][k]=RGBtoInt(r,g,I[l][k],a);
144       }
145     }
146   }
147   public void setAlphaArray(int[][] I) {
148     int r,g,a;
149     width=I[0].length;
150     height=I.length;
151     array=new int[height][width];
152     for(int k=0;k<width;k++) {
153       for(int l=0;l<height;l++) {
154         r=getGreen(l,k);
155         g=getBlue(l,k);
156         a=getAlpha(l,k);
157         array[l][k]=RGBtoInt(r,g,I[l][k],a);
158       }
159     }
160   }
161
162   private void setUniformGrey(int[][] I) {
163     width=I[0].length;
164     height=I.length;
165     array=new int[height][width];
166     for(int k=0;k<width;k++) {
167       for(int l=0;l<height;l++) {
168         array[l][k]=RGBtoInt(I[l][k],I[l][k],I[l][k],255);
169       }
170     }
171   }
172
173   /*************************************
174   * Part of the interface ImageObserver
175   **************************************/

176   public boolean imageUpdate(Image img1, int parm2, int parm3, int parm4, int parm5, int parm6) {
177     if((parm3<0)||(parm4<0)) {
178        throw new IllegalArgumentException JavaDoc("Could not load image.");
179     }
180     width=img1.getWidth(this);
181     height=img1.getHeight(this);
182     loaded=true;
183     return(false);
184   }
185   public synchronized void waitForImage(Image img) {
186       while (loaded==false) {
187       try {
188         width=img.getWidth(this);
189         wait(100);
190       } catch (InterruptedException JavaDoc e) {}
191       }
192     int[] p=new int[width*height];
193     PixelGrabber pg=new PixelGrabber(img,0,0,width,height,p,0,width);
194     try {
195         pg.grabPixels();
196     } catch (InterruptedException JavaDoc e) {
197         System.err.println("interrupted waiting for pixels!");
198         return;
199     }
200     if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
201         System.err.println("image fetch aborted or errored");
202         return;
203     }
204     computeArray(p);
205
206   }
207
208
209   public static int RGBtoInt(int r, int g, int b, int a) {
210     return ((a << 24)|(r << 16)|(g << 8)| b);
211   }
212
213   public void invert() {
214    int r,g,b,a;
215     for (int y = 0; y < getWidth(); y++)
216         for (int x = 0 ; x < getHeight(); x++) {
217               r = getRed (x,y);
218         g = getGreen (x,y);
219         b = getBlue (x,y);
220               a = getAlpha(x,y);
221               setPixel(x,y,255-r,255-g,255-b,a);
222       }
223   }
224
225   public void makeGrayFromRed() {
226    int r,a;
227     for (int y = 0; y < getWidth(); y++)
228         for (int x = 0 ; x < getHeight(); x++) {
229               r = getRed (x,y);
230               a = getAlpha(x,y);
231               setPixel(x,y,r,r,r,a);
232       }
233   }
234   public void makeGrayFromGreen() {
235    int g,a;
236     for (int y = 0; y < getWidth(); y++)
237         for (int x = 0 ; x < getHeight(); x++) {
238               g = getGreen (x,y);
239               a = getAlpha(x,y);
240               setPixel(x,y,g,g,g,a);
241       }
242   }
243   public void makeGrayFromBlue() {
244    int b,a;
245     for (int y = 0; y < getWidth(); y++)
246         for (int x = 0 ; x < getHeight(); x++) {
247               b = getBlue (x,y);
248               a = getAlpha(x,y);
249               setPixel(x,y,b,b,b,a);
250       }
251   }
252
253         public void makeRed() {
254                 int r,a;
255                 for (int y = 0; y < getWidth(); y++)
256                    for (int x = 0 ; x < getHeight(); x++) {
257                                 r = getRed (x,y);
258                                 a = getAlpha(x,y);
259                                 setPixel(x,y,r,0,0,a);
260            }
261         }
262         public void makeGreen() {
263                 int g,a;
264                 for (int y = 0; y < getWidth(); y++)
265                         for (int x = 0 ; x < getHeight(); x++) {
266                                 g = getGreen (x,y);
267                                 a = getAlpha(x,y);
268                                 setPixel(x,y,0,g,0,a);
269            }
270         }
271         public void makeBlue() {
272                 int b,a;
273                 for (int y = 0; y < getWidth(); y++)
274                    for (int x = 0 ; x < getHeight(); x++) {
275                                 b = getBlue (x,y);
276                                 a = getAlpha(x,y);
277                                 setPixel(x,y,0,0,b,a);
278            }
279         }
280         public void setPixel(int x,int y, int r, int g, int b, int a) {
281                 array[x][y]=RGBtoInt(r,g,b,a);
282         }
283
284   /*********************************
285   * Allow to change the array
286   * representing the image
287   * @exception IllegalArgumentException if array doesn't make a matrix
288   **********************************/

289   public void setArray (int[][] s) {
290     array=new int[s.length][s[0].length];
291     width=s[0].length;
292     height=s.length;
293     for(int k=0;k<width;k++) {
294       if(s[k].length!=s[0].length) {
295         throw new IllegalArgumentException JavaDoc("Array doesn't make a matrix.");
296       }
297       for(int l=0;l<height;l++) {
298         array[k][l]=s[k][l];
299       }
300     }
301   }
302
303         public int getRed(int x, int y) {
304                 return cm.getRed(array[x][y]);
305         }
306         public int getGreen(int x, int y) {
307                 return cm.getGreen(array[x][y]);
308         }
309         public int getBlue(int x, int y) {
310                 return cm.getBlue(array[x][y]);
311         }
312         public int getAlpha(int x, int y) {
313                 return cm.getAlpha(array[x][y]);
314         }
315
316         public int[][] getRedArray() {
317                 int[][] ans=new int[width][height];
318                 for(int k=0;k<width;k++) {
319                         for(int l=0;l<height;l++)
320                                 ans[k][l]=cm.getRed(array[l][k]);
321                 }
322                 return(ans);
323         }
324         public int[][] getGreenArray() {
325                 int[][] ans=new int[width][height];
326                 for(int k=0;k<width;k++) {
327                         for(int l=0;l<height;l++)
328                                 ans[k][l]=cm.getGreen(array[l][k]);
329                 }
330                 return(ans);
331         }
332         public int[][] getBlueArray() {
333                 int[][] ans=new int[width][height];
334                 for(int k=0;k<width;k++) {
335                         for(int l=0;l<height;l++)
336                                 ans[k][l]=cm.getBlue(array[l][k]);
337                 }
338                 return(ans);
339         }
340         public int[][] getAlphaArray(int x, int y) {
341                 int[][] ans=new int[width][height];
342                 for(int k=0;k<width;k++) {
343                         for(int l=0;l<height;l++)
344                                 ans[k][l]=cm.getAlpha(array[l][k]);
345                 }
346                 return(ans);
347         }
348
349   public int[][] getArray(int x, int y) {
350     int[][] ans=new int[width][height];
351     for(int k=0;k<width;k++) {
352       for(int l=0;l<height;l++) {
353         ans[k][l]=array[k][l];
354       }
355     }
356     return(ans);
357     }
358
359   /**********************************************
360   * Fast Wavelet Transform
361   * This method assumes a dyadic multiresolution.
362   * This implementation is temporary, expect it
363   * to be slow. It is meant to be easily
364   * understood.
365   * One good thing about this method is that
366   * it will handle the boundary automatically
367   * (as long as the chosen Multiresolution
368   * handles them).
369   * Also, it will work with any Multiresolution object.
370   * Only the red component is treated.
371   ***********************************************/

372   public PixelArray[][] redFWT(Multiresolution m) {
373     double[][] doublearray=ArrayCaster.toDouble(getRedArray());
374     return(FWT(m,doublearray));
375   }
376
377   /**********************************************
378   * Fast Wavelet Transform
379   * This method assumes a dyadic multiresolution.
380   * This implementation is temporary, expect it
381   * to be slow. It is meant to be easily
382   * understood.
383   * One good thing about this method is that
384   * it will handle the boundary automatically
385   * (as long as the chosen Multiresolution
386   * handles them).
387   * Also, it will work with any Multiresolution object.
388   * Only the green component is treated.
389   ***********************************************/

390   public PixelArray[][] greenFWT(Multiresolution m) {
391     double[][] doublearray=ArrayCaster.toDouble(getGreenArray());
392     return(FWT(m,doublearray));
393   }
394
395   /**********************************************
396   * Fast Wavelet Transform
397   * This method assumes a dyadic multiresolution.
398   * This implementation is temporary, expect it
399   * to be slow. It is meant to be easily
400   * understood.
401   * One good thing about this method is that
402   * it will handle the boundary automatically
403   * (as long as the chosen Multiresolution
404   * handles them).
405   * Also, it will work with any Multiresolution object.
406   * Only the blue component is treated.
407   ***********************************************/

408   public PixelArray[][] blueFWT(Multiresolution m) {
409     double[][] doublearray=ArrayCaster.toDouble(getBlueArray());
410     return(FWT(m,doublearray));
411   }
412
413   private PixelArray[][] FWT(Multiresolution m, double[][] doublearray) {
414     final int pwidth=m.previousDimension(width);
415     final int wavewidth=width-pwidth;
416     final int pheight=m.previousDimension(height);
417     final int waveheight=height-pheight;
418     DoubleSparseVector[] wcachelow=new DoubleSparseVector[pwidth] ;
419     DoubleSparseVector[] hcachelow=new DoubleSparseVector[pheight] ;
420     DoubleSparseVector[] wcachehigh=new DoubleSparseVector[wavewidth] ;
421     DoubleSparseVector[] hcachehigh=new DoubleSparseVector[waveheight] ;
422     for(int k=0;k<pwidth;k++) {
423       wcachelow[k]=new DoubleSparseVector(m.primaryScaling(pwidth,k).evaluate(1));
424     }
425     for(int k=0;k<pheight;k++) {
426       hcachelow[k]=new DoubleSparseVector(m.primaryScaling(pheight,k).evaluate(1));
427     }
428     for(int k=0;k<wavewidth;k++) {
429       wcachehigh[k]=new DoubleSparseVector(m.primaryWavelet(pwidth,k).evaluate(0));
430     }
431     for(int k=0;k<waveheight;k++) {
432       hcachehigh[k]=new DoubleSparseVector(m.primaryWavelet(pheight,k).evaluate(0));
433     }
434
435         DoubleSparseMatrix temp;
436         DoubleMatrix imgMat=new DoubleMatrix(doublearray);
437     double[][] lowpass=new double[pwidth][pheight];
438     for(int k=0;k<pwidth;k++) {
439       for(int l=0;l<pheight;l++) {
440         temp=wcachelow[k].tensorProduct(hcachelow[l]);
441         lowpass[k][l]=temp.scalarProduct(imgMat);
442       }
443     }
444     double[][] highlowpass=new double[wavewidth][pheight];
445     for(int k=0;k<wavewidth;k++) {
446       for(int l=0;l<pheight;l++) {
447         temp=wcachehigh[k].tensorProduct(hcachelow[l]);
448         highlowpass[k][l]=temp.scalarProduct(imgMat);
449       }
450     }
451     double[][] lowhighpass=new double[pwidth][waveheight];
452     for(int k=0;k<pwidth;k++) {
453       for(int l=0;l<waveheight;l++) {
454         temp=wcachelow[k].tensorProduct(hcachehigh[l]);
455         lowhighpass[k][l]=temp.scalarProduct(imgMat);
456       }
457     }
458     double[][] highhighpass=new double[wavewidth][waveheight];
459     for(int k=0;k<wavewidth;k++) {
460       for(int l=0;l<waveheight;l++) {
461         temp=wcachehigh[k].tensorProduct(hcachehigh[l]);
462         highhighpass[k][l]=temp.scalarProduct(imgMat);
463       }
464     }
465     PixelArray[][] ans=new PixelArray[2][2];
466     ans[0][0]=new PixelArray();
467     ans[0][0].setUniformGrey(toIntegerArray0_255(lowpass));
468     ans[1][0]=new PixelArray();
469     ans[1][0].setUniformGrey(toIntegerArray0_255(highlowpass));
470     ans[0][1]=new PixelArray();
471     ans[0][1].setUniformGrey(toIntegerArray0_255(lowhighpass));
472     ans[1][1]=new PixelArray();
473     ans[1][1].setUniformGrey(toIntegerArray0_255(highhighpass));
474     return(ans);
475   }
476
477
478   private int[][] toIntegerArray0_255(double[][] v) {
479     double max=ArrayMath.max(v);
480     double min=ArrayMath.min(v);
481     if(max==min) {
482       max=min+Double.MIN_VALUE;
483     }
484     int[][] ans=new int[v.length][v[0].length];
485     for(int k=0;k<v.length;k++) {
486       for(int l=0;l<v[0].length;l++) {
487         ans[k][l]=(int) Math.round((v[k][l]-min)/(max-min)*255);
488       }
489     }
490     return(ans);
491   }
492
493   /***********************************
494   * Get the image back
495   ************************************/

496   public Image rebuildImage() {
497     int[] p=new int[height*width];
498     for(int k=0;k<width;k++) {
499       for(int l=0;l<height;l++) {
500         p[l*width+k]=array[l][k];
501       }
502     }
503     MemoryImageSource source=new MemoryImageSource(width,height,cm,p,0,width);
504       return(Toolkit.getDefaultToolkit().createImage(source));
505   }
506
507   public static Image buildImage(int[][] a) {
508     int h=a.length;
509     int w=a[0].length;
510     int[] p=new int[h*w];
511     for(int k=0;k<w;k++) {
512       for(int l=0;l<h;l++) {
513         p[l*w+k]=a[l][k];
514       }
515     }
516     MemoryImageSource source=new MemoryImageSource(w,h,ColorModel.getRGBdefault(),p,0,w);
517       return(Toolkit.getDefaultToolkit().createImage(source));
518   }
519 }
520
521
Popular Tags