KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > image > RGBImageFilter


1 /*
2  * @(#)RGBImageFilter.java 1.24 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.awt.image;
9
10 import java.awt.image.ImageConsumer JavaDoc;
11 import java.awt.image.ColorModel JavaDoc;
12
13 /**
14  * This class provides an easy way to create an ImageFilter which modifies
15  * the pixels of an image in the default RGB ColorModel. It is meant to
16  * be used in conjunction with a FilteredImageSource object to produce
17  * filtered versions of existing images. It is an abstract class that
18  * provides the calls needed to channel all of the pixel data through a
19  * single method which converts pixels one at a time in the default RGB
20  * ColorModel regardless of the ColorModel being used by the ImageProducer.
21  * The only method which needs to be defined to create a useable image
22  * filter is the filterRGB method. Here is an example of a definition
23  * of a filter which swaps the red and blue components of an image:
24  * <pre>
25  *
26  * class RedBlueSwapFilter extends RGBImageFilter {
27  * public RedBlueSwapFilter() {
28  * // The filter's operation does not depend on the
29  * // pixel's location, so IndexColorModels can be
30  * // filtered directly.
31  * canFilterIndexColorModel = true;
32  * }
33  *
34  * public int filterRGB(int x, int y, int rgb) {
35  * return ((rgb & 0xff00ff00)
36  * | ((rgb & 0xff0000) >> 16)
37  * | ((rgb & 0xff) << 16));
38  * }
39  * }
40  *
41  * </pre>
42  *
43  * @see FilteredImageSource
44  * @see ImageFilter
45  * @see ColorModel#getRGBdefault
46  *
47  * @version 1.24 12/19/03
48  * @author Jim Graham
49  */

50 public abstract class RGBImageFilter extends ImageFilter JavaDoc {
51
52     /**
53      * The <code>ColorModel</code> to be replaced by
54      * <code>newmodel</code> when the user calls
55      * {@link #substituteColorModel(ColorModel, ColorModel) substituteColorModel}.
56      */

57     protected ColorModel JavaDoc origmodel;
58
59     /**
60      * The <code>ColorModel</code> with which to
61      * replace <code>origmodel</code> when the user calls
62      * <code>substituteColorModel</code>.
63      */

64     protected ColorModel JavaDoc newmodel;
65
66     /**
67      * This boolean indicates whether or not it is acceptable to apply
68      * the color filtering of the filterRGB method to the color table
69      * entries of an IndexColorModel object in lieu of pixel by pixel
70      * filtering. Subclasses should set this variable to true in their
71      * constructor if their filterRGB method does not depend on the
72      * coordinate of the pixel being filtered.
73      * @see #substituteColorModel
74      * @see #filterRGB
75      * @see IndexColorModel
76      */

77     protected boolean canFilterIndexColorModel;
78
79     /**
80      * If the ColorModel is an IndexColorModel and the subclass has
81      * set the canFilterIndexColorModel flag to true, we substitute
82      * a filtered version of the color model here and wherever
83      * that original ColorModel object appears in the setPixels methods.
84      * If the ColorModel is not an IndexColorModel or is null, this method
85      * overrides the default ColorModel used by the ImageProducer and
86      * specifies the default RGB ColorModel instead.
87      * <p>
88      * Note: This method is intended to be called by the
89      * <code>ImageProducer</code> of the <code>Image</code> whose pixels
90      * are being filtered. Developers using
91      * this class to filter pixels from an image should avoid calling
92      * this method directly since that operation could interfere
93      * with the filtering operation.
94      * @see ImageConsumer
95      * @see ColorModel#getRGBdefault
96      */

97     public void setColorModel(ColorModel JavaDoc model) {
98     if (canFilterIndexColorModel && (model instanceof IndexColorModel JavaDoc)) {
99         ColorModel JavaDoc newcm = filterIndexColorModel((IndexColorModel JavaDoc)model);
100         substituteColorModel(model, newcm);
101         consumer.setColorModel(newcm);
102     } else {
103         consumer.setColorModel(ColorModel.getRGBdefault());
104     }
105     }
106
107     /**
108      * Registers two ColorModel objects for substitution. If the oldcm
109      * is encountered during any of the setPixels methods, the newcm
110      * is substituted and the pixels passed through
111      * untouched (but with the new ColorModel object).
112      * @param oldcm the ColorModel object to be replaced on the fly
113      * @param newcm the ColorModel object to replace oldcm on the fly
114      */

115     public void substituteColorModel(ColorModel JavaDoc oldcm, ColorModel JavaDoc newcm) {
116     origmodel = oldcm;
117     newmodel = newcm;
118     }
119
120     /**
121      * Filters an IndexColorModel object by running each entry in its
122      * color tables through the filterRGB function that RGBImageFilter
123      * subclasses must provide. Uses coordinates of -1 to indicate that
124      * a color table entry is being filtered rather than an actual
125      * pixel value.
126      * @param icm the IndexColorModel object to be filtered
127      * @exception NullPointerException if <code>icm</code> is null
128      * @return a new IndexColorModel representing the filtered colors
129      */

130     public IndexColorModel JavaDoc filterIndexColorModel(IndexColorModel JavaDoc icm) {
131     int mapsize = icm.getMapSize();
132     byte r[] = new byte[mapsize];
133     byte g[] = new byte[mapsize];
134     byte b[] = new byte[mapsize];
135     byte a[] = new byte[mapsize];
136     icm.getReds(r);
137     icm.getGreens(g);
138     icm.getBlues(b);
139     icm.getAlphas(a);
140     int trans = icm.getTransparentPixel();
141     boolean needalpha = false;
142     for (int i = 0; i < mapsize; i++) {
143         int rgb = filterRGB(-1, -1, icm.getRGB(i));
144         a[i] = (byte) (rgb >> 24);
145         if (a[i] != ((byte)0xff) && i != trans) {
146         needalpha = true;
147         }
148         r[i] = (byte) (rgb >> 16);
149         g[i] = (byte) (rgb >> 8);
150         b[i] = (byte) (rgb >> 0);
151     }
152     if (needalpha) {
153         return new IndexColorModel JavaDoc(icm.getPixelSize(), mapsize,
154                        r, g, b, a);
155     } else {
156         return new IndexColorModel JavaDoc(icm.getPixelSize(), mapsize,
157                        r, g, b, trans);
158     }
159     }
160
161     /**
162      * Filters a buffer of pixels in the default RGB ColorModel by passing
163      * them one by one through the filterRGB method.
164      * @param x,&nbsp;y the coordinates of the upper-left corner of the
165      * region of pixels
166      * @param w the width of the region of pixels
167      * @param h the height of the region of pixels
168      * @param pixels the array of pixels
169      * @param off the offset into the <code>pixels</code> array
170      * @param scansize the distance from one row of pixels to the next
171      * in the array
172      * @see ColorModel#getRGBdefault
173      * @see #filterRGB
174      */

175     public void filterRGBPixels(int x, int y, int w, int h,
176                 int pixels[], int off, int scansize) {
177     int index = off;
178     for (int cy = 0; cy < h; cy++) {
179         for (int cx = 0; cx < w; cx++) {
180         pixels[index] = filterRGB(x + cx, y + cy, pixels[index]);
181         index++;
182         }
183         index += scansize - w;
184     }
185     consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(),
186                pixels, off, scansize);
187     }
188
189     /**
190      * If the ColorModel object is the same one that has already
191      * been converted, then simply passes the pixels through with the
192      * converted ColorModel. Otherwise converts the buffer of byte
193      * pixels to the default RGB ColorModel and passes the converted
194      * buffer to the filterRGBPixels method to be converted one by one.
195      * <p>
196      * Note: This method is intended to be called by the
197      * <code>ImageProducer</code> of the <code>Image</code> whose pixels
198      * are being filtered. Developers using
199      * this class to filter pixels from an image should avoid calling
200      * this method directly since that operation could interfere
201      * with the filtering operation.
202      * @see ColorModel#getRGBdefault
203      * @see #filterRGBPixels
204      */

