/*
* This code is part of Project Waterloo from King's College London
*
*
* Copyright King's College London 2012-
*
* @author Malcolm Lidierth, King's College London [Contact]
*
* This program 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 3 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 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, see .
*
*/
package kcl.waterloo.defaults;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import kcl.waterloo.math.ArrayMath;
/**
* Colors and color utilities.
*
* Defines a set of web colors corresponding to those in JavaFX. See
* http://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html for
* details.
*
* N.B. Future versions of the library are likely to add JavaFX support.
*
* @author Malcolm Lidierth, King's College London [Contact]
*/
public class Colors {
/**
* LinkedHashMap of standard named web colors.
*/
private static final LinkedHashMap color = new LinkedHashMap();
private static final LinkedHashMap blueDarkOrange18 = new LinkedHashMap();
private static final LinkedHashMap blueDarkRed18 = new LinkedHashMap();
private static LinkedHashMap defaultMap = blueDarkRed18;
// CIELab reference values: Observer= 2 degrees, Illuminant= D65
private static final double ref_X = 95.047;
private static final double ref_Y = 100.000;
private static final double ref_Z = 108.883;
/**
* Static instance. The instance is not made accessible - it is here only to
* force instantiation of the hash map when the class is first referenced in
* a JVM session.
*/
private static final Colors instance = new Colors();
/**
*
*/
private Colors() {
color.put("TRANSPARENT", new java.awt.Color(0, 0, 0, 0));
color.put("ALICEBLUE", new Color(240, 248, 255));
color.put("ANTIQUEWHITE", new Color(250, 235, 215));
color.put("AQUA", new Color(0, 255, 255));
color.put("AQUAMARINE", new Color(127, 255, 212));
color.put("AZURE", new Color(240, 255, 255));
color.put("BEIGE", new Color(245, 245, 220));
color.put("BISQUE", new Color(255, 228, 196));
color.put("BLACK", new Color(0, 0, 0));
color.put("BLANCHEDALMOND", new Color(255, 235, 205));
color.put("BLUE", new Color(0, 0, 255));
color.put("BLUEVIOLET", new Color(138, 43, 226));
color.put("BROWN", new Color(165, 42, 42));
color.put("BURLYWOOD", new Color(222, 184, 135));
color.put("CADETBLUE", new Color(95, 158, 160));
color.put("CHARTREUSE", new Color(127, 255, 0));
color.put("CHOCOLATE", new Color(210, 105, 30));
color.put("CORAL", new Color(255, 127, 80));
color.put("CORNFLOWERBLUE", new Color(100, 149, 237));
color.put("CORNSILK", new Color(255, 248, 220));
color.put("CRIMSON", new Color(220, 20, 60));
color.put("CYAN", new Color(0, 255, 255));
color.put("DARKBLUE", new Color(0, 0, 139));
color.put("DARKCYAN", new Color(0, 139, 139));
color.put("DARKGOLDENROD", new Color(184, 134, 11));
color.put("DARKGRAY", new Color(169, 169, 169));
color.put("DARKGREEN", new Color(0, 100, 0));
color.put("DARKGREY", new Color(169, 169, 169));
color.put("DARKKHAKI", new Color(189, 183, 107));
color.put("DARKMAGENTA", new Color(139, 0, 139));
color.put("DARKOLIVEGREEN", new Color(85, 107, 47));
color.put("DARKORANGE", new Color(255, 140, 0));
color.put("DARKORCHID", new Color(153, 50, 204));
color.put("DARKRED", new Color(139, 0, 0));
color.put("DARKSALMON", new Color(233, 150, 122));
color.put("DARKSEAGREEN", new Color(143, 188, 143));
color.put("DARKSLATEBLUE", new Color(72, 61, 139));
color.put("DARKSLATEGRAY", new Color(47, 79, 79));
color.put("DARKSLATEGREY", new Color(47, 79, 79));
color.put("DARKTURQUOISE", new Color(0, 206, 209));
color.put("DARKVIOLET", new Color(148, 0, 211));
color.put("DEEPPINK", new Color(255, 20, 147));
color.put("DEEPSKYBLUE", new Color(0, 191, 255));
color.put("DIMGRAY", new Color(105, 105, 105));
color.put("DIMGREY", new Color(105, 105, 105));
color.put("DODGERBLUE", new Color(30, 144, 255));
color.put("FIREBRICK", new Color(178, 34, 34));
color.put("FLORALWHITE", new Color(255, 250, 240));
color.put("FORESTGREEN", new Color(34, 139, 34));
color.put("FUCHSIA", new Color(255, 0, 255));
color.put("GAINSBORO", new Color(220, 220, 220));
color.put("GHOSTWHITE", new Color(248, 248, 255));
color.put("GOLD", new Color(255, 215, 0));
color.put("GOLDENROD", new Color(218, 165, 32));
color.put("GRAY", new Color(128, 128, 128));
color.put("GREEN", new Color(0, 128, 0));
color.put("GREENYELLOW", new Color(173, 255, 47));
color.put("GREY", new Color(128, 128, 128));
color.put("HONEYDEW", new Color(240, 255, 240));
color.put("HOTPINK", new Color(255, 105, 180));
color.put("INDIANRED", new Color(205, 92, 92));
color.put("INDIGO", new Color(75, 0, 130));
color.put("IVORY", new Color(255, 255, 240));
color.put("KHAKI", new Color(240, 230, 140));
color.put("LAVENDER", new Color(230, 230, 250));
color.put("LAVENDERBLUSH", new Color(255, 240, 245));
color.put("LAWNGREEN", new Color(124, 252, 0));
color.put("LEMONCHIFFON", new Color(255, 250, 205));
color.put("LIGHTBLUE", new Color(173, 216, 230));
color.put("LIGHTCORAL", new Color(240, 128, 128));
color.put("LIGHTCYAN", new Color(224, 255, 255));
color.put("LIGHTGOLDENRODYELLOW", new Color(250, 250, 210));
color.put("LIGHTGRAY", new Color(211, 211, 211));
color.put("LIGHTGREEN", new Color(144, 238, 144));
color.put("LIGHTGREY", new Color(211, 211, 211));
color.put("LIGHTPINK", new Color(255, 182, 193));
color.put("LIGHTSALMON", new Color(255, 160, 122));
color.put("LIGHTSEAGREEN", new Color(32, 178, 170));
color.put("LIGHTSKYBLUE", new Color(135, 206, 250));
color.put("LIGHTSLATEGRAY", new Color(119, 136, 153));
color.put("LIGHTSLATEGREY", new Color(119, 136, 153));
color.put("LIGHTSTEELBLUE", new Color(176, 196, 222));
color.put("LIGHTYELLOW", new Color(255, 255, 224));
color.put("LIME", new Color(0, 255, 0));
color.put("LIMEGREEN", new Color(50, 205, 50));
color.put("LINEN", new Color(250, 240, 230));
color.put("MAGENTA", new Color(255, 0, 255));
color.put("MAROON", new Color(128, 0, 0));
color.put("MEDIUMAQUAMARINE", new Color(102, 205, 170));
color.put("MEDIUMBLUE", new Color(0, 0, 205));
color.put("MEDIUMORCHID", new Color(186, 85, 211));
color.put("MEDIUMPURPLE", new Color(147, 112, 219));
color.put("MEDIUMSEAGREEN", new Color(60, 179, 113));
color.put("MEDIUMSLATEBLUE", new Color(123, 104, 238));
color.put("MEDIUMSPRINGGREEN", new Color(0, 250, 154));
color.put("MEDIUMTURQUOISE", new Color(72, 209, 204));
color.put("MEDIUMVIOLETRED", new Color(199, 21, 133));
color.put("MIDNIGHTBLUE", new Color(25, 25, 112));
color.put("MINTCREAM", new Color(245, 255, 250));
color.put("MISTYROSE", new Color(255, 228, 225));
color.put("MOCCASIN", new Color(255, 228, 181));
color.put("NAVAJOWHITE", new Color(255, 222, 173));
color.put("NAVY", new Color(0, 0, 128));
color.put("OLDLACE", new Color(253, 245, 230));
color.put("OLIVE", new Color(128, 128, 0));
color.put("OLIVEDRAB", new Color(107, 142, 35));
color.put("ORANGE", new Color(255, 165, 0));
color.put("ORANGERED", new Color(255, 69, 0));
color.put("ORCHID", new Color(218, 112, 214));
color.put("PALEGOLDENROD", new Color(238, 232, 170));
color.put("PALEGREEN", new Color(152, 251, 152));
color.put("PALETURQUOISE", new Color(175, 238, 238));
color.put("PALEVIOLETRED", new Color(219, 112, 147));
color.put("PAPAYAWHIP", new Color(255, 239, 213));
color.put("PEACHPUFF", new Color(255, 218, 185));
color.put("PERU", new Color(205, 133, 63));
color.put("PINK", new Color(255, 192, 203));
color.put("PLUM", new Color(221, 160, 221));
color.put("POWDERBLUE", new Color(176, 224, 230));
color.put("PURPLE", new Color(128, 0, 128));
color.put("RED", new Color(255, 0, 0));
color.put("ROSYBROWN", new Color(188, 143, 143));
color.put("ROYALBLUE", new Color(65, 105, 225));
color.put("SADDLEBROWN", new Color(139, 69, 19));
color.put("SALMON", new Color(250, 128, 114));
color.put("SANDYBROWN", new Color(244, 164, 96));
color.put("SEAGREEN", new Color(46, 139, 87));
color.put("SEASHELL", new Color(255, 245, 238));
color.put("SIENNA", new Color(160, 82, 45));
color.put("SILVER", new Color(192, 192, 192));
color.put("SKYBLUE", new Color(135, 206, 235));
color.put("SLATEBLUE", new Color(106, 90, 205));
color.put("SLATEGRAY", new Color(112, 128, 144));
color.put("SLATEGREY", new Color(112, 128, 144));
color.put("SNOW", new Color(255, 250, 250));
color.put("SPRINGGREEN", new Color(0, 255, 127));
color.put("STEELBLUE", new Color(70, 130, 180));
color.put("TAN", new Color(210, 180, 140));
color.put("TEAL", new Color(0, 128, 128));
color.put("THISTLE", new Color(216, 191, 216));
color.put("TOMATO", new Color(255, 99, 71));
color.put("TURQUOISE", new Color(64, 224, 208));
color.put("VIOLET", new Color(238, 130, 238));
color.put("WHEAT", new Color(245, 222, 179));
color.put("WHITE", new Color(255, 255, 255));
color.put("WHITESMOKE", new Color(245, 245, 245));
color.put("YELLOW", new Color(255, 255, 0));
color.put("YELLOWGREEN", new Color(154, 205, 50));
// These non-standard colors are Waterloo defined
color.put("AREAFILL", new Color(245, 222, 179, 200));
color.put("TRANSPARENTWHITE", new Color(255, 255, 255, 200));
// http://www.ncl.ucar.edu/Document/Graphics/ColorTables/BlueDarkOrange18.shtml
blueDarkOrange18.put(0, new Color(0, 102, 102));
blueDarkOrange18.put(1, new Color(0, 153, 153));
blueDarkOrange18.put(2, new Color(0, 204, 204));
blueDarkOrange18.put(3, new Color(0, 255, 255));
blueDarkOrange18.put(4, new Color(51, 255, 255));
blueDarkOrange18.put(5, new Color(101, 255, 255));
blueDarkOrange18.put(6, new Color(153, 255, 255));
blueDarkOrange18.put(7, new Color(178, 255, 255));
blueDarkOrange18.put(8, new Color(203, 255, 255));
blueDarkOrange18.put(9, new Color(229, 255, 255));
blueDarkOrange18.put(10, new Color(255, 229, 203));
blueDarkOrange18.put(11, new Color(255, 202, 153));
blueDarkOrange18.put(12, new Color(255, 173, 101));
blueDarkOrange18.put(13, new Color(255, 142, 51));
blueDarkOrange18.put(14, new Color(255, 110, 0));
blueDarkOrange18.put(15, new Color(204, 85, 0));
blueDarkOrange18.put(16, new Color(153, 61, 0));
blueDarkOrange18.put(17, new Color(102, 39, 0));
blueDarkRed18.put(0, new Color(36, 0, 216));
blueDarkRed18.put(1, new Color(24, 28, 247));
blueDarkRed18.put(2, new Color(40, 87, 255));
blueDarkRed18.put(3, new Color(61, 135, 255));
blueDarkRed18.put(4, new Color(86, 176, 255));
blueDarkRed18.put(5, new Color(117, 211, 255));
blueDarkRed18.put(6, new Color(153, 234, 255));
blueDarkRed18.put(7, new Color(188, 249, 255));
blueDarkRed18.put(8, new Color(234, 255, 255));
blueDarkRed18.put(9, new Color(255, 255, 234));
blueDarkRed18.put(10, new Color(255, 241, 188));
blueDarkRed18.put(11, new Color(255, 214, 153));
blueDarkRed18.put(12, new Color(255, 172, 117));
blueDarkRed18.put(13, new Color(255, 120, 86));
blueDarkRed18.put(14, new Color(255, 61, 61));
blueDarkRed18.put(15, new Color(247, 39, 53));
blueDarkRed18.put(16, new Color(216, 21, 47));
blueDarkRed18.put(17, new Color(165, 0, 33));
}
/**
* Returns the standard web colors sorted by hue
*
* @return ArrayList
*/
public static ArrayList sortByHue() {
ArrayList c = new ArrayList(color.values());
Collections.sort(c, HueSorter.getInstance());
return c;
}
/**
* Returns the standard web colors sorted by saturation
*
* @return ArrayList
*/
public static ArrayList sortBySaturation() {
ArrayList c = new ArrayList(color.values());
Collections.sort(c, SaturationSorter.getInstance());
return c;
}
/**
* Returns the standard web colors sorted by lightness
*
* @return ArrayList
*/
public static ArrayList sortByLightness() {
ArrayList c = new ArrayList(color.values());
Collections.sort(c, LightnessSorter.getInstance());
return c;
}
/**
* Returns the standard web colors sorted by luminance
*
* @return ArrayList
*/
public static ArrayList sortByLuminance() {
ArrayList c = new ArrayList(color.values());
Collections.sort(c, LuminanceSorter.getInstance());
return c;
}
/**
*
* Returns the standard web colors sorted alphabetically by name
*
* @return ArrayList
*/
public static LinkedHashMap getColors() {
return color;
}
/**
* Returns the color specified by a name.
*
* @param s name of the web color
* @return an AWT Color
*/
public static java.awt.Color getColor(String s) {
return color.get(s.toUpperCase());
}
public static java.awt.Color[] getColor(String... s) {
Color[] p = new Color[s.length];
for (int k = 0; k < s.length; k++) {
p[k] = color.get(s[k].toUpperCase());
}
return p;
}
/**
* Returns the name associated with a color (or "" if the color is not
* recognized).
*
* @param c AWT Color
* @return name of the web color or "".
*/
public static String getColor(Color c) {
if (color.containsValue(c)) {
for (Entry x : color.entrySet()) {
if (x.getValue().equals(c)) {
return x.getKey();
}
}
}
return "UNKNOWN";
}
public static Color getColor(int i) {
return defaultMap.get(Integer.valueOf(i));
}
public static Color getColor(Integer i) {
return defaultMap.get(i);
}
/**
* getLuminance returns the luminance as a weighted average of the RGB
* components.
*
* @param color an AWT Color value
* @return
*/
public static float getLuminance(Color color) {
return color.getRed() * 0.3f + color.getGreen() * 0.59f + color.getBlue() * 0.11f;
}
/**
* getTheta returns the angle of the color in the color circle
*
* @param c an AWT Color value
* @return
*/
public static float getTheta(Color c) {
float[] hsl = toHSL(c);
return hsl[1] * 360f;
}
/**
*
* @param colors an AWT Color array
* @return
*/
public static float[] getLuminance(Color[] colors) {
float[] lum = new float[colors.length];
for (int k = 0; k < colors.length; k++) {
lum[k] = getLuminance(colors[k]);
}
return lum;
}
private static double hue2RGB(double v1, double v2, double vH) {
if (vH < 0d) {
vH = vH + 1d;
}
if (vH > 1d) {
vH = vH - 1d;
}
if (6d * vH < 1d) {
return v1 + (v2 - v1) * 6d * vH;
}
if (2d * vH < 1d) {
return v2;
}
if (3d * vH < 2d) {
return v1 + (v2 - v1) * (2d / 3d - vH) * 6d;
}
return v1;
}
/**
* Convert HSL to RGB
*
* @param h hue
* @param s saturation
* @param l luminance
* @return an AWT Color value
*/
public static Color HSLtoRGB(float h, float s, float l) {
if (s == 0d) {
return new java.awt.Color(l, l, l);
} else {
double var2;
if (l < 0.5d) {
var2 = l * (1 + s);
} else {
var2 = (l + s) - (s * l);
}
double var1 = 2d * l - var2;
float r = (float) hue2RGB(var1, var2, h + 1d / 3d);
float g = (float) hue2RGB(var1, var2, h);
float b = (float) hue2RGB(var1, var2, h - 1d / 3d);
return new java.awt.Color(r, g, b);
}
}
/**
* toHSL converts RGB to HSL Based on source at EasyRGB
*
* @param color an AWT Color value
* @return HSL values as a float[]
*/
public static float[] toHSL(Color color) {
double r = color.getRed() / 255d;
double g = color.getGreen() / 255d;
double b = color.getBlue() / 255d;
double mn = ArrayMath.min(new double[]{r, g, b});
double mx = ArrayMath.max(new double[]{r, g, b});
double delta = mx - mn;
double l = (mx + mn) / 2d;
double h = Double.NaN;
double s;
if (delta == 0d) {
h = 0d;
s = 0d;
} else {
if (l < 0.5d) {
s = delta / (mx + mn);
} else {
s = delta / (2d - mx - mn);
}
double deltaR = (((mx - r) / 6d) + (delta / 2d)) / delta;
double deltaG = (((mx - g) / 6d) + (delta / 2d)) / delta;
double deltaB = (((mx - b) / 6d) + (delta / 2d)) / delta;
if (r == mx) {// Fp equality ok
h = deltaB - deltaG;
} else if (g == mx) {
h = (1 / 3d) + deltaR - deltaB;
} else if (b == mx) {
h = (2d / 3d) + deltaG - deltaR;
}
if (h < 0d) {
h = h + 1;
} else if (h > 1d) {
h = h - 1;
}
}
return new float[]{(float) h, (float) s, (float) l};
}
/**
* Convert an AWT Color array to hsl values
*
* @param colors an AWT Color array
* @return the hsl values as a float[][]
*/
public static float[][] toHSL(Color[] colors) {
float[][] hsl = new float[3][colors.length];
for (int k = 0; k < colors.length; k++) {
hsl[k] = toHSL(colors[k]);
}
return hsl;
}
/**
* toXYZ converts RGB to XYZ Based on source at EasyRGB
*
* @param color
* @return
*/
public static float[] toXYZ(Color color) {
double var_R = (color.getRed() / 255d); //R from 0 to 255
double var_G = (color.getGreen() / 255d); //G from 0 to 255
double var_B = (color.getBlue() / 255d); //B from 0 to 255
if (var_R > 0.04045d) {
var_R = Math.pow(((var_R + 0.055d) / 1.055d), 2.4d);
} else {
var_R = var_R / 12.92d;
}
if (var_G > 0.04045d) {
var_G = Math.pow(((var_G + 0.055d) / 1.055d), 2.4d);
} else {
var_G = var_G / 12.92d;
}
if (var_B > 0.04045d) {
var_B = Math.pow(((var_B + 0.055d) / 1.055d), 2.4d);
} else {
var_B = var_B / 12.92d;
}
var_R = var_R * 100d;
var_G = var_G * 100d;
var_B = var_B * 100d;
//Observer. = 2 degrees, Illuminant = D65
float X = (float) (var_R * 0.4124d + var_G * 0.3576d + var_B * 0.1805d);
float Y = (float) (var_R * 0.2126d + var_G * 0.7152d + var_B * 0.0722d);
float Z = (float) (var_R * 0.0193d + var_G * 0.1192d + var_B * 0.9505d);
return new float[]{X, Y, Z};
}
/**
* toXYZ converts RGB Color array to XYZ Based on source at
* http://www.easyrgb.com/index.php?X=MATH&H=18#text18
*
* @param colors an AWT Color array
* @return the XYZ color values as a float[][]
*/
public static float[][] toXYZ(Color[] colors) {
float[][] xyz = new float[3][colors.length];
for (int k = 0; k < colors.length; k++) {
xyz[k] = toXYZ(colors[k]);
}
return xyz;
}
/**
* toLab converts RGB to CIELab Based on source at EasyRGB
*
* @param color an AWT Color value
* @return CIELab values as float[]
*/
public static float[] toLab(Color color) {
float[] xyzcolor = Colors.toXYZ(color);
// Observer= 2 degrees, Illuminant= D65
double var_X = xyzcolor[0] / ref_X;
double var_Y = xyzcolor[1] / ref_Y;
double var_Z = xyzcolor[2] / ref_Z;
if (var_X > 0.008856) {
var_X = Math.pow(var_X, 1 / 3d);
} else {
var_X = (7.787 * var_X) + (16 / 116);
}
if (var_Y > 0.008856) {
var_Y = Math.pow(var_Y, 1 / 3d);
} else {
var_Y = (7.787 * var_Y) + (16 / 116);
}
if (var_Z > 0.008856) {
var_Z = Math.pow(var_Z, 1 / 3d);
} else {
var_Z = (7.787 * var_Z) + (16 / 116);
}
float CIEL = (float) (116 * var_Y - 16d);
float CIEa = (float) (500 * (var_X - var_Y));
float CIEb = (float) (200 * (var_Y - var_Z));
return new float[]{CIEL, CIEa, CIEb};
}
/**
* toLab converts RGB Color[] to CIELab Based on source at EasyRGB
*
* @param colors AWT Color array
* @return CIELab values as float[][]
*/
public static float[][] toLab(Color[] colors) {
float[][] lab = new float[3][colors.length];
for (int k = 0; k < colors.length; k++) {
lab[k] = toLab(colors[k]);
}
return lab;
}
/**
* Converts CIELab to XYZ Based on source at EasyRGB
*
* @param xyz XYZ values
* @return CIELab values
*/
public static float[] labToXYZ(float[] xyz) {
double var_Y = (xyz[0] + 16d) / 116d;
double var_X = xyz[1] / 500d + var_Y;
double var_Z = var_Y - xyz[2] / 200d;
if (Math.pow(var_Y, 3) > 0.008856) {
var_Y = Math.pow(var_Y, 3);
} else {
var_Y = (var_Y - 16 / 116) / 7.787;
}
if (Math.pow(var_X, 3) > 0.008856) {
var_X = Math.pow(var_X, 3);
} else {
var_X = (var_X - 16 / 116) / 7.787;
}
if (Math.pow(var_Z, 3) > 0.008856) {
var_Z = Math.pow(var_Z, 3);
} else {
var_Z = (var_Z - 16 / 116) / 7.787;
}
// Observer= 2 degrees, Illuminant= D65
float X = (float) (ref_X * var_X);
float Y = (float) (ref_Y * var_Y);
float Z = (float) (ref_Z * var_Z);
return new float[]{X, Y, Z};
}
/**
* Convert RGB to XYZ.
*
* @param xyz XYZ values
* @return RGB values
*/
public static Color XYZToRGB(float[] xyz) {
// Observer = 2 degrees, Illuminant = D65
double var_X = xyz[0] / 100;
double var_Y = xyz[1] / 100;
double var_Z = xyz[2] / 100;
double var_R = var_X * 3.2406d + var_Y * -1.5372d + var_Z * -0.4986d;
double var_G = var_X * -0.9689d + var_Y * 1.8758d + var_Z * 0.0415d;
double var_B = var_X * 0.0557d + var_Y * -0.2040d + var_Z * 1.0570d;
if (var_R > 0.0031308d) {
var_R = 1.055d * Math.pow(var_R, 1d / 2.4d) - 0.055d;
} else {
var_R = 12.92d * var_R;
}
if (var_G > 0.0031308d) {
var_G = 1.055d * Math.pow(var_G, 1d / 2.4d) - 0.055d;
} else {
var_G = 12.92 * var_G;
}
if (var_B > 0.0031308d) {
var_B = 1.055d * Math.pow(var_B, 1d / 2.4d) - 0.055d;
} else {
var_B = 12.92d * var_B;
}
float R = (float) var_R;
float G = (float) var_G;
float B = (float) var_B;
return new Color(R, G, B);
}
/**
*
* @param lab CIELab array
* @return an AWT Color.
*/
public static Color labToRGB(float[] lab) {
return XYZToRGB(labToXYZ(lab));
}
/**
* getArcSeries generates a set of colors of different hue.
*
* Example: colors=getArcSeries(color, n, theta)
*
* where color is the central color of a set of n colors that subtend an arc
* of +/-(theta/2) in the color circle. Theta is specified in degrees and
* should be 0 to 360.
*
* @param color
* @param n
* @param theta
* @return
*/
public static Color[] getArcSeries(Color color, int n, float theta) {
float[] hsl = toHSL(color);
theta = theta / (2 * 360);
double[] s = new double[1];
if (n > 1) {
s = ArrayMath.linspace(hsl[0] - theta, hsl[0] + theta, n);
} else {
s[0] = hsl[0] + theta;
}
Color[] colors = new Color[s.length];
for (int k = 0; k < s.length; k++) {
colors[k] = HSLtoRGB((float) s[k], hsl[1], hsl[2]);
}
return colors;
}
/**
* getComplement returns the complement of a color (rotated 180 degrees on
* the color circle).
*
* Example:
*
* color=getComplement(color);
*
* @param color the reference color
* @return the complement of the reference color
*/
public static Color getComplement(Color color) {
float[] hsl = toHSL(color);
float s = hsl[0] - 0.5f;
return HSLtoRGB(s, hsl[1], hsl[2]);
}
/**
* getSplitComplements returns the 2 split complements of the input i.e. the
* colors at +/- 150 degrees. Example: color=getSplitComplements(color);
*
* @param color an AWT Color
* @return
*/
public static Color[] getSplitComplements(Color color) {
return getArcSeries(color, 2, 300);
}
/**
* getTriads returns the two triadic complements of the input colors. i.e.
* the colors at +/- 120 degrees.
*
* Example:
*
* color=getTriads(color);
*
* @param color an AWT Color
* @return
*/
public static Color[] getTriads(Color color) {
return getArcSeries(color, 2, 240);
}
/**
* getAnalagous returns neigbouring colors i.e. the colors at +/- 30
* degrees.
*
* Example:
*
* color=getAnalagous(color);
*
* @param color an AWT Color
* @return
*/
public static Color[] getAnalagous(Color color) {
return getArcSeries(color, 2, 60);
}
/**
* getMonochrome returns a monochrome series by varying the lightness of the
* reference color.
*
* Example:
*
* colors=getMonochrome(color, n)
*
* @param color an AWT Color
* @param n
* @return
*/
public static Color[] getMonochromeSeries(Color color, int n) {
return getMonochromeSeries(color, n, 1);
}
/**
* getMonochrome returns a monochrome series by varying the lightness of the
* reference color.
*
* Example:
*
* colors=getMonochrome(color, n, llim)
*
* where color on input is the starting color and n=number of colors to
* return. Terminate the series at higher lightness by specifying llim on
* input where llim/2=proportion of the reference color lightness to use.
*
* @param color an AWT Color
* @param n
* @param llim
* @return
*/
public static Color[] getMonochromeSeries(Color color, int n, double llim) {
float[] hsl = toHSL(color);
double[] l = ArrayMath.linspace(hsl[2] + (llim * hsl[2]), hsl[2] - (llim * hsl[2]), n);
Color[] out = new Color[l.length];
for (int k = 0; k < l.length; k++) {
out[k] = HSLtoRGB(hsl[0], hsl[1], (float) l[k]);
}
return out;
}
/**
*
* @param color an AWT Color
* @param n
* @return
*/
public static Color[] getSatSeries(Color color, int n) {
float[] hsl = toHSL(color);
double[] s = ArrayMath.linspace(0, 1, n);
Color[] out = new Color[s.length];
for (int k = 0; k < s.length; k++) {
out[k] = HSLtoRGB(hsl[0], (float) s[k], hsl[2]);
}
return out;
}
/**
*
* getLightnessSeries generates a set of colors of different lightness.
*
* Example:
*
* colors=getLightnessSeries(color, n)
*
* where the output is a set of n colors whose lightness ranges from 0 to 1
* but which have the same hue and saturation as the input with the
* reference color at the centre.
*
* @param color
* @param n
* @return
*/
public static Color[] getLightnessSeries(Color color, int n) {
float[] hsl = toHSL(color);
double[] l = ArrayMath.linspace(0, 1, n);
Color[] out = new Color[l.length];
for (int k = 0; k < l.length; k++) {
out[k] = HSLtoRGB(hsl[0], hsl[1], (float) l[k]);
}
return out;
}
/**
* Returns a Color[] in reverse order to the input.
*
* @param in an AWT Color[] to reverse
* @return the reversed AWT Color[]
*/
public static Color[] reverse(Color[] in) {
Color[] out = new Color[in.length];
int n = 0;
for (int k = in.length - 1; k >= 0; k--) {
out[n++] = in[k];
}
return out;
}
/**
* @return the defaultMap
*/
public static LinkedHashMap getDefaultMap() {
return defaultMap;
}
/**
* @param aDefaultMap the defaultMap to set
*/
public static void setDefaultMap(LinkedHashMap aDefaultMap) {
defaultMap = aDefaultMap;
}
/**
* Sorts HSL color sequence by hue.
*/
private static final class HueSorter implements Comparator {
private static final Colors.HueSorter instance = new Colors.HueSorter();
private HueSorter() {
}
private static Colors.HueSorter getInstance() {
return instance;
}
@Override
public final int compare(Color c0, Color c1) {
if (Colors.toHSL(c0)[0] > Colors.toHSL(c1)[0]) {
return 1;
} else if (Colors.toHSL(c0)[0] < Colors.toHSL(c1)[0]) {
return -1;
} else {
return 0;
}
}
}
/**
* Sorts HSL color sequence by saturation.
*/
private static final class SaturationSorter implements Comparator {
private static Colors.SaturationSorter instance = new Colors.SaturationSorter();
private SaturationSorter() {
}
private static Colors.SaturationSorter getInstance() {
return instance;
}
@Override
public final int compare(Color c0, Color c1) {
if (Colors.toHSL(c0)[1] > Colors.toHSL(c1)[1]) {
return 1;
} else if (Colors.toHSL(c0)[1] < Colors.toHSL(c1)[1]) {
return -1;
} else {
return 0;
}
}
}
/**
* Sorts HSL color sequence by lightness.
*/
private static final class LightnessSorter implements Comparator {
private static final Colors.LightnessSorter instance = new Colors.LightnessSorter();
private LightnessSorter() {
}
private static Colors.LightnessSorter getInstance() {
return instance;
}
@Override
public final int compare(Color c0, Color c1) {
if (Colors.toHSL(c0)[2] > Colors.toHSL(c1)[2]) {
return 1;
} else if (Colors.toHSL(c0)[2] < Colors.toHSL(c1)[2]) {
return -1;
} else {
return 0;
}
}
}
/**
* Sorts RGB color sequence by luminance.
*/
private static final class LuminanceSorter implements Comparator {
private static final Colors.LuminanceSorter instance = new Colors.LuminanceSorter();
private LuminanceSorter() {
}
private static Colors.LuminanceSorter getInstance() {
return instance;
}
@Override
public final int compare(Color c0, Color c1) {
if (Colors.getLuminance(c0) > Colors.getLuminance(c1)) {
return 1;
} else if (Colors.getLuminance(c0) < Colors.getLuminance(c1)) {
return -1;
} else {
return 0;
}
}
}
}
Ads help maintain this website.