Subversion Repositories distributed

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. package test.fraktal3d;
  2.  
  3. /*
  4.  * $Id: ColorUtilities.java 1496 2006-10-22 03:26:24Z gfx $
  5.  *
  6.  * Dual-licensed under LGPL (Sun and Romain Guy) and BSD (Romain Guy).
  7.  *
  8.  * Copyright 2005 Sun Microsystems, Inc., 4150 Network Circle,
  9.  * Santa Clara, California 95054, U.S.A. All rights reserved.
  10.  *
  11.  * Copyright (c) 2006 Romain Guy <romain.guy@mac.com>
  12.  * All rights reserved.
  13.  *
  14.  * Redistribution and use in source and binary forms, with or without
  15.  * modification, are permitted provided that the following conditions
  16.  * are met:
  17.  * 1. Redistributions of source code must retain the above copyright
  18.  *    notice, this list of conditions and the following disclaimer.
  19.  * 2. Redistributions in binary form must reproduce the above copyright
  20.  *    notice, this list of conditions and the following disclaimer in the
  21.  *    documentation and/or other materials provided with the distribution.
  22.  * 3. The name of the author may not be used to endorse or promote products
  23.  *    derived from this software without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  26.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  27.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  28.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  29.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  30.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  31.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  34.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35.  */
  36.  
  37. // package org.jdesktop.swingx.graphics;
  38.  
  39. import java.awt.Color;
  40.  
  41. /**
  42.  * <p><code>ColorUtilities</code> contains a set of tools to perform
  43.  * common color operations easily.</p>
  44.  *
  45.  * @author Romain Guy <romain.guy@mac.com>
  46.  */
  47. public class ColorUtilities {
  48.     private ColorUtilities() {
  49.     }
  50.  
  51.     /**
  52.      * <p>Returns the HSL (Hue/Saturation/Luminance) equivalent of a given
  53.      * RGB color. All three HSL components are between 0.0 and 1.0.</p>
  54.      *
  55.      * @param color the RGB color to convert
  56.      * @return a new array of 3 floats corresponding to the HSL components
  57.      */
  58.     public static float[] RGBtoHSL(Color color) {
  59.         return RGBtoHSL(color.getRed(), color.getGreen(), color.getBlue(), null);
  60.     }
  61.  
  62.     /**
  63.      * <p>Returns the HSL (Hue/Saturation/Luminance) equivalent of a given
  64.      * RGB color. All three HSL components are between 0.0 and 1.0.</p>
  65.      *
  66.      * @param color the RGB color to convert
  67.      * @param hsl a pre-allocated array of floats; can be null
  68.      * @return <code>hsl</code> if non-null, a new array of 3 floats otherwise
  69.      * @throws IllegalArgumentException if <code>hsl</code> has a length lower
  70.      *   than 3
  71.      */
  72.     public static float[] RGBtoHSL(Color color, float[] hsl) {
  73.         return RGBtoHSL(color.getRed(), color.getGreen(), color.getBlue(), hsl);
  74.     }
  75.  
  76.     /**
  77.      * <p>Returns the HSL (Hue/Saturation/Luminance) equivalent of a given
  78.      * RGB color. All three HSL components are between 0.0 and 1.0.</p>
  79.      *
  80.      * @param r the red component, between 0 and 255
  81.      * @param g the green component, between 0 and 255
  82.      * @param b the blue component, between 0 and 255
  83.      * @return a new array of 3 floats corresponding to the HSL components
  84.      */
  85.     public static float[] RGBtoHSL(int r, int g, int b) {
  86.         return RGBtoHSL(r, g, b, null);
  87.     }
  88.  
  89.     /**
  90.      * <p>Returns the HSL (Hue/Saturation/Luminance) equivalent of a given
  91.      * RGB color. All three HSL components are floats between 0.0 and 1.0.</p>
  92.      *
  93.      * @param r the red component, between 0 and 255
  94.      * @param g the green component, between 0 and 255
  95.      * @param b the blue component, between 0 and 255
  96.      * @param hsl a pre-allocated array of floats; can be null
  97.      * @return <code>hsl</code> if non-null, a new array of 3 floats otherwise
  98.      * @throws IllegalArgumentException if <code>hsl</code> has a length lower
  99.      *   than 3
  100.      */
  101.     public static float[] RGBtoHSL(int r, int g, int b, float[] hsl) {
  102.         if (hsl == null) {
  103.             hsl = new float[3];
  104.         } else if (hsl.length < 3) {
  105.             throw new IllegalArgumentException("hsl array must have a length of" +
  106.                                                " at least 3");
  107.         }
  108.  
  109.         if (r < 0) r = 0;
  110.         else if (r > 255) r = 255;
  111.         if (g < 0) g = 0;
  112.         else if (g > 255) g = 255;
  113.         if (b < 0) b = 0;
  114.         else if (b > 255) b = 255;
  115.  
  116.         float var_R = (r / 255f);
  117.         float var_G = (g / 255f);
  118.         float var_B = (b / 255f);
  119.  
  120.         float var_Min;
  121.         float var_Max;
  122.         float del_Max;
  123.  
  124.         if (var_R > var_G) {
  125.             var_Min = var_G;
  126.             var_Max = var_R;
  127.         } else {
  128.             var_Min = var_R;
  129.             var_Max = var_G;
  130.         }
  131.         if (var_B > var_Max) {
  132.             var_Max = var_B;
  133.         }
  134.         if (var_B < var_Min) {
  135.             var_Min = var_B;
  136.         }
  137.  
  138.         del_Max = var_Max - var_Min;
  139.  
  140.         float H, S, L;
  141.         L = (var_Max + var_Min) / 2f;
  142.  
  143.         if (del_Max - 0.01f <= 0.0f) {
  144.             H = 0;
  145.             S = 0;
  146.         } else {
  147.             if (L < 0.5f) {
  148.                 S = del_Max / (var_Max + var_Min);
  149.             } else {
  150.                 S = del_Max / (2 - var_Max - var_Min);
  151.             }
  152.  
  153.             float del_R = (((var_Max - var_R) / 6f) + (del_Max / 2f)) / del_Max;
  154.             float del_G = (((var_Max - var_G) / 6f) + (del_Max / 2f)) / del_Max;
  155.             float del_B = (((var_Max - var_B) / 6f) + (del_Max / 2f)) / del_Max;
  156.  
  157.             if (var_R == var_Max) {
  158.                 H = del_B - del_G;
  159.             } else if (var_G == var_Max) {
  160.                 H = (1 / 3f) + del_R - del_B;
  161.             } else {
  162.                 H = (2 / 3f) + del_G - del_R;
  163.             }
  164.             if (H < 0) {
  165.                 H += 1;
  166.             }
  167.             if (H > 1) {
  168.                 H -= 1;
  169.             }
  170.         }
  171.  
  172.         hsl[0] = H;
  173.         hsl[1] = S;
  174.         hsl[2] = L;
  175.  
  176.         return hsl;
  177.     }
  178.  
  179.     /**
  180.      * <p>Returns the RGB equivalent of a given HSL (Hue/Saturation/Luminance)
  181.      * color.</p>
  182.      *
  183.      * @param h the hue component, between 0.0 and 1.0
  184.      * @param s the saturation component, between 0.0 and 1.0
  185.      * @param l the luminance component, between 0.0 and 1.0
  186.      * @return a new <code>Color</code> object equivalent to the HSL components
  187.      */
  188.     public static Color HSLtoRGB(float h, float s, float l) {
  189.         int[] rgb = HSLtoRGB(h, s, l, null);
  190.         return new Color(rgb[0], rgb[1], rgb[2]);
  191.     }
  192.  
  193.     /**
  194.      * <p>Returns the RGB equivalent of a given HSL (Hue/Saturation/Luminance)
  195.      * color. All three RGB components are integers between 0 and 255.</p>
  196.      *
  197.      * @param h the hue component, between 0.0 and 1.0
  198.      * @param s the saturation component, between 0.0 and 1.0
  199.      * @param l the luminance component, between 0.0 and 1.0
  200.      * @param rgb a pre-allocated array of ints; can be null
  201.      * @return <code>rgb</code> if non-null, a new array of 3 ints otherwise
  202.      * @throws IllegalArgumentException if <code>rgb</code> has a length lower
  203.      *   than 3
  204.      */
  205.     public static int[] HSLtoRGB(float h, float s, float l, int[] rgb) {
  206.         if (rgb == null) {
  207.             rgb = new int[3];
  208.         } else if (rgb.length < 3) {
  209.             throw new IllegalArgumentException("rgb array must have a length of" +
  210.                                                " at least 3");
  211.         }
  212.  
  213.         if (h < 0) h = 0.0f;
  214.         else if (h > 1.0f) h = 1.0f;
  215.         if (s < 0) s = 0.0f;
  216.         else if (s > 1.0f) s = 1.0f;
  217.         if (l < 0) l = 0.0f;
  218.         else if (l > 1.0f) l = 1.0f;
  219.  
  220.         int R, G, B;
  221.  
  222.         if (s - 0.01f <= 0.0f) {
  223.             R = (int) (l * 255.0f);
  224.             G = (int) (l * 255.0f);
  225.             B = (int) (l * 255.0f);
  226.         } else {
  227.             float var_1, var_2;
  228.             if (l < 0.5f) {
  229.                 var_2 = l * (1 + s);
  230.             } else {
  231.                 var_2 = (l + s) - (s * l);
  232.             }
  233.             var_1 = 2 * l - var_2;
  234.  
  235.             R = (int) (255.0f * hue2RGB(var_1, var_2, h + (1.0f / 3.0f)));
  236.             G = (int) (255.0f * hue2RGB(var_1, var_2, h));
  237.             B = (int) (255.0f * hue2RGB(var_1, var_2, h - (1.0f / 3.0f)));
  238.         }
  239.  
  240.         rgb[0] = R;
  241.         rgb[1] = G;
  242.         rgb[2] = B;
  243.  
  244.         return rgb;
  245.     }
  246.  
  247.     private static float hue2RGB(float v1, float v2, float vH) {
  248.         if (vH < 0.0f) {
  249.             vH += 1.0f;
  250.         }
  251.         if (vH > 1.0f) {
  252.             vH -= 1.0f;
  253.         }
  254.         if ((6.0f * vH) < 1.0f) {
  255.             return (v1 + (v2 - v1) * 6.0f * vH);
  256.         }
  257.         if ((2.0f * vH) < 1.0f) {
  258.             return (v2);
  259.         }
  260.         if ((3.0f * vH) < 2.0f) {
  261.             return (v1 + (v2 - v1) * ((2.0f / 3.0f) - vH) * 6.0f);
  262.         }
  263.         return (v1);
  264.     }
  265. }
  266.