205     public void setPixels(int x, int y, int w, int h,
206               ColorModel JavaDoc model, byte pixels[], int off,
207               int scansize) {
208     if (model == origmodel) {
209         consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
210     } else {
211         int filteredpixels[] = new int[w];
212         int index = off;
213         for (int cy = 0; cy < h; cy++) {
214         for (int cx = 0; cx < w; cx++) {
215             filteredpixels[cx] = model.getRGB((pixels[index] & 0xff));
216             index++;
217         }
218         index += scansize - w;
219         filterRGBPixels(x, y + cy, w, 1, filteredpixels, 0, w);
220         }
221     }
222     }
223
224     /**
225      * If the ColorModel object is the same one that has already
226      * been converted, then simply passes the pixels through with the
227      * converted ColorModel, otherwise converts the buffer of integer
228      * pixels to the default RGB ColorModel and passes the converted
229      * buffer to the filterRGBPixels method to be converted one by one.
230      * Converts a buffer of integer pixels to the default RGB ColorModel
231      * and passes the converted buffer to the filterRGBPixels method.
232      * <p>
233      * Note: This method is intended to be called by the
234      * <code>ImageProducer</code> of the <code>Image</code> whose pixels
235      * are being filtered. Developers using
236      * this class to filter pixels from an image should avoid calling
237      * this method directly since that operation could interfere
238      * with the filtering operation.
239      * @see ColorModel#getRGBdefault
240      * @see #filterRGBPixels
241      */

242     public void setPixels(int x, int y, int w, int h,
243               ColorModel JavaDoc model, int pixels[], int off,
244               int scansize) {
245     if (model == origmodel) {
246         consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
247     } else {
248         int filteredpixels[] = new int[w];
249         int index = off;
250         for (int cy = 0; cy < h; cy++) {
251         for (int cx = 0; cx < w; cx++) {
252             filteredpixels[cx] = model.getRGB(pixels[index]);
253             index++;
254         }
255         index += scansize - w;
256         filterRGBPixels(x, y + cy, w, 1, filteredpixels, 0, w);
257         }
258     }
259     }
260
261     /**
262      * Subclasses must specify a method to convert a single input pixel
263      * in the default RGB ColorModel to a single output pixel.
264      * @param x,&nbsp;y the coordinates of the pixel
265      * @param rgb the integer pixel representation in the default RGB
266      * color model
267      * @return a filtered pixel in the default RGB color model.
268      * @see ColorModel#getRGBdefault
269      * @see #filterRGBPixels
270      */

271     public abstract int filterRGB(int x, int y, int rgb);
272 }
273
Popular Tags