Java Color Value getDerivedColor(Color color, float ratio)

Here you can find the source of getDerivedColor(Color color, float ratio)

Description

Gets a derived color from an existing color.

License

Open Source License

Parameter

Parameter Description
color the given color.
ratio the ratio. 0.5f if the same color. Any ratio greater than 0.5f will make the result color lighter. Smaller than 0.5f will make the color darker.

Return

the derived color.

Declaration

public static Color getDerivedColor(Color color, float ratio) 

Method Source Code


//package com.java2s;
import javax.swing.plaf.ColorUIResource;
import java.awt.*;

public class Main {
    /**//  w w  w. j a va  2s .c om
     * Gets a derived color from an existing color. The derived color is either lighter or darker version of the given
     * color with the same hue.
     *
     * @param color the given color.
     * @param ratio the ratio. 0.5f if the same color. Any ratio greater than 0.5f will make the result color lighter.
     *              Smaller than 0.5f will make the color darker.
     *
     * @return the derived color.
     */
    public static Color getDerivedColor(Color color, float ratio) {
        if (color != null) {
            float[] hsl = RGBtoHSL(color);
            if (hsl[2] < 0.4) {
                hsl[2] = 0.4f;
            }
            if (ratio > 0.5) {
                hsl[2] += (1f - hsl[2]) * 2 * (ratio - 0.5);
            } else {
                hsl[2] -= hsl[2] * 2 * (0.5 - ratio);
            }
            int colorRGB = HSLtoRGB(hsl);
            return new ColorUIResource(colorRGB);
        } else {
            return null;
        }
    }

    /**
     * Converts a color from RBG to HSL color space.
     *
     * @param colorRGB the Color.
     *
     * @return color space in HSL.
     */
    public static float[] RGBtoHSL(Color colorRGB) {
        float r, g, b, h, s, l; //this function works with floats between 0 and 1
        r = colorRGB.getRed() / 256.0f;
        g = colorRGB.getGreen() / 256.0f;
        b = colorRGB.getBlue() / 256.0f;

        // Then, minColor and maxColor are defined. Min color is the value of the color component with
        // the smallest value, while maxColor is the value of the color component with the largest value.
        // These two variables are needed because the Lightness is defined as (minColor + maxColor) / 2.

        float maxColor = Math.max(r, Math.max(g, b));
        float minColor = Math.min(r, Math.min(g, b));

        // If minColor equals maxColor, we know that R=G=B and thus the color is a shade of gray.
        // This is a trivial case, hue can be set to anything, saturation has to be set to 0 because
        // only then it's a shade of gray, and lightness is set to R=G=B, the shade of the gray.

        //R == G == B, so it's a shade of gray
        if (r == g && g == b) {
            h = 0.0f; //it doesn't matter what value it has
            s = 0.0f;
            l = r; //doesn't matter if you pick r, g, or b
        }

        // If minColor is not equal to maxColor, we have a real color instead of a shade of gray, so more calculations are needed:

        // Lightness (l) is now set to it's definition of (minColor + maxColor)/2.
        // Saturation (s) is then calculated with a different formula depending if light is in the first half of the second half. This is because the HSL model can be represented as a double cone, the first cone has a black tip and corresponds to the first half of lightness values, the second cone has a white tip and contains the second half of lightness values.
        // Hue (h) is calculated with a different formula depending on which of the 3 color components is the dominating one, and then normalized to a number between 0 and 1.

        else {
            l = (minColor + maxColor) / 2;

            if (l < 0.5)
                s = (maxColor - minColor) / (maxColor + minColor);
            else
                s = (maxColor - minColor) / (2.0f - maxColor - minColor);

            if (r == maxColor)
                h = (g - b) / (maxColor - minColor);
            else if (g == maxColor)
                h = 2.0f + (b - r) / (maxColor - minColor);
            else
                h = 4.0f + (r - g) / (maxColor - minColor);

            h /= 6; //to bring it to a number between 0 and 1
            if (h < 0)
                h++;
        }

        // Finally, H, S and L are calculated out of h, s and l as integers between 0 and 255 and "returned"
        // as the result. Returned, because H, S and L were passed by reference to the function.

        float[] hsl = new float[3];
        hsl[0] = h;
        hsl[1] = s;
        hsl[2] = l;
        return hsl;
    }

    /**
     * Converts from HSL color space to RGB color.
     *
     * @param hsl the hsl values.
     *
     * @return the RGB color.
     */
    public static int HSLtoRGB(float[] hsl) {
        float r, g, b, h, s, l; //this function works with floats between 0 and 1
        float temp1, temp2, tempr, tempg, tempb;
        h = hsl[0];
        s = hsl[1];
        l = hsl[2];

        // Then follows a trivial case: if the saturation is 0, the color will be a grayscale color,
        // and the calculation is then very simple: r, g and b are all set to the lightness.

        //If saturation is 0, the color is a shade of gray
        if (s == 0) {
            r = g = b = l;
        }
        // If the saturation is higher than 0, more calculations are needed again.
        // red, green and blue are calculated with the formulas defined in the code.
        // If saturation > 0, more complex calculations are needed
        else {
            //Set the temporary values
            if (l < 0.5)
                temp2 = l * (1 + s);
            else
                temp2 = (l + s) - (l * s);
            temp1 = 2 * l - temp2;
            tempr = h + 1.0f / 3.0f;
            if (tempr > 1)
                tempr--;
            tempg = h;
            tempb = h - 1.0f / 3.0f;
            if (tempb < 0)
                tempb++;

            //Red
            if (tempr < 1.0 / 6.0)
                r = temp1 + (temp2 - temp1) * 6.0f * tempr;
            else if (tempr < 0.5)
                r = temp2;
            else if (tempr < 2.0 / 3.0)
                r = temp1 + (temp2 - temp1) * ((2.0f / 3.0f) - tempr) * 6.0f;
            else
                r = temp1;

            //Green
            if (tempg < 1.0 / 6.0)
                g = temp1 + (temp2 - temp1) * 6.0f * tempg;
            else if (tempg < 0.5)
                g = temp2;
            else if (tempg < 2.0 / 3.0)
                g = temp1 + (temp2 - temp1) * ((2.0f / 3.0f) - tempg) * 6.0f;
            else
                g = temp1;

            //Blue
            if (tempb < 1.0 / 6.0)
                b = temp1 + (temp2 - temp1) * 6.0f * tempb;
            else if (tempb < 0.5)
                b = temp2;
            else if (tempb < 2.0 / 3.0)
                b = temp1 + (temp2 - temp1) * ((2.0f / 3.0f) - tempb) * 6.0f;
            else
                b = temp1;
        }

        // And finally, the results are returned as integers between 0 and 255.

        int result = 0;
        result += ((int) (r * 255) & 0xFF) << 16;
        result += ((int) (g * 255) & 0xFF) << 8;
        result += ((int) (b * 255) & 0xFF);

        return result;
    }
}

Related

  1. getColorLabels(Object obj)
  2. getColorTercio(Color a, Color b)
  3. getColorValue(Element element, Object constant)
  4. getDefaultBackgroundColor()
  5. getDefaultBackgroundColor(Color color)
  6. getDisabledForeground(Color c)
  7. getDisabledLineColor()
  8. getFieldForegroundColor()
  9. getGripperForegroundColor(Color color)