/*
 *  HSBColor.java, translates RGB colors into Hue-Saturation-Brightness 
 *  colors.
 *  Copyright (C) 2004 - 2011 Achim Westermann.
 *
 *  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
 *
 *  If you modify or optimize the code in a useful way please let me know.
 *  Achim.Westermann@gmx.de
 *
 */
package info.monitorenter.gui.util;

/**
 * Color that internally works with the Hue Saturation Luminance color space.
 * 

* * @author Achim Westermann * * @version $Revision: 1.7 $ */ public class HSBColor implements java.io.Serializable, Cloneable { /** * Generated serialVersionUID. */ private static final long serialVersionUID = 3257288036910903863L; /** * Inspired by * float[] java.awt.Color.RGBtoHSB(int r,int g, int b, float[]hsbvals) * except that algorithm is tuned
* Testing results showed about 25% speed up. Therefore the sources have * become harder to understand. * * @param color * the java.awt.Color (that follows the RGB model) and * should be transformed to a color instance in the * hue-saturation-luminance model. * * @return the transformed values of the RGB colors in that order: * hue,saturation,brightness. */ public static HSBColor rgbToHSB(final java.awt.Color color) { // TODO: Fix alpha treatment!!!! final int rgb = color.getRGB(); final int r = (rgb & 0xFF0000) >> 16; final int g = (rgb & 0xFF00) >> 8; final int b = (rgb & 0xFF); final HSBColor ret = new HSBColor(); final int cmax = (r >= g) ? (r >= b) ? r : b : (g >= b) ? g : b; final int cmin = (r <= g) ? (r <= b) ? r : b : (g <= b) ? g : b; ret.m_lum = (cmax) / 255f; if (cmax != cmin) { final float difference = (cmax - cmin); ret.m_sat = difference / (cmax); if (r == cmax) { ret.m_hue = (g - b) / difference; } else if (g == cmax) { ret.m_hue = (b - r) / difference + 2.0f; } else { ret.m_hue = (r - g) / difference + 4.0f; } ret.m_hue /= 6.0f; if (ret.m_hue < 0) { ret.m_hue += 1.0f; } } else { ret.m_sat = 0; ret.m_hue = 0; } ret.m_alpha = color.getAlpha(); return ret; } /** Hue value between 0.0 and 1.0. */ protected double m_hue; /** Luminance value between 0.0 and 1.0. */ protected double m_lum; /** Saturation value between 0.0 and 1.0. */ protected double m_sat; /** * The unused alpha channel between 0 and 255: stored here for allow * java.awt.Color instances to be transformed to instances of this class and * be re - transformed with preserving their alpha setting. */ protected double m_alpha; /** * Constructor for internal use only. *

*/ private HSBColor() { // nop } /** * Creates an instance with the given values for hue saturation and luminance. *

* * @param hue * the hue component of the HSBColor * @param saturation * the saturation component of the HSBColor * @param brightness * the brightness component of the HSBColor */ HSBColor(final double hue, final double saturation, final double brightness) { this(hue, saturation, brightness, 255); } /** * Creates an instance with the given values for hue saturation, luminance and * alpha. *

* * @param hue * the hue component of the HSBColor * * @param saturation * the saturation component of the HSBColor * * @param brightness * the brightness component of the HSBColor * * @param alpha * the alpha channed between 0.0 and 1.0. */ HSBColor(final double hue, final double saturation, final double brightness, final int alpha) { this.m_hue = hue; this.m_sat = saturation; this.m_lum = brightness; this.m_alpha = alpha; } /** * Creates an instance transformed from the rgb color. *

* * @param rgbcolor * standard java rgb color. */ public HSBColor(final java.awt.Color rgbcolor) { final int rgb = rgbcolor.getRGB(); final int r = (rgb & 0xFF0000) >> 16; final int g = (rgb & 0xFF00) >> 8; final int b = (rgb & 0xFF); final int cmax = (r >= g) ? (r >= b) ? r : b : (g >= b) ? g : b; final int cmin = (r <= g) ? (r <= b) ? r : b : (g <= b) ? g : b; this.m_lum = (cmax) / 255f; if (cmax != cmin) { final float difference = (cmax - cmin); this.m_sat = difference / (cmax); if (r == cmax) { this.m_hue = (g - b) / difference; } else if (g == cmax) { this.m_hue = (b - r) / difference + 2.0; } else { this.m_hue = (r - g) / difference + 4.0; } this.m_hue /= 6.0; if (this.m_hue < 0) { this.m_hue += 1.0; } } else { this.m_sat = 0; this.m_hue = 0; } this.m_alpha = rgbcolor.getAlpha(); } /** * Clone implementation. *

* * Following statements are true:
* * x.clone() != x * x.clone().getClass() == x.getClass() * x.clone().equals(x) * A deep copy of this HSBColor is returned. *

* * @return an instance copied from this one. */ @Override public Object clone() { HSBColor result = null; try { result = (HSBColor) super.clone(); result.m_hue = this.m_hue; result.m_lum = this.m_lum; result.m_sat = this.m_sat; result.m_alpha = this.m_alpha; } catch (final CloneNotSupportedException e) { result = new HSBColor((float) this.m_hue, (float) this.m_sat, (float) this.m_lum, (int) Math .round(this.m_alpha)); } return result; } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (this.getClass() != obj.getClass()) { return false; } final HSBColor other = (HSBColor) obj; if (Double.doubleToLongBits(this.m_alpha) != Double.doubleToLongBits(other.m_alpha)) { return false; } if (Double.doubleToLongBits(this.m_hue) != Double.doubleToLongBits(other.m_hue)) { return false; } if (Double.doubleToLongBits(this.m_lum) != Double.doubleToLongBits(other.m_lum)) { return false; } if (Double.doubleToLongBits(this.m_sat) != Double.doubleToLongBits(other.m_sat)) { return false; } return true; } /** * Returns the transformation of this color to the rgb color. *

* * @return the transformation of this color to the rgb color. */ public java.awt.Color getRGBColor() { final int rgb = java.awt.Color.HSBtoRGB((float) this.m_hue, (float) this.m_sat, (float) this.m_lum); // This does not work as it filters out the alpha channel! // return new java.awt.Color(rgb); final int r = (rgb & 0xff0000) >> 16; final int g = (rgb & 0x00ff00) >> 8; final int b = (rgb & 0x0000ff); return new java.awt.Color(r, g, b, (int) Math.round(this.m_alpha)); } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; long temp; temp = Double.doubleToLongBits(this.m_alpha); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(this.m_hue); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(this.m_lum); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(this.m_sat); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } }

Ads help maintain this website.