Java/2D Graphics GUI/Color
Содержание
- 1 140 colors - defined for X Window System listed in O"Reilly html pocket reference 87pp
- 2 An efficient color quantization algorithm
- 3 Color class is used to work with colors in Java 2D
- 4 Color Difference
- 5 Color Factory
- 6 Color fading animation
- 7 Color Util
- 8 Color Utilities: common color operations
- 9 Common color utilities
- 10 Converts a given string into a color.
- 11 Converts the String representation of a color to an actual Color object.
- 12 Derives a color by adding the specified offsets to the base color"s hue, saturation, and brightness values
- 13 Drawing with Color
- 14 If the color is equal to one of the defined constant colors, that name is returned instead.
- 15 Map colors into names and vice versa.
- 16 Rainbow Color
- 17 Utility for checking colors given either hexa or natural language string descriptions.
- 18 XOR color
140 colors - defined for X Window System listed in O"Reilly html pocket reference 87pp
<source lang="java"> /*
- Caramel - Non-GUI Java Addons
- Copyright (c) 2001, 2002, 2003 by Gerald Bauer
- This program is free software.
- You may redistribute it and/or modify it under the terms of the GNU
- Lesser General Public License as published by the Free Software Foundation.
- Version 2.1 of the license should be included with this distribution in
- the file LICENSE, as well as License.html. If the license is not
- included with this distribution, you may find a copy at the FSF web
- site at "www.gnu.org" or "www.fsf.org", or you may write to the
- Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
- THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
- NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
- OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
- CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
- REDISTRIBUTION OF THIS SOFTWARE.
- /
import java.awt.*; import java.util.*; /**
* 140 colors - defined for X Window System listed in O"Reilly html pocket * reference 87pp */
public class ColorUtils {
public final static Color aliceblue = new Color( 240, 248, 255 ); public final static Color antiquewhite = new Color( 250, 235, 215 ); public final static Color aqua = new Color( 0, 255, 255 ); public final static Color aquamarine = new Color( 127, 255, 212 ); public final static Color azure = new Color( 240, 255, 255 ); public final static Color beige = new Color( 245, 245, 220 ); public final static Color bisque = new Color( 255, 228, 196 ); public final static Color black = new Color( 0, 0, 0 ); public final static Color blanchedalmond = new Color( 255, 255, 205 ); public final static Color blue = new Color( 0, 0, 255 ); public final static Color blueviolet = new Color( 138, 43, 226 ); public final static Color brown = new Color( 165, 42, 42 ); public final static Color burlywood = new Color( 222, 184, 135 ); public final static Color cadetblue = new Color( 95, 158, 160 ); public final static Color chartreuse = new Color( 127, 255, 0 ); public final static Color chocolate = new Color( 210, 105, 30 ); public final static Color coral = new Color( 255, 127, 80 ); public final static Color cornflowerblue = new Color( 100, 149, 237 ); public final static Color cornsilk = new Color( 255, 248, 220 ); public final static Color crimson = new Color( 220, 20, 60 ); public final static Color cyan = new Color( 0, 255, 255 ); public final static Color darkblue = new Color( 0, 0, 139 ); public final static Color darkcyan = new Color( 0, 139, 139 ); public final static Color darkgoldenrod = new Color( 184, 134, 11 ); public final static Color darkgray = new Color( 169, 169, 169 ); public final static Color darkgreen = new Color( 0, 100, 0 ); public final static Color darkkhaki = new Color( 189, 183, 107 ); public final static Color darkmagenta = new Color( 139, 0, 139 ); public final static Color darkolivegreen = new Color( 85, 107, 47 ); public final static Color darkorange = new Color( 255, 140, 0 ); public final static Color darkorchid = new Color( 153, 50, 204 ); public final static Color darkred = new Color( 139, 0, 0 ); public final static Color darksalmon = new Color( 233, 150, 122 ); public final static Color darkseagreen = new Color( 143, 188, 143 ); public final static Color darkslateblue = new Color( 72, 61, 139 ); public final static Color darkslategray = new Color( 47, 79, 79 ); public final static Color darkturquoise = new Color( 0, 206, 209 ); public final static Color darkviolet = new Color( 148, 0, 211 ); public final static Color deeppink = new Color( 255, 20, 147 ); public final static Color deepskyblue = new Color( 0, 191, 255 ); public final static Color dimgray = new Color( 105, 105, 105 ); public final static Color dodgerblue = new Color( 30, 144, 255 ); public final static Color firebrick = new Color( 178, 34, 34 ); public final static Color floralwhite = new Color( 255, 250, 240 ); public final static Color forestgreen = new Color( 34, 139, 34 ); public final static Color fuchsia = new Color( 255, 0, 255 ); public final static Color gainsboro = new Color( 220, 220, 220 ); public final static Color ghostwhite = new Color( 248, 248, 255 ); public final static Color gold = new Color( 255, 215, 0 ); public final static Color goldenrod = new Color( 218, 165, 32 ); public final static Color gray = new Color( 128, 128, 128 ); public final static Color green = new Color( 0, 128, 0 ); public final static Color greenyellow = new Color( 173, 255, 47 ); public final static Color honeydew = new Color( 240, 255, 240 ); public final static Color hotpink = new Color( 255, 105, 180 ); public final static Color indianred = new Color( 205, 92, 92 ); public final static Color indigo = new Color( 75, 0, 130 ); public final static Color ivory = new Color( 255, 240, 240 ); public final static Color khaki = new Color( 240, 230, 140 ); public final static Color lavender = new Color( 230, 230, 250 ); public final static Color lavenderblush = new Color( 255, 240, 245 ); public final static Color lawngreen = new Color( 124, 252, 0 ); public final static Color lemonchiffon = new Color( 255, 250, 205 ); public final static Color lightblue = new Color( 173, 216, 230 ); public final static Color lightcoral = new Color( 240, 128, 128 ); public final static Color lightcyan = new Color( 224, 255, 255 ); public final static Color lightgoldenrodyellow = new Color( 250, 250, 210 ); public final static Color lightgreen = new Color( 144, 238, 144 ); public final static Color lightgrey = new Color( 211, 211, 211 ); public final static Color lightpink = new Color( 255, 182, 193 ); public final static Color lightsalmon = new Color( 255, 160, 122 ); public final static Color lightseagreen = new Color( 32, 178, 170 ); public final static Color lightskyblue = new Color( 135, 206, 250 ); public final static Color lightslategray = new Color( 119, 136, 153 ); public final static Color lightsteelblue = new Color( 176, 196, 222 ); public final static Color lightyellow = new Color( 255, 255, 224 ); public final static Color lime = new Color( 0, 255, 0 ); public final static Color limegreen = new Color( 50, 205, 50 ); public final static Color linen = new Color( 250, 240, 230 ); public final static Color magenta = new Color( 255, 0, 255 ); public final static Color maroon = new Color( 128, 0, 0 ); public final static Color mediumaquamarine = new Color( 102, 205, 170 ); public final static Color mediumblue = new Color( 0, 0, 205 ); public final static Color mediumorchid = new Color( 186, 85, 211 ); public final static Color mediumpurple = new Color( 147, 112, 219 ); public final static Color mediumseagreen = new Color( 60, 179, 113 ); public final static Color mediumslateblue = new Color( 123, 104, 238 ); public final static Color mediumspringgreen = new Color( 0, 250, 154 ); public final static Color mediumturquoise = new Color( 72, 209, 204 ); public final static Color mediumvioletred = new Color( 199, 21, 133 ); public final static Color midnightblue = new Color( 25, 25, 112 ); public final static Color mintcream = new Color( 245, 255, 250 ); public final static Color mistyrose = new Color( 255, 228, 225 ); public final static Color mocassin = new Color( 255, 228, 181 ); public final static Color navajowhite = new Color( 255, 222, 173 ); public final static Color navy = new Color( 0, 0, 128 ); public final static Color oldlace = new Color( 253, 245, 230 ); public final static Color olive = new Color( 128, 128, 0 ); public final static Color olivedrab = new Color( 107, 142, 35 ); public final static Color orange = new Color( 255, 165, 0 ); public final static Color orangered = new Color( 255, 69, 0 ); public final static Color orchid = new Color( 218, 112, 214 ); public final static Color palegoldenrod = new Color( 238, 232, 170 ); public final static Color palegreen = new Color( 152, 251, 152 ); public final static Color paleturquoise = new Color( 175, 238, 238 ); public final static Color palevioletred = new Color( 219, 112, 147 ); public final static Color papayawhip = new Color( 255, 239, 213 ); public final static Color peachpuff = new Color( 255, 218, 185 ); public final static Color peru = new Color( 205, 133, 63 ); public final static Color pink = new Color( 255, 192, 203 ); public final static Color plum = new Color( 221, 160, 221 ); public final static Color powderblue = new Color( 176, 224, 230 ); public final static Color purple = new Color( 128, 0, 128 ); public final static Color red = new Color( 255, 0, 0 ); public final static Color rosybrown = new Color( 188, 143, 143 ); public final static Color royalblue = new Color( 65, 105, 225 ); public final static Color saddlebrown = new Color( 139, 69, 19 ); public final static Color salmon = new Color( 250, 128, 114 ); public final static Color sandybrown = new Color( 244, 164, 96 ); public final static Color seagreen = new Color( 46, 139, 87 ); public final static Color seashell = new Color( 255, 245, 238 ); public final static Color sienna = new Color( 160, 82, 45 ); public final static Color silver = new Color( 192, 192, 192 ); public final static Color skyblue = new Color( 135, 206, 235 ); public final static Color slateblue = new Color( 106, 90, 205 ); public final static Color slategray = new Color( 112, 128, 144 ); public final static Color snow = new Color( 255, 250, 250 ); public final static Color springgreen = new Color( 0, 255, 127 ); public final static Color steelblue = new Color( 70, 138, 180 ); public final static Color tan = new Color( 210, 180, 140 ); public final static Color teal = new Color( 0, 128, 128 ); public final static Color thistle = new Color( 216, 191, 216 ); public final static Color tomato = new Color( 253, 99, 71 ); public final static Color turquoise = new Color( 64, 224, 208 ); public final static Color violet = new Color( 238, 130, 238 ); public final static Color wheat = new Color( 245, 222, 179 ); public final static Color white = new Color( 255, 255, 255 ); public final static Color whitesmoke = new Color( 245, 245, 245 ); public final static Color yellow = new Color( 255, 255, 0 ); public final static Color yellowgreen = new Color( 154, 205, 50 ); private static HashMap _colors; private static Object[][] data = { {"aliceblue", aliceblue}, {"antiquewhite", antiquewhite}, {"aqua", aqua}, {"aquamarine", aquamarine}, {"azure", azure}, {"beige", beige}, {"bisque", bisque}, {"black", black}, {"blanchedalmond", blanchedalmond}, {"blue", blue}, {"blueviolet", blueviolet}, {"brown", brown}, {"burlywood", burlywood}, {"cadetblue", cadetblue}, {"chartreuse", chartreuse}, {"chocolate", chocolate}, {"coral", coral}, {"cornflowerblue", cornflowerblue}, {"cornsilk", cornsilk}, {"crimson", crimson}, {"cyan", cyan}, {"darkblue", darkblue}, {"darkcyan", darkcyan}, {"darkgoldenrod", darkgoldenrod}, {"darkgray", darkgray}, {"darkgreen", darkgreen}, {"darkkhaki", darkkhaki}, {"darkmagenta", darkmagenta}, {"darkolivegreen", darkolivegreen}, {"darkorange", darkorange}, {"darkorchid", darkorchid}, {"darkred", darkred}, {"darksalmon", darksalmon}, {"darkseagreen", darkseagreen}, {"darkslateblue", darkslateblue}, {"darkslategray", darkslategray}, {"darkturquoise", darkturquoise}, {"darkviolet", darkviolet}, {"deeppink", deeppink}, {"deepskyblue", deepskyblue}, {"dimgray", dimgray}, {"dodgerblue", dodgerblue}, {"firebrick", firebrick}, {"floralwhite", floralwhite}, {"forestgreen", forestgreen}, {"fuchsia", fuchsia}, {"gainsboro", gainsboro}, {"ghostwhite", ghostwhite}, {"gold", gold}, {"goldenrod", goldenrod}, {"gray", gray}, {"green", green}, {"greenyellow", greenyellow}, {"honeydew", honeydew}, {"hotpink", hotpink}, {"indianred", indianred}, {"indigo", indigo}, {"ivory", ivory}, {"khaki", khaki}, {"lavender", lavender}, {"lavenderblush", lavenderblush}, {"lawngreen", lawngreen}, {"lemonchiffon", lemonchiffon}, {"lightblue", lightblue}, {"lightcoral", lightcoral}, {"lightcyan", lightcyan}, {"lightgoldenrodyellow", lightgoldenrodyellow}, {"lightgreen", lightgreen}, {"lightgrey", lightgrey}, {"lightpink", lightpink}, {"lightsalmon", lightsalmon}, {"lightseagreen", lightseagreen}, {"lightskyblue", lightskyblue}, {"lightslategray", lightslategray}, {"lightsteelblue", lightsteelblue}, {"lightyellow", lightyellow}, {"lime", lime}, {"limegreen", limegreen}, {"linen", linen}, {"magenta", magenta}, {"maroon", maroon}, {"mediumaquamarine", mediumaquamarine}, {"mediumblue", mediumblue}, {"mediumorchid", mediumorchid}, {"mediumpurple", mediumpurple}, {"mediumseagreen", mediumseagreen}, {"mediumslateblue", mediumslateblue}, {"mediumspringgreen", mediumspringgreen}, {"mediumturquoise", mediumturquoise}, {"mediumvioletred", mediumvioletred}, {"midnightblue", midnightblue}, {"mintcream", mintcream}, {"mistyrose", mistyrose}, {"moccasin", mocassin}, {"navajowhite", navajowhite}, {"navy", navy}, {"oldlace", oldlace}, {"olive", olive}, {"olivedrab", olivedrab}, {"orange", orange}, {"orangered", orangered}, {"orchid", orchid}, {"palegoldenrod", palegoldenrod}, {"palegreen", palegreen}, {"paleturquoise", paleturquoise}, {"palevioletred", palevioletred}, {"papayawhip", papayawhip}, {"peachpuff", peachpuff}, {"peru", peru}, {"pink", pink}, {"plum", plum}, {"powderblue", powderblue}, {"purple", purple}, {"red", red}, {"rosybrown", rosybrown}, {"royalblue", royalblue}, {"saddlebrown", saddlebrown}, {"salmon", salmon}, {"sandybrown", sandybrown}, {"seagreen", seagreen}, {"seashell", seashell}, {"sienna", sienna}, {"silver", silver}, {"skyblue", skyblue}, {"slateblue", slateblue}, {"slategray", slategray}, {"snow", snow}, {"springgreen", springgreen}, {"steelblue", steelblue}, {"tan", tan}, {"teal", teal}, {"thistle", thistle}, {"tomato", tomato}, {"turquoise", turquoise}, {"violet", violet}, {"wheat", wheat}, {"white", white}, {"whitesmoke", whitesmoke}, {"yellow", yellow}, {"yellowgreen", yellowgreen}, }; public static HashMap getColors() { return _colors; } public static Color findColor( String key ) { return ( Color ) _colors.get( key ); } static { _colors = new HashMap(); for( int i = 0; i < data.length; i++ ) { Object row[] = data[i]; _colors.put( row[0], row[1] ); } }
}
</source>
An efficient color quantization algorithm
<source lang="java"> /*
* @(#)Quantize.java 0.90 9/19/00 Adam Doppelt */
/**
* An efficient color quantization algorithm, adapted from the C++ * implementation quantize.c in */
public class Quantize { /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % QQQ U U AAA N N TTTTT IIIII ZZZZZ EEEEE % % Q Q U U A A NN N T I ZZ E % % Q Q U U AAAAA N N N T I ZZZ EEEEE % % Q QQ U U A A N NN T I ZZ E % % QQQQ UUU A A N N T IIIII ZZZZZ EEEEE % % % % % % Reduce the Number of Unique Colors in an Image % % % % % % Software Design % % John Cristy % % July 1992 % % % % % % Copyright 1998 E. I. du Pont de Nemours and Company % % % % Permission is hereby granted, free of charge, to any person obtaining a % % copy of this software and associated documentation files ("ImageMagick"), % % to deal in ImageMagick without restriction, including without limitation % % the rights to use, copy, modify, merge, publish, distribute, sublicense, % % and/or sell copies of ImageMagick, and to permit persons to whom the % % ImageMagick is furnished to do so, subject to the following conditions: % % % % The above copyright notice and this permission notice shall be included in % % all copies or substantial portions of ImageMagick. % % % % The software is provided "as is", without warranty of any kind, express or % % implied, including but not limited to the warranties of merchantability, % % fitness for a particular purpose and noninfringement. In no event shall % % E. I. du Pont de Nemours and Company be liable for any claim, damages or % % other liability, whether in an action of contract, tort or otherwise, % % arising from, out of or in connection with ImageMagick or the use or other % % dealings in ImageMagick. % % % % Except as contained in this notice, the name of the E. I. du Pont de % % Nemours and Company shall not be used in advertising or otherwise to % % promote the sale, use or other dealings in ImageMagick without prior % % written authorization from the E. I. du Pont de Nemours and Company. % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Realism in computer graphics typically requires using 24 bits/pixel to % generate an image. Yet many graphic display devices do not contain % the amount of memory necessary to match the spatial and color % resolution of the human eye. The QUANTIZE program takes a 24 bit % image and reduces the number of colors so it can be displayed on % raster device with less bits per pixel. In most instances, the % quantized image closely resembles the original reference image. % % A reduction of colors in an image is also desirable for image % transmission and real-time animation. % % Function Quantize takes a standard RGB or monochrome images and quantizes % them down to some fixed number of colors. % % For purposes of color allocation, an image is a set of n pixels, where % each pixel is a point in RGB space. RGB space is a 3-dimensional % vector space, and each pixel, pi, is defined by an ordered triple of % red, green, and blue coordinates, (ri, gi, bi). % % Each primary color component (red, green, or blue) represents an % intensity which varies linearly from 0 to a maximum value, cmax, which % corresponds to full saturation of that color. Color allocation is % defined over a domain consisting of the cube in RGB space with % opposite vertices at (0,0,0) and (cmax,cmax,cmax). QUANTIZE requires % cmax = 255. % % The algorithm maps this domain onto a tree in which each node % represents a cube within that domain. In the following discussion % these cubes are defined by the coordinate of two opposite vertices: % The vertex nearest the origin in RGB space and the vertex farthest % from the origin. % % The tree"s root node represents the the entire domain, (0,0,0) through % (cmax,cmax,cmax). Each lower level in the tree is generated by % subdividing one node"s cube into eight smaller cubes of equal size. % This corresponds to bisecting the parent cube with planes passing % through the midpoints of each edge. % % The basic algorithm operates in three phases: Classification, % Reduction, and Assignment. Classification builds a color % description tree for the image. Reduction collapses the tree until % the number it represents, at most, the number of colors desired in the % output image. Assignment defines the output image"s color map and % sets each pixel"s color by reclassification in the reduced tree. % Our goal is to minimize the numerical discrepancies between the original % colors and quantized colors (quantization error). % % Classification begins by initializing a color description tree of % sufficient depth to represent each possible input color in a leaf. % However, it is impractical to generate a fully-formed color % description tree in the classification phase for realistic values of % cmax. If colors components in the input image are quantized to k-bit % precision, so that cmax= 2k-1, the tree would need k levels below the % root node to allow representing each possible input color in a leaf. % This becomes prohibitive because the tree"s total number of nodes is % 1 + sum(i=1,k,8k). % % A complete tree would require 19,173,961 nodes for k = 8, cmax = 255. % Therefore, to avoid building a fully populated tree, QUANTIZE: (1) % Initializes data structures for nodes only as they are needed; (2) % Chooses a maximum depth for the tree as a function of the desired % number of colors in the output image (currently log2(colormap size)). % % For each pixel in the input image, classification scans downward from % the root of the color description tree. At each level of the tree it % identifies the single node which represents a cube in RGB space % containing the pixel"s color. It updates the following data for each % such node: % % n1: Number of pixels whose color is contained in the RGB cube % which this node represents; % % n2: Number of pixels whose color is not represented in a node at % lower depth in the tree; initially, n2 = 0 for all nodes except % leaves of the tree. % % Sr, Sg, Sb: Sums of the red, green, and blue component values for % all pixels not classified at a lower depth. The combination of % these sums and n2 will ultimately characterize the mean color of a % set of pixels represented by this node. % % E: The distance squared in RGB space between each pixel contained % within a node and the nodes" center. This represents the quantization % error for a node. % % Reduction repeatedly prunes the tree until the number of nodes with % n2 > 0 is less than or equal to the maximum number of colors allowed % in the output image. On any given iteration over the tree, it selects % those nodes whose E count is minimal for pruning and merges their % color statistics upward. It uses a pruning threshold, Ep, to govern % node selection as follows: % % Ep = 0 % while number of nodes with (n2 > 0) > required maximum number of colors % prune all nodes such that E <= Ep % Set Ep to minimum E in remaining nodes % % This has the effect of minimizing any quantization error when merging % two nodes together. % % When a node to be pruned has offspring, the pruning procedure invokes % itself recursively in order to prune the tree from the leaves upward. % n2, Sr, Sg, and Sb in a node being pruned are always added to the % corresponding data in that node"s parent. This retains the pruned % node"s color characteristics for later averaging. % % For each node, n2 pixels exist for which that node represents the % smallest volume in RGB space containing those pixel"s colors. When n2 % > 0 the node will uniquely define a color in the output image. At the % beginning of reduction, n2 = 0 for all nodes except a the leaves of % the tree which represent colors present in the input image. % % The other pixel count, n1, indicates the total number of colors % within the cubic volume which the node represents. This includes n1 - % n2 pixels whose colors should be defined by nodes at a lower level in % the tree. % % Assignment generates the output image from the pruned tree. The % output image consists of two parts: (1) A color map, which is an % array of color descriptions (RGB triples) for each color present in % the output image; (2) A pixel array, which represents each pixel as % an index into the color map array. % % First, the assignment phase makes one pass over the pruned color % description tree to establish the image"s color map. For each node % with n2 > 0, it divides Sr, Sg, and Sb by n2 . This produces the % mean color of all pixels that classify no lower than this node. Each % of these colors becomes an entry in the color map. % % Finally, the assignment phase reclassifies each pixel in the pruned % tree to identify the deepest node containing the pixel"s color. The % pixel"s value in the pixel array becomes the index of this node"s mean % color in the color map. % % With the permission of USC Information Sciences Institute, 4676 Admiralty % Way, Marina del Rey, California 90292, this code was adapted from module % ALCOLS written by Paul Raveling. % % The names of ISI and USC are not used in advertising or publicity % pertaining to distribution of the software without prior specific % written permission from ISI. %
- /
final static boolean QUICK = true; final static int MAX_RGB = 255; final static int MAX_NODES = 266817; final static int MAX_TREE_DEPTH = 8; // these are precomputed in advance static int SQUARES[]; static int SHIFT[]; static { SQUARES = new int[MAX_RGB + MAX_RGB + 1]; for (int i= -MAX_RGB; i <= MAX_RGB; i++) { SQUARES[i + MAX_RGB] = i * i; } SHIFT = new int[MAX_TREE_DEPTH + 1]; for (int i = 0; i < MAX_TREE_DEPTH + 1; ++i) { SHIFT[i] = 1 << (15 - i); } }
/** * Reduce the image to the given number of colors. The pixels are * reduced in place. * @return The new color palette. */ public static int[] quantizeImage(int pixels[][], int max_colors) { Cube cube = new Cube(pixels, max_colors); cube.classification(); cube.reduction(); cube.assignment(); return cube.colormap; } static class Cube { int pixels[][]; int max_colors; int colormap[]; Node root; int depth; // counter for the number of colors in the cube. this gets // recalculated often. int colors; // counter for the number of nodes in the tree int nodes; Cube(int pixels[][], int max_colors) { this.pixels = pixels; this.max_colors = max_colors; int i = max_colors; // tree_depth = log max_colors // 4 for (depth = 1; i != 0; depth++) { i /= 4; } if (depth > 1) { --depth; } if (depth > MAX_TREE_DEPTH) { depth = MAX_TREE_DEPTH; } else if (depth < 2) { depth = 2; } root = new Node(this); } /* * Procedure Classification begins by initializing a color * description tree of sufficient depth to represent each * possible input color in a leaf. However, it is impractical * to generate a fully-formed color description tree in the * classification phase for realistic values of cmax. If * colors components in the input image are quantized to k-bit * precision, so that cmax= 2k-1, the tree would need k levels * below the root node to allow representing each possible * input color in a leaf. This becomes prohibitive because the * tree"s total number of nodes is 1 + sum(i=1,k,8k). * * A complete tree would require 19,173,961 nodes for k = 8, * cmax = 255. Therefore, to avoid building a fully populated * tree, QUANTIZE: (1) Initializes data structures for nodes * only as they are needed; (2) Chooses a maximum depth for * the tree as a function of the desired number of colors in * the output image (currently log2(colormap size)). * * For each pixel in the input image, classification scans * downward from the root of the color description tree. At * each level of the tree it identifies the single node which * represents a cube in RGB space containing It updates the * following data for each such node: * * number_pixels : Number of pixels whose color is contained * in the RGB cube which this node represents; * * unique : Number of pixels whose color is not represented * in a node at lower depth in the tree; initially, n2 = 0 * for all nodes except leaves of the tree. * * total_red/green/blue : Sums of the red, green, and blue * component values for all pixels not classified at a lower * depth. The combination of these sums and n2 will * ultimately characterize the mean color of a set of pixels * represented by this node. */ void classification() { int pixels[][] = this.pixels; int width = pixels.length; int height = pixels[0].length; // convert to indexed color for (int x = width; x-- > 0; ) { for (int y = height; y-- > 0; ) { int pixel = pixels[x][y]; int red = (pixel >> 16) & 0xFF; int green = (pixel >> 8) & 0xFF; int blue = (pixel >> 0) & 0xFF; // a hard limit on the number of nodes in the tree if (nodes > MAX_NODES) { System.out.println("pruning"); root.pruneLevel(); --depth; } // walk the tree to depth, increasing the // number_pixels count for each node Node node = root; for (int level = 1; level <= depth; ++level) { int id = (((red > node.mid_red ? 1 : 0) << 0) | ((green > node.mid_green ? 1 : 0) << 1) | ((blue > node.mid_blue ? 1 : 0) << 2)); if (node.child[id] == null) { new Node(node, id, level); } node = node.child[id]; node.number_pixels += SHIFT[level]; } ++node.unique; node.total_red += red; node.total_green += green; node.total_blue += blue; } } } /* * reduction repeatedly prunes the tree until the number of * nodes with unique > 0 is less than or equal to the maximum * number of colors allowed in the output image. * * When a node to be pruned has offspring, the pruning * procedure invokes itself recursively in order to prune the * tree from the leaves upward. The statistics of the node * being pruned are always added to the corresponding data in * that node"s parent. This retains the pruned node"s color * characteristics for later averaging. */ void reduction() { int threshold = 1; while (colors > max_colors) { colors = 0; threshold = root.reduce(threshold, Integer.MAX_VALUE); } } /** * The result of a closest color search. */ static class Search { int distance; int color_number; } /* * Procedure assignment generates the output image from the * pruned tree. The output image consists of two parts: (1) A * color map, which is an array of color descriptions (RGB * triples) for each color present in the output image; (2) A * pixel array, which represents each pixel as an index into * the color map array. * * First, the assignment phase makes one pass over the pruned * color description tree to establish the image"s color map. * For each node with n2 > 0, it divides Sr, Sg, and Sb by n2. * This produces the mean color of all pixels that classify no * lower than this node. Each of these colors becomes an entry * in the color map. * * Finally, the assignment phase reclassifies each pixel in * the pruned tree to identify the deepest node containing the * pixel"s color. The pixel"s value in the pixel array becomes * the index of this node"s mean color in the color map. */ void assignment() { colormap = new int[colors]; colors = 0; root.colormap(); int pixels[][] = this.pixels; int width = pixels.length; int height = pixels[0].length; Search search = new Search(); // convert to indexed color for (int x = width; x-- > 0; ) { for (int y = height; y-- > 0; ) { int pixel = pixels[x][y]; int red = (pixel >> 16) & 0xFF; int green = (pixel >> 8) & 0xFF; int blue = (pixel >> 0) & 0xFF; // walk the tree to find the cube containing that color Node node = root; for ( ; ; ) { int id = (((red > node.mid_red ? 1 : 0) << 0) | ((green > node.mid_green ? 1 : 0) << 1) | ((blue > node.mid_blue ? 1 : 0) << 2) ); if (node.child[id] == null) { break; } node = node.child[id]; } if (QUICK) { // if QUICK is set, just use that // node. Strictly speaking, this isn"t // necessarily best match. pixels[x][y] = node.color_number; } else { // Find the closest color. search.distance = Integer.MAX_VALUE; node.parent.closestColor(red, green, blue, search); pixels[x][y] = search.color_number; } } } } /** * A single Node in the tree. */ static class Node { Cube cube; // parent node Node parent; // child nodes Node child[]; int nchild; // our index within our parent int id; // our level within the tree int level; // our color midpoint int mid_red; int mid_green; int mid_blue; // the pixel count for this node and all children int number_pixels; // the pixel count for this node int unique; // the sum of all pixels contained in this node int total_red; int total_green; int total_blue; // used to build the colormap int color_number; Node(Cube cube) { this.cube = cube; this.parent = this; this.child = new Node[8]; this.id = 0; this.level = 0; this.number_pixels = Integer.MAX_VALUE; this.mid_red = (MAX_RGB + 1) >> 1; this.mid_green = (MAX_RGB + 1) >> 1; this.mid_blue = (MAX_RGB + 1) >> 1; } Node(Node parent, int id, int level) { this.cube = parent.cube; this.parent = parent; this.child = new Node[8]; this.id = id; this.level = level; // add to the cube ++cube.nodes; if (level == cube.depth) { ++cube.colors; } // add to the parent ++parent.nchild; parent.child[id] = this; // figure out our midpoint int bi = (1 << (MAX_TREE_DEPTH - level)) >> 1; mid_red = parent.mid_red + ((id & 1) > 0 ? bi : -bi); mid_green = parent.mid_green + ((id & 2) > 0 ? bi : -bi); mid_blue = parent.mid_blue + ((id & 4) > 0 ? bi : -bi); } /** * Remove this child node, and make sure our parent * absorbs our pixel statistics. */ void pruneChild() { --parent.nchild; parent.unique += unique; parent.total_red += total_red; parent.total_green += total_green; parent.total_blue += total_blue; parent.child[id] = null; --cube.nodes; cube = null; parent = null; } /** * Prune the lowest layer of the tree. */ void pruneLevel() { if (nchild != 0) { for (int id = 0; id < 8; id++) { if (child[id] != null) { child[id].pruneLevel(); } } } if (level == cube.depth) { pruneChild(); } } /** * Remove any nodes that have fewer than threshold * pixels. Also, as long as we"re walking the tree: * * - figure out the color with the fewest pixels * - recalculate the total number of colors in the tree */ int reduce(int threshold, int next_threshold) { if (nchild != 0) { for (int id = 0; id < 8; id++) { if (child[id] != null) { next_threshold = child[id].reduce(threshold, next_threshold); } } } if (number_pixels <= threshold) { pruneChild(); } else { if (unique != 0) { cube.colors++; } if (number_pixels < next_threshold) { next_threshold = number_pixels; } } return next_threshold; } /* * colormap traverses the color cube tree and notes each * colormap entry. A colormap entry is any node in the * color cube tree where the number of unique colors is * not zero. */ void colormap() { if (nchild != 0) { for (int id = 0; id < 8; id++) { if (child[id] != null) { child[id].colormap(); } } } if (unique != 0) { int r = ((total_red + (unique >> 1)) / unique); int g = ((total_green + (unique >> 1)) / unique); int b = ((total_blue + (unique >> 1)) / unique); cube.colormap[cube.colors] = ((( 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF) << 0)); color_number = cube.colors++; } } /* ClosestColor traverses the color cube tree at a * particular node and determines which colormap entry * best represents the input color. */ void closestColor(int red, int green, int blue, Search search) { if (nchild != 0) { for (int id = 0; id < 8; id++) { if (child[id] != null) { child[id].closestColor(red, green, blue, search); } } } if (unique != 0) { int color = cube.colormap[color_number]; int distance = distance(color, red, green, blue); if (distance < search.distance) { search.distance = distance; search.color_number = color_number; } } } /** * Figure out the distance between this node and som color. */ final static int distance(int color, int r, int g, int b) { return (SQUARES[((color >> 16) & 0xFF) - r + MAX_RGB] + SQUARES[((color >> 8) & 0xFF) - g + MAX_RGB] + SQUARES[((color >> 0) & 0xFF) - b + MAX_RGB]); } public String toString() { StringBuffer buf = new StringBuffer(); if (parent == this) { buf.append("root"); } else { buf.append("node"); } buf.append(" "); buf.append(level); buf.append(" ["); buf.append(mid_red); buf.append(","); buf.append(mid_green); buf.append(","); buf.append(mid_blue); buf.append("]"); return new String(buf); } } }
}
</source>
Color class is used to work with colors in Java 2D
<source lang="java"> import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JFrame; import javax.swing.JPanel; public class Colors extends JPanel {
public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(new Color(12, 16, 116)); g2d.fillRect(10, 15, 90, 60); g2d.setColor(new Color(42, 19, 31)); g2d.fillRect(130, 15, 90, 60); g2d.setColor(new Color(70, 7, 23)); g2d.fillRect(250, 15, 90, 60); g2d.setColor(new Color(10, 10, 84)); g2d.fillRect(10, 105, 90, 60); g2d.setColor(new Color(22, 21, 61)); g2d.fillRect(130, 105, 90, 60); g2d.setColor(new Color(21, 98, 69)); g2d.fillRect(250, 105, 90, 60); g2d.setColor(new Color(217, 146, 54)); g2d.fillRect(10, 195, 90, 60); g2d.setColor(new Color(63, 121, 186)); g2d.fillRect(130, 195, 90, 60); g2d.setColor(new Color(131, 121, 11)); g2d.fillRect(250, 195, 90, 60); } public static void main(String[] args) { JFrame frame = new JFrame("Colors"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new Colors()); frame.setSize(360, 300); frame.setLocationRelativeTo(null); frame.setVisible(true); }
}
</source>
Color Difference
<source lang="java">
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
/*
* ColorDifference.java * * Created on May 3, 2007, 7:12 AM * * Copyright (c) 2007, Sun Microsystems, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the TimingFramework project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/**
* * @author Chet */
public class ColorDifference extends JComponent implements ActionListener {
private Color largeRectColors[] = { Color.BLACK, new Color(3, 3, 3) }; private Color smallRectColors[] = { Color.BLACK, Color.WHITE }; private int colorIndex = 0; private static int FADE_X = 0; private static int BLANK_X = 0; /** Creates a new instance of ColorDifference */ public ColorDifference() { Timer timer = new Timer(1000, this); timer.start(); setPreferredSize(new Dimension(300, 200)); } /** * Displays our component with the animating colors of the areas on the left * and right, separated by an area of white in the middle */ @Override protected void paintComponent(Graphics g) { int fadeX = 0; int blankX = getWidth() / 3; int bigRectW = getWidth() / 3; // Fill left-side rectangle with current animating color g.setColor(largeRectColors[colorIndex]); g.fillRect(0, 0, bigRectW, getHeight()); // Fill middle area with white g.setColor(Color.WHITE); g.fillRect(bigRectW, 0, bigRectW, getHeight()); // Fill right-side rectangle with black, with a white square // in the middle int bigRectX = 2 * bigRectW; int smallRectW = 4; int smallRectH = 4; int smallRectX = bigRectX + (bigRectW / 2) - (smallRectW / 2); int smallRectY = (getHeight() / 2) - (smallRectH / 2); g.setColor(Color.BLACK); g.fillRect(2 * getWidth() / 3, 0, getWidth() / 3, getHeight()); g.setColor(smallRectColors[colorIndex]); g.fillRect(smallRectX, smallRectY, smallRectW, smallRectH); } /** * Handles Timer events by toggling the colorIndex used to fill the left-side * rectangle */ public void actionPerformed(ActionEvent ae) { colorIndex++; colorIndex = colorIndex % 2; repaint(); } private static void createAndShowGUI() { JFrame f = new JFrame("Color Difference"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(300, 200); ColorDifference component = new ColorDifference(); f.add(component); f.pack(); f.setVisible(true); } /** * @param args * the command line arguments */ public static void main(String[] args) { Runnable doCreateAndShowGUI = new Runnable() { public void run() { createAndShowGUI(); } }; SwingUtilities.invokeLater(doCreateAndShowGUI); }
}
</source>
Color Factory
<source lang="java"> /*
GNU LESSER GENERAL PUBLIC LICENSE Copyright (C) 2006 The Lobo Project This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Contact info: lobochief@users.sourceforge.net
- /
/*
* Created on Apr 17, 2005 */
import java.util.*; import java.util.logging.*; import java.awt.*; /**
* @author J. H. S. */
public class ColorFactory {
private static final Logger logger = Logger.getLogger(ColorFactory.class.getName()); public static final Color TRANSPARENT = new Color(0, 0, 0, 0); private static ColorFactory instance; private final Map colorMap = new HashMap(256); private ColorFactory() { Map colorMap = this.colorMap; synchronized(this) { colorMap.put("transparent", TRANSPARENT); //http://www.w3schools.ru/css/css_colornames.asp colorMap.put("aliceblue", new Color(0xf0f8ff)); colorMap.put("antiquewhite", new Color(0xfaebd7)); colorMap.put("aqua", new Color(0x00ffff)); colorMap.put("aquamarine", new Color(0x7fffd4)); colorMap.put("azure", new Color(0xf0ffff)); colorMap.put("beige", new Color(0xf5f5dc)); colorMap.put("bisque", new Color(0xffe4c4)); colorMap.put("black", new Color(0x000000)); colorMap.put("blanchedalmond", new Color(0xffebcd)); colorMap.put("blue", new Color(0x0000ff)); colorMap.put("blueviolet", new Color(0x8a2be2)); colorMap.put("brown", new Color(0xa52a2a)); colorMap.put("burlywood", new Color(0xdeb887)); colorMap.put("cadetblue", new Color(0x5f9ea0)); colorMap.put("chartreuse", new Color(0x7fff00)); colorMap.put("chocolate", new Color(0xd2691e)); colorMap.put("coral", new Color(0xff7f50)); colorMap.put("cornflowerblue", new Color(0x6495ed)); colorMap.put("cornsilk", new Color(0xfff8dc)); colorMap.put("crimson", new Color(0xdc143c)); colorMap.put("cyan", new Color(0x00ffff)); colorMap.put("darkblue", new Color(0x00008b)); colorMap.put("darkcyan", new Color(0x008b8b)); colorMap.put("darkgoldenrod", new Color(0xb8860b)); colorMap.put("darkgray", new Color(0xa9a9a9)); colorMap.put("darkgrey", new Color(0xa9a9a9)); colorMap.put("darkgreen", new Color(0x006400)); colorMap.put("darkkhaki", new Color(0xbdb76b)); colorMap.put("darkmagenta", new Color(0x8b008b)); colorMap.put("darkolivegreen", new Color(0x556b2f)); colorMap.put("darkorange", new Color(0xff8c00)); colorMap.put("darkorchid", new Color(0x9932cc)); colorMap.put("darkred", new Color(0x8b0000)); colorMap.put("darksalmon", new Color(0xe9967a)); colorMap.put("darkseagreen", new Color(0x8fbc8f)); colorMap.put("darkslateblue", new Color(0x483d8b)); colorMap.put("darkslategray", new Color(0x2f4f4f)); colorMap.put("darkslategrey", new Color(0x2f4f4f)); colorMap.put("darkturquoise", new Color(0x00ced1)); colorMap.put("darkviolet", new Color(0x9400d3)); colorMap.put("deeppink", new Color(0xff1493)); colorMap.put("deepskyblue", new Color(0x00bfff)); colorMap.put("dimgray", new Color(0x696969)); colorMap.put("dimgrey", new Color(0x696969)); colorMap.put("dodgerblue", new Color(0x1e90ff)); colorMap.put("firebrick", new Color(0xb22222)); colorMap.put("floralwhite", new Color(0xfffaf0)); colorMap.put("forestgreen", new Color(0x228b22)); colorMap.put("fuchsia", new Color(0xff00ff)); colorMap.put("gainsboro", new Color(0xdcdcdc)); colorMap.put("ghostwhite", new Color(0xf8f8ff)); colorMap.put("gold", new Color(0xffd700)); colorMap.put("goldenrod", new Color(0xdaa520)); colorMap.put("gray", new Color(0x808080)); colorMap.put("grey", new Color(0x808080)); colorMap.put("green", new Color(0x008000)); colorMap.put("greenyellow", new Color(0xadff2f)); colorMap.put("honeydew", new Color(0xf0fff0)); colorMap.put("hotpink", new Color(0xff69b4)); colorMap.put("indianred", new Color(0xcd5c5c)); colorMap.put("indigo", new Color(0x4b0082)); colorMap.put("ivory", new Color(0xfffff0)); colorMap.put("khaki", new Color(0xf0e68c)); colorMap.put("lavender", new Color(0xe6e6fa)); colorMap.put("lavenderblush", new Color(0xfff0f5)); colorMap.put("lawngreen", new Color(0x7cfc00)); colorMap.put("lemonchiffon", new Color(0xfffacd)); colorMap.put("lightblue", new Color(0xadd8e6)); colorMap.put("lightcoral", new Color(0xf08080)); colorMap.put("lightcyan", new Color(0xe0ffff)); colorMap.put("lightgoldenrodyellow", new Color(0xfafad2)); colorMap.put("lightgray", new Color(0xd3d3d3)); colorMap.put("lightgrey", new Color(0xd3d3d3)); colorMap.put("lightgreen", new Color(0x90ee90)); colorMap.put("lightpink", new Color(0xffb6c1)); colorMap.put("lightsalmon", new Color(0xffa07a)); colorMap.put("lightseagreen", new Color(0x20b2aa)); colorMap.put("lightskyblue", new Color(0x87cefa)); colorMap.put("lightslategray", new Color(0x778899)); colorMap.put("lightslategrey", new Color(0x778899)); colorMap.put("lightsteelblue", new Color(0xb0c4de)); colorMap.put("lightyellow", new Color(0xffffe0)); colorMap.put("lime", new Color(0x00ff00)); colorMap.put("limegreen", new Color(0x32cd32)); colorMap.put("linen", new Color(0xfaf0e6)); colorMap.put("magenta", new Color(0xff00ff)); colorMap.put("maroon", new Color(0x800000)); colorMap.put("mediumaquamarine", new Color(0x66cdaa)); colorMap.put("mediumblue", new Color(0x0000cd)); colorMap.put("mediumorchid", new Color(0xba55d3)); colorMap.put("mediumpurple", new Color(0x9370d8)); colorMap.put("mediumseagreen", new Color(0x3cb371)); colorMap.put("mediumslateblue", new Color(0x7b68ee)); colorMap.put("mediumspringgreen", new Color(0x00fa9a)); colorMap.put("mediumturquoise", new Color(0x48d1cc)); colorMap.put("mediumvioletred", new Color(0xc71585)); colorMap.put("midnightblue", new Color(0x191970)); colorMap.put("mintcream", new Color(0xf5fffa)); colorMap.put("mistyrose", new Color(0xffe4e1)); colorMap.put("moccasin", new Color(0xffe4b5)); colorMap.put("navajowhite", new Color(0xffdead)); colorMap.put("navy", new Color(0x000080)); colorMap.put("oldlace", new Color(0xfdf5e6)); colorMap.put("olive", new Color(0x808000)); colorMap.put("olivedrab", new Color(0x6b8e23)); colorMap.put("orange", new Color(0xffa500)); colorMap.put("orangered", new Color(0xff4500)); colorMap.put("orchid", new Color(0xda70d6)); colorMap.put("palegoldenrod", new Color(0xeee8aa)); colorMap.put("palegreen", new Color(0x98fb98)); colorMap.put("paleturquoise", new Color(0xafeeee)); colorMap.put("palevioletred", new Color(0xd87093)); colorMap.put("papayawhip", new Color(0xffefd5)); colorMap.put("peachpuff", new Color(0xffdab9)); colorMap.put("peru", new Color(0xcd853f)); colorMap.put("pink", new Color(0xffc0cb)); colorMap.put("plum", new Color(0xdda0dd)); colorMap.put("powderblue", new Color(0xb0e0e6)); colorMap.put("purple", new Color(0x800080)); colorMap.put("red", new Color(0xff0000)); colorMap.put("rosybrown", new Color(0xbc8f8f)); colorMap.put("royalblue", new Color(0x4169e1)); colorMap.put("saddlebrown", new Color(0x8b4513)); colorMap.put("salmon", new Color(0xfa8072)); colorMap.put("sandybrown", new Color(0xf4a460)); colorMap.put("seagreen", new Color(0x2e8b57)); colorMap.put("seashell", new Color(0xfff5ee)); colorMap.put("sienna", new Color(0xa0522d)); colorMap.put("silver", new Color(0xc0c0c0)); colorMap.put("skyblue", new Color(0x87ceeb)); colorMap.put("slateblue", new Color(0x6a5acd)); colorMap.put("slategray", new Color(0x708090)); colorMap.put("slategrey", new Color(0x708090)); colorMap.put("snow", new Color(0xfffafa)); colorMap.put("springgreen", new Color(0x00ff7f)); colorMap.put("steelblue", new Color(0x4682b4)); colorMap.put("tan", new Color(0xd2b48c)); colorMap.put("teal", new Color(0x008080)); colorMap.put("thistle", new Color(0xd8bfd8)); colorMap.put("tomato", new Color(0xff6347)); colorMap.put("turquoise", new Color(0x40e0d0)); colorMap.put("violet", new Color(0xee82ee)); colorMap.put("wheat", new Color(0xf5deb3)); colorMap.put("white", new Color(0xffffff)); colorMap.put("whitesmoke", new Color(0xf5f5f5)); colorMap.put("yellow", new Color(0xffff00)); colorMap.put("yellowgreen", new Color(0x9acd32)); } } public static final ColorFactory getInstance() { if(instance == null) { synchronized(ColorFactory.class) { if(instance == null) { instance = new ColorFactory(); } } } return instance; } private static final String RGB_START = "rgb("; public boolean isColor(String colorSpec) { if(colorSpec.startsWith("#")) { return true; } String normalSpec = colorSpec.toLowerCase(); if(normalSpec.startsWith(RGB_START)) { return true; } synchronized(this) { return colorMap.containsKey(normalSpec); } } public Color getColor(String colorSpec) { String normalSpec = colorSpec.toLowerCase(); synchronized(this) { Color color = (Color) colorMap.get(normalSpec); if(color == null) { if(normalSpec.startsWith(RGB_START)) { // CssParser produces this format. int endIdx = normalSpec.lastIndexOf(")"); String commaValues = endIdx == -1 ? normalSpec.substring(RGB_START.length()) : normalSpec.substring(RGB_START.length(), endIdx); StringTokenizer tok = new StringTokenizer(commaValues, ","); int r = 0, g = 0, b = 0; if(tok.hasMoreTokens()) { String rstr = tok.nextToken().trim(); try { r = Integer.parseInt(rstr); } catch(NumberFormatException nfe) { // ignore } if(tok.hasMoreTokens()) { String gstr = tok.nextToken().trim(); try { g = Integer.parseInt(gstr); } catch(NumberFormatException nfe) { // ignore } if(tok.hasMoreTokens()) { String bstr = tok.nextToken().trim(); try { b = Integer.parseInt(bstr); } catch(NumberFormatException nfe) { // ignore } } } } color = new Color(r, g, b); } else if(normalSpec.startsWith("#")) { //TODO: OPTIMIZE: It would be more efficient to //create new Color(hex), but CssParser doesn"t //give us values formatted with "#" either way. int len = normalSpec.length(); int[] rgba = new int[4]; rgba[3] = 255; for(int i = 0; i < rgba.length; i++) { int idx = 2 * i + 1; if(idx < len) { String hexText = normalSpec.substring(idx, idx + Math.min(2, len - idx)); try { rgba[i] = Integer.parseInt(hexText, 16); } catch(NumberFormatException nfe) { // Ignore } } } color = new Color(rgba[0], rgba[1], rgba[2], rgba[3]); } else { if(logger.isLoggable(Level.INFO)) { logger.warning("getColor(): Color spec [" + normalSpec + "] unknown."); } return Color.RED; } colorMap.put(normalSpec, color); } return color; } }
}
</source>
Color fading animation
<source lang="java"> import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.Rectangle2D; import javax.swing.JFrame; import javax.swing.JPanel; public class ColorFadingAnimation extends JPanel {
private Rectangle2D rect = new Rectangle2D.Float(20f, 20f, 80f, 50f); private float alpha_rectangle = 1f; public ColorFadingAnimation() { new RectRunnable(); } public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(new Color(50, 50, 50)); RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2d.setRenderingHints(rh); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha_rectangle)); g2d.fill(rect); } public static void main(String[] args) { JFrame frame = new JFrame("Color fading aniamtion"); frame.add(new ColorFadingAnimation()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(250, 150); frame.setLocationRelativeTo(null); frame.setVisible(true); } class RectRunnable implements Runnable { private Thread runner; public RectRunnable() { runner = new Thread(this); runner.start(); } public void run() { while (alpha_rectangle >= 0) { repaint(); alpha_rectangle += -0.01f; if (alpha_rectangle < 0) { alpha_rectangle = 0; } try { Thread.sleep(50); } catch (Exception e) { } } } }
}
</source>
Color Util
<source lang="java"> /*
* Copyright (C) 2004 NNL Technology AB * Visit www.infonode.net for information about InfoNode(R) * products and how to contact NNL Technology AB. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */
// $Id: ColorUtil.java,v 1.10 2005/02/16 11:28:14 jesper Exp $
import java.awt.*; public final class ColorUtil {
private ColorUtil() { } public static Color getOpposite(Color c) { return isDark(c) ? Color.WHITE : Color.BLACK; } public static Color shade(Color c, double amount) { return blend(c, getOpposite(c), amount); } public static final Color mult(Color c, double amount) { return c == null ? null : new Color(Math.min(255, (int) (c.getRed() * amount)), Math.min(255, (int) (c.getGreen() * amount)), Math.min(255, (int) (c.getBlue() * amount)), c.getAlpha()); } public static Color setAlpha(Color c, int alpha) { return c == null ? null : new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha); } public static final Color add(Color c1, Color c2) { return c1 == null ? c2 : c2 == null ? c1 : new Color(Math.min(255, c1.getRed() + c2.getRed()), Math.min(255, c1.getGreen() + c2.getGreen()), Math.min(255, c1.getBlue() + c2.getBlue()), c1.getAlpha()); } public static Color blend(Color c1, Color c2, double v) { double v2 = 1 - v; return c1 == null ? (c2 == null ? null : c2) : c2 == null ? c1 : new Color(Math.min(255, (int) (c1.getRed() * v2 + c2.getRed() * v)), Math.min(255, (int) (c1.getGreen() * v2 + c2.getGreen() * v)), Math.min(255, (int) (c1.getBlue() * v2 + c2.getBlue() * v)), Math.min(255, (int) (c1.getAlpha() * v2 + c2.getAlpha() * v))); } public static boolean isDark(Color c) { return c.getRed() + c.getGreen() + c.getBlue() < 3 * 180; } public static Color highlight(Color c) { return mult(c, isDark(c) ? 1.5F : 0.67F); } public static Color copy(Color c) { return c == null ? null : new Color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); }
}
</source>
Color Utilities: common color operations
<source lang="java">
/* * $Id: ColorUtilities.java,v 1.1 2006/12/15 13:53:13 gfx Exp $ * * Dual-licensed under LGPL (Sun and Romain Guy) and BSD (Romain Guy). * * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, * Santa Clara, California 95054, U.S.A. All rights reserved. * * Copyright (c) 2006 Romain Guy <romain.guy@mac.ru> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS"" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/***
ColorUtilities
contains a set of tools to perform
* common color operations easily.
* * @author Romain Guy <romain.guy@mac.ru> */ class ColorUtilities { private ColorUtilities() { } /***
Returns the HSL (Hue/Saturation/Luminance) equivalent of a given * RGB color. All three HSL components are between 0.0 and 1.0.
* * @param color the RGB color to convert * @return a new array of 3 floats corresponding to the HSL components */ public static float[] RGBtoHSL(Color color) { return RGBtoHSL(color.getRed(), color.getGreen(), color.getBlue(), null); } /***
Returns the HSL (Hue/Saturation/Luminance) equivalent of a given * RGB color. All three HSL components are between 0.0 and 1.0.
* * @param color the RGB color to convert * @param hsl a pre-allocated array of floats; can be null * @return*hsl
if non-null, a new array of 3 floats otherwise * @throws IllegalArgumentException ifhsl
has a length lower * than 3 */ public static float[] RGBtoHSL(Color color, float[] hsl) { return RGBtoHSL(color.getRed(), color.getGreen(), color.getBlue(), hsl); } /**
Returns the HSL (Hue/Saturation/Luminance) equivalent of a given * RGB color. All three HSL components are between 0.0 and 1.0.
* * @param r the red component, between 0 and 255 * @param g the green component, between 0 and 255 * @param b the blue component, between 0 and 255 * @return a new array of 3 floats corresponding to the HSL components */ public static float[] RGBtoHSL(int r, int g, int b) { return RGBtoHSL(r, g, b, null); } /***
Returns the HSL (Hue/Saturation/Luminance) equivalent of a given * RGB color. All three HSL components are floats between 0.0 and 1.0.
* * @param r the red component, between 0 and 255 * @param g the green component, between 0 and 255 * @param b the blue component, between 0 and 255 * @param hsl a pre-allocated array of floats; can be null * @return*hsl
if non-null, a new array of 3 floats otherwise * @throws IllegalArgumentException ifhsl
has a length lower * than 3 */ public static float[] RGBtoHSL(int r, int g, int b, float[] hsl) { if (hsl == null) { hsl = new float[3]; } else if (hsl.length < 3) { throw new IllegalArgumentException("hsl array must have a length of" + " at least 3"); } if (r < 0) r = 0; else if (r > 255) r = 255; if (g < 0) g = 0; else if (g > 255) g = 255; if (b < 0) b = 0; else if (b > 255) b = 255; float var_R = (r / 255f); float var_G = (g / 255f); float var_B = (b / 255f); float var_Min; float var_Max; float del_Max; if (var_R > var_G) { var_Min = var_G; var_Max = var_R; } else { var_Min = var_R; var_Max = var_G; } if (var_B > var_Max) { var_Max = var_B; } if (var_B < var_Min) { var_Min = var_B; } del_Max = var_Max - var_Min; float H, S, L; L = (var_Max + var_Min) / 2f; if (del_Max - 0.01f <= 0.0f) { H = 0; S = 0; } else { if (L < 0.5f) { S = del_Max / (var_Max + var_Min); } else { S = del_Max / (2 - var_Max - var_Min); } float del_R = (((var_Max - var_R) / 6f) + (del_Max / 2f)) / del_Max; float del_G = (((var_Max - var_G) / 6f) + (del_Max / 2f)) / del_Max; float del_B = (((var_Max - var_B) / 6f) + (del_Max / 2f)) / del_Max; if (var_R == var_Max) { H = del_B - del_G; } else if (var_G == var_Max) { H = (1 / 3f) + del_R - del_B; } else { H = (2 / 3f) + del_G - del_R; } if (H < 0) { H += 1; } if (H > 1) { H -= 1; } } hsl[0] = H; hsl[1] = S; hsl[2] = L; return hsl; } /**
Returns the RGB equivalent of a given HSL (Hue/Saturation/Luminance) * color.
*
* @param h the hue component, between 0.0 and 1.0
* @param s the saturation component, between 0.0 and 1.0
* @param l the luminance component, between 0.0 and 1.0
* @return a new Color
object equivalent to the HSL components
*/
public static Color HSLtoRGB(float h, float s, float l) {
int[] rgb = HSLtoRGB(h, s, l, null);
return new Color(rgb[0], rgb[1], rgb[2]);
}
/**
* Returns the RGB equivalent of a given HSL (Hue/Saturation/Luminance) * color. All three RGB components are integers between 0 and 255.
* * @param h the hue component, between 0.0 and 1.0 * @param s the saturation component, between 0.0 and 1.0 * @param l the luminance component, between 0.0 and 1.0 * @param rgb a pre-allocated array of ints; can be null * @returnrgb
if non-null, a new array of 3 ints otherwise * @throws IllegalArgumentException ifrgb
has a length lower * than 3 */ public static int[] HSLtoRGB(float h, float s, float l, int[] rgb) { if (rgb == null) { rgb = new int[3]; } else if (rgb.length < 3) { throw new IllegalArgumentException("rgb array must have a length of" + " at least 3"); } if (h < 0) h = 0.0f; else if (h > 1.0f) h = 1.0f; if (s < 0) s = 0.0f; else if (s > 1.0f) s = 1.0f; if (l < 0) l = 0.0f; else if (l > 1.0f) l = 1.0f; int R, G, B; if (s - 0.01f <= 0.0f) { R = (int) (l * 255.0f); G = (int) (l * 255.0f); B = (int) (l * 255.0f); } else { float var_1, var_2; if (l < 0.5f) { var_2 = l * (1 + s); } else { var_2 = (l + s) - (s * l); } var_1 = 2 * l - var_2; R = (int) (255.0f * hue2RGB(var_1, var_2, h + (1.0f / 3.0f))); G = (int) (255.0f * hue2RGB(var_1, var_2, h)); B = (int) (255.0f * hue2RGB(var_1, var_2, h - (1.0f / 3.0f))); } rgb[0] = R; rgb[1] = G; rgb[2] = B; return rgb; } private static float hue2RGB(float v1, float v2, float vH) { if (vH < 0.0f) { vH += 1.0f; } if (vH > 1.0f) { vH -= 1.0f; } if ((6.0f * vH) < 1.0f) { return (v1 + (v2 - v1) * 6.0f * vH); } if ((2.0f * vH) < 1.0f) { return (v2); } if ((3.0f * vH) < 2.0f) { return (v1 + (v2 - v1) * ((2.0f / 3.0f) - vH) * 6.0f); } return (v1); } } </source>
Common color utilities
<source lang="java"> /*
* This code is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */
//package no.geosoft.cc.color.ui;
import java.awt.Color;
/**
* Common color utilities. * * @author */
public class ColorUtil {
/** * Blend two colors. * * @param color1 First color to blend. * @param color2 Second color to blend. * @param ratio Blend ratio. 0.5 will give even blend, 1.0 will return * color1, 0.0 will return color2 and so on. * @return Blended color. */ public static Color blend (Color color1, Color color2, double ratio) { float r = (float) ratio; float ir = (float) 1.0 - r; float rgb1[] = new float[3]; float rgb2[] = new float[3]; color1.getColorComponents (rgb1); color2.getColorComponents (rgb2); Color color = new Color (rgb1[0] * r + rgb2[0] * ir, rgb1[1] * r + rgb2[1] * ir, rgb1[2] * r + rgb2[2] * ir); return color; }
/** * Make an even blend between two colors. * * @param c1 First color to blend. * @param c2 Second color to blend. * @return Blended color. */ public static Color blend (Color color1, Color color2) { return ColorUtil.blend (color1, color2, 0.5); }
/** * Make a color darker. * * @param color Color to make darker. * @param fraction Darkness fraction. * @return Darker color. */ public static Color darker (Color color, double fraction) { int red = (int) Math.round (color.getRed() * (1.0 - fraction)); int green = (int) Math.round (color.getGreen() * (1.0 - fraction)); int blue = (int) Math.round (color.getBlue() * (1.0 - fraction)); if (red < 0) red = 0; else if (red > 255) red = 255; if (green < 0) green = 0; else if (green > 255) green = 255; if (blue < 0) blue = 0; else if (blue > 255) blue = 255; int alpha = color.getAlpha(); return new Color (red, green, blue, alpha); } /** * Make a color lighter. * * @param color Color to make lighter. * @param fraction Darkness fraction. * @return Lighter color. */ public static Color lighter (Color color, double fraction) { int red = (int) Math.round (color.getRed() * (1.0 + fraction)); int green = (int) Math.round (color.getGreen() * (1.0 + fraction)); int blue = (int) Math.round (color.getBlue() * (1.0 + fraction)); if (red < 0) red = 0; else if (red > 255) red = 255; if (green < 0) green = 0; else if (green > 255) green = 255; if (blue < 0) blue = 0; else if (blue > 255) blue = 255; int alpha = color.getAlpha(); return new Color (red, green, blue, alpha); }
/** * Return the hex name of a specified color. * * @param color Color to get hex name of. * @return Hex name of color: "rrggbb". */ public static String getHexName (Color color) { int r = color.getRed(); int g = color.getGreen(); int b = color.getBlue(); String rHex = Integer.toString (r, 16); String gHex = Integer.toString (g, 16); String bHex = Integer.toString (b, 16); return (rHex.length() == 2 ? "" + rHex : "0" + rHex) + (gHex.length() == 2 ? "" + gHex : "0" + gHex) + (bHex.length() == 2 ? "" + bHex : "0" + bHex); }
/** * Return the "distance" between two colors. The rgb entries are taken * to be coordinates in a 3D space [0.0-1.0], and this method returnes * the distance between the coordinates for the first and second color. * * @param r1, g1, b1 First color. * @param r2, g2, b2 Second color. * @return Distance bwetween colors. */ public static double colorDistance (double r1, double g1, double b1, double r2, double g2, double b2) { double a = r2 - r1; double b = g2 - g1; double c = b2 - b1; return Math.sqrt (a*a + b*b + c*c); } /** * Return the "distance" between two colors. * * @param color1 First color [r,g,b]. * @param color2 Second color [r,g,b]. * @return Distance bwetween colors. */ public static double colorDistance (double[] color1, double[] color2) { return ColorUtil.colorDistance (color1[0], color1[1], color1[2], color2[0], color2[1], color2[2]); }
/** * Return the "distance" between two colors. * * @param color1 First color. * @param color2 Second color. * @return Distance between colors. */ public static double colorDistance (Color color1, Color color2) { float rgb1[] = new float[3]; float rgb2[] = new float[3]; color1.getColorComponents (rgb1); color2.getColorComponents (rgb2); return ColorUtil.colorDistance (rgb1[0], rgb1[1], rgb1[2], rgb2[0], rgb2[1], rgb2[2]); }
/** * Check if a color is more dark than light. Useful if an entity of * this color is to be labeled: Use white label on a "dark" color and * black label on a "light" color. * * @param r,g,b Color to check. * @return True if this is a "dark" color, false otherwise. */ public static boolean isDark (double r, double g, double b) { // Measure distance to white and black respectively double dWhite = ColorUtil.colorDistance (r, g, b, 1.0, 1.0, 1.0); double dBlack = ColorUtil.colorDistance (r, g, b, 0.0, 0.0, 0.0); return dBlack < dWhite; }
/** * Check if a color is more dark than light. Useful if an entity of * this color is to be labeled: Use white label on a "dark" color and * black label on a "light" color. * * @param color Color to check. * @return True if this is a "dark" color, false otherwise. */ public static boolean isDark (Color color) { float r = color.getRed() / 255.0f; float g = color.getGreen() / 255.0f; float b = color.getBlue() / 255.0f; return isDark (r, g, b); }
}
</source>
Converts a given string into a color.
<source lang="java"> import java.awt.Color; import java.lang.reflect.Field; /*
* JCommon : a free general purpose class library for the Java(tm) platform * * * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. * * Project Info: http://www.jfree.org/jcommon/index.html * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. * * [Java is a trademark or registered trademark of Sun Microsystems, Inc. * in the United States and other countries.] * * ------------------- * PaintUtilities.java * ------------------- * (C) Copyright 2003-2005, by Object Refinery Limited. * * Original Author: David Gilbert (for Object Refinery Limited); * Contributor(s): -; * * $Id: PaintUtilities.java,v 1.10 2007/11/02 17:50:37 taqua Exp $ * * Changes * ------- * 13-Nov-2003 : Version 1 (DG); * 04-Oct-2004 : Renamed PaintUtils --> PaintUtilities (DG); * 23-Feb-2005 : Rewrote equal() method with less indenting required (DG); * */
public class Main {
/** * Converts a given string into a color. * * @param value * the string, either a name or a hex-string. * @return the color. */ public static Color stringToColor(final String value) { if (value == null) { return Color.black; } try { // get color by hex or octal value return Color.decode(value); } catch (NumberFormatException nfe) { // if we can"t decode lets try to get it by name try { // try to get a color by name using reflection final Field f = Color.class.getField(value); return (Color) f.get(null); } catch (Exception ce) { // if we can"t get any color return black return Color.black; } } }
}
</source>
Converts the String representation of a color to an actual Color object.
<source lang="java"> import java.awt.Color; /*
* Copyright 2007 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
/**
* Some string utilities for joining list of strings. * * @author ycoppel@google.ru (Yohann Coppel) * */
public class Utils {
/** * Converts theString
representation of a color to an actual *Color
object. * * @param value String representation of the color in "r,g,b" format (e.g. * "100,255,0") * @returnColor
object that matches the red-green-blue values * provided by the parameter. Returnsnull
for empty string. */ public static Color stringToColor(String value) { try { if (!value.equals("")) { String[] s = value.split(","); if (s.length == 3) { int red = Integer.parseInt(s[0]); int green = Integer.parseInt(s[1]); int blue = Integer.parseInt(s[2]); return new Color(red, green, blue); } } } catch (NumberFormatException ex) { // ignore it, don"t change anything. return null; } catch (IllegalArgumentException ex) { // if a user entered 548 as the red value.... // ignore it, don"t change anything. return null; } return null; }
}
</source>
Derives a color by adding the specified offsets to the base color"s hue, saturation, and brightness values
<source lang="java"> /*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
import java.awt.Color; /**
- @author aim
- /
public class Utils {
/** * Derives a color by adding the specified offsets to the base color"s * hue, saturation, and brightness values. The resulting hue, saturation, * and brightness values will be contrained to be between 0 and 1. * @param base the color to which the HSV offsets will be added * @param dH the offset for hue * @param dS the offset for saturation * @param dB the offset for brightness * @return Color with modified HSV values */ public static Color deriveColorHSB(Color base, float dH, float dS, float dB) { float hsb[] = Color.RGBtoHSB( base.getRed(), base.getGreen(), base.getBlue(), null); hsb[0] += dH; hsb[1] += dS; hsb[2] += dB; return Color.getHSBColor( hsb[0] < 0? 0 : (hsb[0] > 1? 1 : hsb[0]), hsb[1] < 0? 0 : (hsb[1] > 1? 1 : hsb[1]), hsb[2] < 0? 0 : (hsb[2] > 1? 1 : hsb[2])); }
}
</source>
Drawing with Color
<source lang="java"> import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import javax.swing.JComponent; import javax.swing.JFrame; public class BasicDraw {
public static void main(String[] args) { new BasicDraw(); } BasicDraw() { JFrame frame = new JFrame(); frame.add(new MyComponent()); frame.setSize(300, 300); frame.setVisible(true); }
} class MyComponent extends JComponent {
public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; g2d.setColor(Color.red); g2d.fill(new Rectangle(20,20,200,200)); int red = 230; int green = 45; int blue = 67; g2d.setColor(new Color(red, green, blue)); g2d.fill(new Rectangle(40,40,200,200)); }
}
</source>
If the color is equal to one of the defined constant colors, that name is returned instead.
<source lang="java"> import java.awt.Color; import java.lang.reflect.Field; import java.lang.reflect.Modifier; /*
* JCommon : a free general purpose class library for the Java(tm) platform * * * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. * * Project Info: http://www.jfree.org/jcommon/index.html * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. * * [Java is a trademark or registered trademark of Sun Microsystems, Inc. * in the United States and other countries.] * * ------------------- * PaintUtilities.java * ------------------- * (C) Copyright 2003-2005, by Object Refinery Limited. * * Original Author: David Gilbert (for Object Refinery Limited); * Contributor(s): -; * * $Id: PaintUtilities.java,v 1.10 2007/11/02 17:50:37 taqua Exp $ * * Changes * ------- * 13-Nov-2003 : Version 1 (DG); * 04-Oct-2004 : Renamed PaintUtils --> PaintUtilities (DG); * 23-Feb-2005 : Rewrote equal() method with less indenting required (DG); * */
public class Main {
/** * Converts a color into a string. If the color is equal to one of the defined * constant colors, that name is returned instead. Otherwise the color is * returned as hex-string. * * @param c * the color. * @return the string for this color. */ public static String colorToString(final Color c) { try { final Field[] fields = Color.class.getFields(); for (int i = 0; i < fields.length; i++) { final Field f = fields[i]; if (Modifier.isPublic(f.getModifiers()) && Modifier.isFinal(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) { final String name = f.getName(); final Object oColor = f.get(null); if (oColor instanceof Color) { if (c.equals(oColor)) { return name; } } } } } catch (Exception e) { // } // no defined constant color, so this must be a user defined color final String color = Integer.toHexString(c.getRGB() & 0x00ffffff); final StringBuffer retval = new StringBuffer(7); retval.append("#"); final int fillUp = 6 - color.length(); for (int i = 0; i < fillUp; i++) { retval.append("0"); } retval.append(color); return retval.toString(); }
}
</source>
Map colors into names and vice versa.
<source lang="java"> /**
* * LibSparkline : a free Java sparkline chart library * * * Project Info: http://reporting.pentaho.org/libsparkline/ * * (C) Copyright 2008, by Larry Ogrodnek, Pentaho Corporation and Contributors. * * This library is free software; you can redistribute it and/or modify it under the terms * of the Apache License 2.0. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the Apache License 2.0 along with this library; * if not, a online version is available at http://www.apache.org/licenses/ * * [Java is a trademark or registered trademark of Sun Microsystems, Inc. * in the United States and other countries.] * * ------------ * ColorUtilitiy.java * ------------ */
import java.awt.Color; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashMap; /**
* A helper class to map colors into names and vice versa. * * @author Thomas Morgner */
public final class ColorUtilitiy {
private static final HashMap knownColorNamesByColor; private static final HashMap knownColorsByName; static { knownColorNamesByColor = new HashMap(); knownColorsByName = new HashMap(); try { final Field[] fields = Color.class.getFields(); for (int i = 0; i < fields.length; i++) { final Field f = fields[i]; if (Modifier.isPublic(f.getModifiers()) && Modifier.isFinal(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) { final String name = f.getName(); final Object oColor = f.get(null); if (oColor instanceof Color) { knownColorNamesByColor.put(oColor, name.toLowerCase()); knownColorsByName.put(name.toLowerCase(), oColor); } } } } catch (Exception e) { // ignore .. } } /** * Utility class constructor prevents object creation. */ private ColorUtilitiy() { } /** * Parse a String into a Color. <p/> This method will accept either a color * name (a field name from {@link Color}, case insensitive e.g. "red"), or a * HTML hex color string (e.g. "#ff0000" for Color.RED). * * @param value * String to parse for color name or color number. * @return Color for s. */ private static Color parseColor(final String value) { if (value == null) { return null; } final Object o = knownColorsByName.get(value.toLowerCase()); if (o != null) { return (Color) o; } try { // get color by hex or octal value return Color.decode(value.trim()); } catch (NumberFormatException nfe) { return null; } } /** * Parse a String into a Color, and returns the given default value if the * color is not parsable. <p/> This method will accept either a color name (a * field name from {@link Color}, case insensitive e.g. "red"), or a HTML hex * color string (e.g. "#ff0000" for Color.RED). * * @param colorText * String to parse for color name or color number. * @param defValue * the default value that should be returned if the string is not * parseable or null. * @return Color for the text. */ public static Color convertColor(final String colorText, final Color defValue) { if (colorText == null || colorText.isEmpty()) { return defValue; } final Color retval = parseColor(colorText); if (retval == null) { return defValue; } return retval; }
}
</source>
Rainbow Color
<source lang="java"> import java.awt.Graphics; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import javax.swing.JComponent; import javax.swing.JFrame; public class ColorPan extends JComponent {
BufferedImage image; public void initialize() { int width = getSize().width; int height = getSize().height; int[] data = new int[width * height]; int index = 0; for (int i = 0; i < height; i++) { int red = (i * 255) / (height - 1); for (int j = 0; j < width; j++) { int green = (j * 255) / (width - 1); int blue = 128; data[index++] = (red << 16) | (green << 8) | blue; } } image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); image.setRGB(0, 0, width, height, data, 0, width); } public void paint(Graphics g) { if (image == null) initialize(); g.drawImage(image, 0, 0, this); } public static void main(String[] args) { JFrame f = new JFrame("ColorPan"); f.getContentPane().add(new ColorPan()); f.setSize(300, 300); f.setLocation(100, 100); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setVisible(true); }
}
</source>
Utility for checking colors given either hexa or natural language string descriptions.
<source lang="java"> import java.awt.*; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; /**
* Utility for checking colors given either hexa or "natural language" string descriptions.*
For all assertEquals/equals methods, the "expected" parameter can be either: *
-
*
- A
Color
object specifying the exact color
* - A
String
object containing the hexadecimal description of the exact color
* - A
String
object containing the name of a color for an approximate comparison. * The authorized names are those of the predefined Color objects defined in the Java * */ public final class ColorUtils { private static final Map<String, Color> nameToColorMap = buildNameToColorMap(); static final String UNEXPECTED_COLOR_CLASS = "Expected color should be an instance of Color or String"; public static boolean equals(Object expectedColor, Color actual) { if (expectedColor instanceof Color) { return expectedColor.equals(actual); } else if (expectedColor instanceof String) { return equals((String)expectedColor, actual); } throw new IllegalArgumentException(UNEXPECTED_COLOR_CLASS); } public static boolean equals(String expectedColor, Color actual) { Color foundColor = nameToColorMap.get(expectedColor.toUpperCase()); if (foundColor != null) { return equals(foundColor, actual, true); } try { foundColor = getColor(expectedColor); return equals(foundColor, actual, false); } catch (NumberFormatException e) { throw new IllegalArgumentException(""" + expectedColor + "" does not seem to be a color"); } } public static Color getColor(String hexaString) { return new Color(Integer.parseInt(hexaString, 16)); } /** * Returns a normalized string description given a Color or another String description */ public static String getColorDescription(Object color) { if (color instanceof Color) { return getColorDescription((Color)color); } else if (color instanceof String) { return getColorDescription((String)color); } throw new IllegalArgumentException(UNEXPECTED_COLOR_CLASS); } /** * Returns a description string for a given Color object */ public static String getColorDescription(Color color) { return toHexString(color).toUpperCase(); } /** * Normalizes a given color description string */ public static String getColorDescription(String color) { return color.toUpperCase(); } private static boolean equals(Color expected, Color actual, boolean matchBySimilarity) { if (matchBySimilarity) { return computeHSBDistance(expected, actual) < 0.9; } else { return expected.equals(actual); } } private static Color getColor(Object input) { if (input instanceof Color) { return (Color)input; } else if (input instanceof String) { Color namedColor = nameToColorMap.get(((String)input).toUpperCase()); if (namedColor != null) { return namedColor; } return getColor((String)input); } throw new IllegalArgumentException(UNEXPECTED_COLOR_CLASS); } private static double computeHSBDistance(Color expected, Color actual) { float[] expectedHSB = toHSB(expected); float[] actualHSB = toHSB(actual); return Math.sqrt(Math.pow((expectedHSB[0] - actualHSB[0]) * 20, 2) + Math.pow(expectedHSB[1] - actualHSB[1], 2) + Math.pow((expectedHSB[2] - actualHSB[2]) * 2, 2)); } private static float[] toHSB(Color aColor) { return Color.RGBtoHSB(aColor.getRed(), aColor.getGreen(), aColor.getBlue(), null); } private static Map<String, Color> buildNameToColorMap() { Map<String, Color> colorMap = new HashMap<String, Color>(); for (Field field : Color.class.getDeclaredFields()) { if (isConstantColorField(field)) { try { Color color = (Color)field.get(null); colorMap.put(field.getName().toUpperCase(), color); } catch (IllegalAccessException e) { // Should not occur because the field is public and static } } } colorMap.put("DARKGREY", getColor("555555")); colorMap.put("DARKBLUE", getColor("000055")); colorMap.put("DARKRED", getColor("550000")); colorMap.put("DARKGREEN", getColor("005500")); colorMap.put("DARK_GREY", getColor("555555")); colorMap.put("DARK_BLUE", getColor("000055")); colorMap.put("DARK_RED", getColor("550000")); colorMap.put("DARK_GREEN", getColor("005500")); return colorMap; } private static boolean isConstantColorField(Field field) { return Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers()) && Color.class == field.getType(); } private static String toHexString(Color color) { return Integer.toHexString(color.getRGB()).substring(2); } } </source>XOR color
<source lang="java"> import java.awt.Color; import java.awt.Container; import java.awt.Graphics; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JPanel; public class XORPanel extends JPanel {
XORPanel() { setBackground(Color.black); } public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.red); g.fillRect(10, 10, 80, 30); g.setColor(Color.green); g.fillRect(50, 20, 80, 30); g.setColor(Color.blue); g.fillRect(130, 40, 80, 30); g.setXORMode(Color.green); g.fillRect(90, 30, 80, 30); } public static void main(String[] args) { JFrame frame = new JFrame(); frame.setTitle("XOR"); frame.setSize(300, 200); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); Container contentPane = frame.getContentPane(); contentPane.add(new XORPanel()); frame.show(); }
}
</source>