KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > util > ColorLib


1 package prefuse.util;
2
3 import java.awt.Color JavaDoc;
4
5 import prefuse.util.collections.IntObjectHashMap;
6
7 /**
8  * <p>Library routines for processing color values. The standard color
9  * representation used by prefuse is to store each color as single
10  * primitive integer value, using 32 bits to represent 4 8-bit color
11  * channels: red, green, blue, and alpha (transparency). An alpha value
12  * of 0 indicates complete transparency while a maximum value (255)
13  * indicated complete opacity. The layout of the bit is as follows,
14  * moving from most significant bit on the left to least significant
15  * bit on the right:</p>
16  *
17  * <pre>
18  * AAAAAAAARRRRRRRRGGGGGGGBBBBBBBB
19  * </pre>
20  *
21  * <p>This class also maintains methods for mapping these values to actual
22  * Java {@link java.awt.Color} instances; a cache is maintained for
23  * quick-lookups, avoiding the need to continually allocate new Color
24  * instances.</p>
25  *
26  * <p>Finally, this class also contains routine for creating color
27  * palettes for use in visualization.</p>
28  *
29  * @author <a HREF="http://jheer.org">jeffrey heer</a>
30  */

31 public class ColorLib {
32
33     public static final char HEX_PREFIX = '#';
34     
35     private static final IntObjectHashMap colorMap = new IntObjectHashMap();
36     private static int misses = 0;
37     private static int lookups = 0;
38     
39     // ------------------------------------------------------------------------
40
// Color Code Methods
41

42     /**
43      * Get the color code for the given red, green, and blue values.
44      * @param r the red color component (in the range 0-255)
45      * @param g the green color component (in the range 0-255)
46      * @param b the blue color component (in the range 0-255)
47      * @return the integer color code
48      */

49     public static int rgb(int r, int g, int b) {
50         return rgba(r, g, b, 255);
51     }
52
53     /**
54      * Get the color code for the given grayscale value.
55      * @param v the grayscale value (in the range 0-255, 0 is
56      * black and 255 is white)
57      * @return the integer color code
58      */

59     public static int gray(int v) {
60         return rgba(v, v, v, 255);
61     }
62
63     /**
64      * Get the color code for the given grayscale value.
65      * @param v the grayscale value (in the range 0-255, 0 is
66      * black and 255 is white)
67      * @param a the alpha (transparency) value (in the range 0-255)
68      * @return the integer color code
69      */

70     public static int gray(int v, int a) {
71         return rgba(v, v, v, a);
72     }
73     
74     /**
75      * Parse a hexadecimal String as a color code. The color convention
76      * is the same as that used in webpages, with two-decimal hexadecimal
77      * numbers representing RGB color values in the range 0-255. A single
78      * '#' character may be included at the beginning of the String, but
79      * is not required. For example '#000000' is black, 'FFFFFF' is white,
80      * '0000FF' is blue, and '#FFFF00' is orange. Color values may also
81      * include transparency (alpha) values, ranging from 00 (fully transparent)
82      * to FF (fully opaque). If included, alpha values should come first in
83      * the string. For example, "#770000FF" is a translucent blue.
84      * @param hex the color code value as a hexadecimal String
85      * @return the integer color code for the input String
86      */

87     public static int hex(String JavaDoc hex) {
88         if ( hex.charAt(0) == HEX_PREFIX )
89             hex = hex.substring(1);
90         
91         if ( hex.length() > 6 ) {
92             // break up number, as Integer will puke on a large unsigned int
93
int rgb = Integer.parseInt(hex.substring(2), 16);
94             int alpha = Integer.parseInt(hex.substring(0,2), 16);
95             return ColorLib.setAlpha(rgb, alpha);
96         } else {
97             return setAlpha(Integer.parseInt(hex, 16), 255);
98         }
99     }
100     
101     /**
102      * Get the color code for the given hue, saturation, and brightness
103      * values, translating from HSB color space to RGB color space.
104      * @param h the hue value (in the range 0-1.0). This represents the
105      * actual color hue (blue, green, purple, etc).
106      * @param s the saturation value (in the range 0-1.0). This represents
107      * "how much" of the color is included. Lower values can result in
108      * more grayed out or pastel colors.
109      * @param b the brightness value (in the range 0-1.0). This represents
110      * how dark or light the color is.
111      * @return the integer color code
112      */

113     public static int hsb(float h, float s, float b) {
114         return Color.HSBtoRGB(h,s,b);
115     }
116     
117     /**
118      * Get the color code for the given hue, saturation, and brightness
119      * values, translating from HSB color space to RGB color space.
120      * @param h the hue value (in the range 0-1.0). This represents the
121      * actual color hue (blue, green, purple, etc).
122      * @param s the saturation value (in the range 0-1.0). This represents
123      * "how much" of the color is included. Lower values can result in
124      * more grayed out or pastel colors.
125      * @param b the brightness value (in the range 0-1.0). This represents
126      * how dark or light the color is.
127      * @param a the alpha value (in the range 0-1.0). This represents the
128      * transparency of the color.
129      * @return the integer color code
130      */

131     public static int hsba(float h, float s, float b, float a) {
132         return setAlpha(Color.HSBtoRGB(h,s,b), (int)(a*255+0.5) & 0xFF);
133     }
134     
135     /**
136      * Get the color code for the given red, green, blue, and alpha values.
137      * @param r the red color component (in the range 0-255)
138      * @param g the green color component (in the range 0-255)
139      * @param b the blue color component (in the range 0-255)
140      * @param a the alpha (transparency) component (in the range 0-255)
141      * @return the integer color code
142      */

143     public static int rgba(int r, int g, int b, int a) {
144         return ((a & 0xFF) << 24) | ((r & 0xFF) << 16) |
145                ((g & 0xFF) << 8) | ((b & 0xFF) << 0);
146     }
147     
148     /**
149      * Get the color code for the given red, green, blue, and alpha values as
150      * floating point numbers in the range 0-1.0.
151      * @param r the red color component (in the range 0-1.0)
152      * @param g the green color component (in the range 0-1.0)
153      * @param b the blue color component (in the range 0-1.0)
154      * @param a the alpha (transparency) component (in the range 0-1.0)
155      * @return the integer color code
156      */

157     public static int rgba(float r, float g, float b, float a) {
158         return ((((int)(a*255+0.5)) & 0xFF) << 24) |
159                ((((int)(r*255+0.5)) & 0xFF) << 16) |
160                ((((int)(g*255+0.5)) & 0xFF) << 8) |
161                (((int)(b*255+0.5)) & 0xFF);
162     }
163     
164     /**
165      * Get the color code for the given Color instance.
166      * @param c the Java Color instance
167      * @return the integer color code
168      */

169     public static int color(Color JavaDoc c) {
170         return c.getRGB();
171     }
172     
173     /**
174      * Get the red component of the given color.
175      * @param color the color code
176      * @return the red component of the color (in the range 0-255)
177      */

178     public static int red(int color) {
179         return (color>>16) & 0xFF;
180     }
181     
182     /**
183      * Get the green component of the given color.
184      * @param color the color code
185      * @return the green component of the color (in the range 0-255)
186      */

187     public static int green(int color) {
188         return (color>>8) & 0xFF;
189     }
190     
191     /**
192      * Get the blue component of the given color.
193      * @param color the color code
194      * @return the blue component of the color (in the range 0-255)
195      */

196     public static int blue(int color) {
197         return color & 0xFF;
198     }
199     
200     /**
201      * Get the alpha component of the given color.
202      * @param color the color code
203      * @return the alpha component of the color (in the range 0-255)
204      */

205     public static int alpha(int color) {
206         return (color>>24) & 0xFF;
207     }
208     
209     /**
210      * Set the alpha component of the given color.
211      * @param c the color code
212      * @param alpha the alpha value to set
213      * @return the new color with updated alpha channel
214      */

215     public static int setAlpha(int c, int alpha) {
216         return rgba(red(c), green(c), blue(c), alpha);
217     }
218     
219     // ------------------------------------------------------------------------
220
// java.awt.Color Lookup Methods
221

222     /**
223      * Get a Java Color object for the given red, green, blue, and alpha values
224      * as floating point numbers in the range 0-1.0.
225      * @param r the red color component (in the range 0-1.0)
226      * @param g the green color component (in the range 0-1.0)
227      * @param b the blue color component (in the range 0-1.0)
228      * @param a the alpha (transparency) component (in the range 0-1.0)
229      * @return a Java Color object
230      */

231     public static Color JavaDoc getColor(float r, float g, float b, float a) {
232         return getColor(rgba(r,g,b,a));
233     }
234
235     /**
236      * Get a Java Color object for the given red, green, and blue values
237      * as floating point numbers in the range 0-1.0.
238      * @param r the red color component (in the range 0-1.0)
239      * @param g the green color component (in the range 0-1.0)
240      * @param b the blue color component (in the range 0-1.0)
241      * @return a Java Color object
242      */

243     public static Color JavaDoc getColor(float r, float g, float b) {
244         return getColor(r,g,b,1.0f);
245     }
246     
247     /**
248      * Get a Java Color object for the given red, green, and blue values.
249      * @param r the red color component (in the range 0-255)
250      * @param g the green color component (in the range 0-255)
251      * @param b the blue color component (in the range 0-255)
252      * @param a the alpa (transparency) component (in the range 0-255)
253      * @return a Java Color object
254      */

255     public static Color JavaDoc getColor(int r, int g, int b, int a) {
256         return getColor(rgba(r,g,b,a));
257     }
258     
259     /**
260      * Get a Java Color object for the given red, green, and blue values.
261      * @param r the red color component (in the range 0-255)
262      * @param g the green color component (in the range 0-255)
263      * @param b the blue color component (in the range 0-255)
264      * @return a Java Color object
265      */

266     public static Color JavaDoc getColor(int r, int g, int b) {
267         return getColor(r,g,b,255);
268     }
269     
270     /**
271      * Get a Java Color object for the given grayscale value.
272      * @param v the grayscale value (in the range 0-255, 0 is
273      * black and 255 is white)
274      * @return a Java Color object
275      */

276     public static Color JavaDoc getGrayscale(int v) {
277         return getColor(v,v,v,255);
278     }
279     
280     /**
281      * Get a Java Color object for the given color code value.
282      * @param rgba the integer color code containing red, green,
283      * blue, and alpha channel information
284      * @return a Java Color object
285      */

286     public static Color JavaDoc getColor(int rgba) {
287         Color JavaDoc c = null;
288         if ( (c=(Color JavaDoc)colorMap.get(rgba)) == null ) {
289             c = new Color JavaDoc(rgba,true);
290             colorMap.put(rgba,c);
291             misses++;
292         }
293         lookups++;
294         return c;
295     }
296     
297     // ------------------------------------------------------------------------
298
// ColorLib Statistics and Cache Management
299

300     /**
301      * Get the number of cache misses to the Color object cache.
302      * @return the number of cache misses
303      */

304     public static int getCacheMissCount() {
305         return misses;
306     }
307
308     /**
309      * Get the number of cache lookups to the Color object cache.
310      * @return the number of cache lookups
311      */

312     public static int getCacheLookupCount() {
313         return lookups;
314     }
315     
316     /**
317      * Clear the Color object cache.
318      */

319     public static void clearCache() {
320         colorMap.clear();
321     }
322     
323     
324     // ------------------------------------------------------------------------
325
// Color Calculations
326

327     private static final float scale = 0.7f;
328     
329     /**
330      * Interpolate between two color values by the given mixing proportion.
331      * A mixing fraction of 0 will result in c1, a value of 1.0 will result
332      * in c2, and value of 0.5 will result in the color mid-way between the
333      * two in RGB color space.
334      * @param c1 the starting color
335      * @param c2 the target color
336      * @param frac a fraction between 0 and 1.0 controlling the interpolation
337      * amount.
338      * @return the interpolated color code
339      */

340     public static int interp(int c1, int c2, double frac) {
341         double ifrac = 1-frac;
342         return rgba(
343             (int)Math.round(frac*red(c2) + ifrac*red(c1)),
344             (int)Math.round(frac*green(c2) + ifrac*green(c1)),
345             (int)Math.round(frac*blue(c2) + ifrac*blue(c1)),
346             (int)Math.round(frac*alpha(c2) + ifrac*alpha(c1)));
347     }
348     
349     /**
350      * Get a darker shade of an input color.
351      * @param c a color code
352      * @return a darkened color code
353      */

354     public static int darker(int c) {
355         return rgba(Math.max(0, (int)(scale*red(c))),
356                     Math.max(0, (int)(scale*green(c))),
357                     Math.max(0, (int)(scale*blue(c))),
358                     alpha(c));
359     }
360
361     /**
362      * Get a brighter shade of an input color.
363      * @param c a color code
364      * @return a brighter color code
365      */

366     public static int brighter(int c) {
367         int r = red(c), g = green(c), b = blue(c);
368         int i = (int)(1.0/(1.0-scale));
369         if ( r == 0 && g == 0 && b == 0) {
370            return rgba(i, i, i, alpha(c));
371         }
372         if ( r > 0 && r < i ) r = i;
373         if ( g > 0 && g < i ) g = i;
374         if ( b > 0 && b < i ) b = i;
375
376         return rgba(Math.min(255, (int)(r/scale)),
377                     Math.min(255, (int)(g/scale)),
378                     Math.min(255, (int)(b/scale)),
379                     alpha(c));
380     }
381     
382     /**
383      * Get a desaturated shade of an input color.
384      * @param c a color code
385      * @return a desaturated color code
386      */

387     public static int desaturate(int c) {
388         int a = c & 0xff000000;
389         float r = ((c & 0xff0000) >> 16);
390         float g = ((c & 0x00ff00) >> 8);
391         float b = (c & 0x0000ff);
392
393         r *= 0.2125f; // red band weight
394
g *= 0.7154f; // green band weight
395
b *= 0.0721f; // blue band weight
396

397         int gray = Math.min(((int)(r+g+b)),0xff) & 0xff;
398         return a | (gray << 16) | (gray << 8) | gray;
399     }
400     
401     /**
402      * Set the saturation of an input color.
403      * @param c a color code
404      * @param saturation the new sautration value
405      * @return a saturated color code
406      */

407     public static int saturate(int c, float saturation) {
408         float[] hsb = Color.RGBtoHSB(red(c), green(c), blue(c), null);
409         return ColorLib.hsb(hsb[0], saturation, hsb[2]);
410     }
411     
412     // ------------------------------------------------------------------------
413
// Color Palettes
414

415     /**
416      * Default palette of category hues.
417      */

418     public static final float[] CATEGORY_HUES = {
419         0f, 1f/12f, 1f/6f, 1f/3f, 1f/2f, 7f/12f, 2f/3f, /*3f/4f,*/ 5f/6f, 11f/12f
420     };
421     
422     /**
423      * The default length of a color palette if its size
424      * is not otherwise specified.
425      */

426     public static final int DEFAULT_MAP_SIZE = 64;
427
428     /**
429      * Returns a color palette that uses a "cool", blue-heavy color scheme.
430      * @param size the size of the color palette
431      * @return the color palette
432      */

433     public static int[] getCoolPalette(int size) {
434         int[] cm = new int[size];
435         for( int i=0; i<size; i++ ) {
436             float r = i / Math.max(size-1,1.f);
437             cm[i] = rgba(r,1-r,1.f,1.f);
438         }
439         return cm;
440     }
441
442     /**
443      * Returns a color palette of default size that uses a "cool",
444      * blue-heavy color scheme.
445      * @return the color palette
446      */

447     public static int[] getCoolPalette() {
448         return getCoolPalette(DEFAULT_MAP_SIZE);
449     }
450
451     /**
452      * Returns a color map that moves from black to red to yellow
453      * to white.
454      * @param size the size of the color palette
455      * @return the color palette
456      */

457     public static int[] getHotPalette(int size) {
458         int[] cm = new int[size];
459         for ( int i=0; i<size; i++ ) {
460             int n = (3*size)/8;
461             float r = ( i<n ? ((float)(i+1))/n : 1.f );
462             float g = ( i<n ? 0.f : ( i<2*n ? ((float)(i-n))/n : 1.f ));
463             float b = ( i<2*n ? 0.f : ((float)(i-2*n))/(size-2*n) );
464             cm[i] = rgba(r,g,b,1.0f);
465         }
466         return cm;
467     }
468
469     /**
470      * Returns a color map of default size that moves from black to
471      * red to yellow to white.
472      * @return the color palette
473      */

474     public static int[] getHotPalette() {
475         return getHotPalette(DEFAULT_MAP_SIZE);
476     }
477
478     /**
479      * Returns a color palette of given size tries to provide colors
480      * appropriate as category labels. There are 12 basic color hues
481      * (red, orange, yellow, olive, green, cyan, blue, purple, magenta,
482      * and pink). If the size is greater than 12, these colors will be
483      * continually repeated, but with varying saturation levels.
484      * @param size the size of the color palette
485      * @param s1 the initial saturation to use
486      * @param s2 the final (most distant) saturation to use
487      * @param b the brightness value to use
488      * @param a the alpha value to use
489      */

490     public static int[] getCategoryPalette(int size,
491             float s1, float s2, float b, float a)
492     {
493         int[] cm = new int[size];
494         float s = s1;
495         for ( int i=0; i<size; i++ ) {
496             int j = i % CATEGORY_HUES.length;
497             if ( j == 0 )
498                 s = s1 + (((float)i)/size)*(s2-s1);
499             cm[i] = hsba(CATEGORY_HUES[j],s,b,a);
500         }
501         return cm;
502     }
503
504     /**
505      * Returns a color palette of given size tries to provide colors
506      * appropriate as category labels. There are 12 basic color hues
507      * (red, orange, yellow, olive, green, cyan, blue, purple, magenta,
508      * and pink). If the size is greater than 12, these colors will be
509      * continually repeated, but with varying saturation levels.
510      * @param size the size of the color palette
511      */

512     public static int[] getCategoryPalette(int size) {
513         return getCategoryPalette(size, 1.f, 0.4f, 1.f, 1.0f);
514     }
515
516     /**
517      * Returns a color palette of given size that cycles through
518      * the hues of the HSB (Hue/Saturation/Brightness) color space.
519      * @param size the size of the color palette
520      * @param s the saturation value to use
521      * @param b the brightness value to use
522      * @return the color palette
523      */

524     public static int[] getHSBPalette(int size, float s, float b) {
525         int[] cm = new int[size];
526         for ( int i=0; i<size; i++ ) {
527             float h = ((float)i)/(size-1);
528             cm[i] = hsb(h,s,b);
529         }
530         return cm;
531     }
532
533     /**
534      * Returns a color palette of default size that cycles through
535      * the hues of the HSB (Hue/Saturation/Brightness) color space at
536      * full saturation and brightness.
537      * @return the color palette
538      */

539     public static int[] getHSBPalette() {
540         return getHSBPalette(DEFAULT_MAP_SIZE, 1.f, 1.f);
541     }
542
543     /**
544      * Returns a color palette of given size that ranges from one
545      * given color to the other.
546      * @param size the size of the color palette
547      * @param c1 the initial color in the color map
548      * @param c2 the final color in the color map
549      * @return the color palette
550      */

551     public static int[] getInterpolatedPalette(int size, int c1, int c2)
552     {
553         int[] cm = new int[size];
554         for ( int i=0; i<size; i++ ) {
555             float f = ((float)i)/(size-1);
556             cm[i] = interp(c1,c2,f);
557         }
558         return cm;
559     }
560
561     /**
562      * Returns a color palette of default size that ranges from one
563      * given color to the other.
564      * @param c1 the initial color in the color map
565      * @param c2 the final color in the color map
566      * @return the color palette
567      */

568     public static int[] getInterpolatedPalette(int c1, int c2) {
569         return getInterpolatedPalette(DEFAULT_MAP_SIZE, c1, c2);
570     }
571
572     /**
573      * Returns a color palette of specified size that ranges from white to
574      * black through shades of gray.
575      * @param size the size of the color palette
576      * @return the color palette
577      */

578     public static int[] getGrayscalePalette(int size) {
579         int[] cm = new int[size];
580         for ( int i=0, g; i<size; i++ ) {
581             g = (int)Math.round(255*(0.2f + 0.6f*((float)i)/(size-1)));
582             cm[size-i-1] = gray(g);
583         }
584         return cm;
585     }
586
587     /**
588      * Returns a color palette of default size that ranges from white to
589      * black through shades of gray.
590      * @return the color palette
591      */

592     public static int[] getGrayscalePalette() {
593         return getGrayscalePalette(DEFAULT_MAP_SIZE);
594     }
595     
596 } // end of class ColorLib
597
Popular Tags