JavaFX Color против HSL Web определений - PullRequest
0 голосов
/ 05 марта 2019

Я реализую графический генератор и что-то заметил - давайте назовем это странным?

WEB: HSLA - стандарт цвета, где палитры цветов 1 доступны, и вы даже можете проверить эти цвета на html в качестве фона color.

например: (один) представление белого: hsla (270, 100%, 100%, 1)

мой графический генератор создает свои цвета с помощью HSLA Модель в JavaFX, и я заметил, что цвет (белый) - это не тот цвет, который я получаю в обычной сети HSLA Модель - (Google Chrome)

Даже JavaDoc говорит:

Color c = Color.web("hsla(270,100%,100%,1.0)");// blue as an hsl web value, explicit alpha

что здесь не так?я что-то путаю?Это ошибка или функция?

ОБНОВЛЕНИЕ: HTML Web HSLA

<!DOCTYPE html>
<html>
<head>
<style>
#p1 {background-color:hsla(0,100%,100%,1);}
#p2 {background-color:hsla(270,100%,100%,1);}
</style>
</head>

<body>
<p>HSL colors with opacity:</p>
<p id="p1">JavaFX red is white in web</p>
<p id="p2">JavaFX blue is white in web</p>
</body>
</html>

и вот пример JavaFX, который демонстрирует «функцию» - обратите внимание, что я реализовал пользовательский HSLAColor, который вычисляетправильное значение (также продемонстрированное в этом приложении

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class HslaWorld extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Hello HSLA World!");

        VBox box = new VBox();

        Label red = new Label("JavaFX HSLA red is white in web");
        red.setMaxWidth(Double.MAX_VALUE);
        red.setStyle("-fx-background-color: " + toHex(Color.web("hsla(0,100%,100%,1.0)")));

        Label blue = new Label("JavaFX HSLA blue is white in web");
        blue.setMaxWidth(Double.MAX_VALUE);
        blue.setStyle("-fx-background-color: " + toHex(Color.web("hsla(270,100%,100%,1.0)")));

        box.getChildren().addAll(red, blue);
        {
            Label redfixed = new Label("Custom HSLA is white in web");
            redfixed.setMaxWidth(Double.MAX_VALUE);
            redfixed.setStyle("-fx-background-color: " + toHex(new HSLColor(0, 100, 100, 1.0).getColor()));

            Label bluefixed = new Label("Custom HSLA is white in web");
            bluefixed.setMaxWidth(Double.MAX_VALUE);
            bluefixed.setStyle("-fx-background-color: " + toHex(new HSLColor(270, 100, 100, 1.0).getColor()));

            box.getChildren().addAll(redfixed, bluefixed);
        }

        primaryStage.setScene(new Scene(box, 300, 250));
        primaryStage.show();
    }

    private static String toHex(Color c) {
        return "#" + Integer.toHexString(c.hashCode());
    }
}


import javafx.scene.paint.Color;

/**
 * The HSLColor class provides methods to manipulate HSL (Hue, Saturation
 * Luminance) values to create a corresponding Color object using the RGB
 * ColorSpace.
 *
 * The HUE is the color, the Saturation is the purity of the color (with respect
 * to grey) and Luminance is the brightness of the color (with respect to black
 * and white)
 *
 * The Hue is specified as an angel between 0 - 360 degrees where red is 0,
 * green is 120 and blue is 240. In between you have the colors of the rainbow.
 * Saturation is specified as a percentage between 0 - 100 where 100 is fully
 * saturated and 0 approaches gray. Luminance is specified as a percentage
 * between 0 - 100 where 0 is black and 100 is white.
 *
 * In particular the HSL color space makes it easier change the Tone or Shade of
 * a color by adjusting the luminance value.
 */
public class HSLColor {

    private Color rgb;
    private double[] hsl;
    private double alpha;

    /**
     * Create a HSLColor object using an RGB Color object.
     *
     * @param rgb
     *            the RGB Color object
     */
    public HSLColor(Color rgb) {
        this.rgb = rgb;
        hsl = fromRGB(rgb);
        alpha = rgb.getOpacity() / 255.0f;
    }

    /**
     * Create a HSLColor object using individual HSL values and a default alpha
     * value of 1.0.
     *
     * @param h
     *            is the Hue value in degrees between 0 - 360
     * @param s
     *            is the Saturation percentage between 0 - 100
     * @param l
     *            is the Lumanance percentage between 0 - 100
     */
    public HSLColor(double h, double s, double l) {
        this(h, s, l, 1.0f);
    }

    /**
     * Create a HSLColor object using individual HSL values.
     *
     * @param h
     *            the Hue value in degrees between 0 - 360
     * @param s
     *            the Saturation percentage between 0 - 100
     * @param l
     *            the Lumanance percentage between 0 - 100
     * @param alpha
     *            the alpha value between 0 - 1
     */
    public HSLColor(double h, double s, double l, double alpha) {
        hsl = new double[] { h, s, l };
        this.alpha = alpha;
        rgb = toRGB(hsl, alpha);
    }

    /**
     * Create a HSLColor object using an an array containing the individual HSL
     * values and with a default alpha value of 1.
     *
     * @param hsl
     *            array containing HSL values
     */
    public HSLColor(double[] hsl) {
        this(hsl, 1.0f);
    }

    /**
     * Create a HSLColor object using an an array containing the individual HSL
     * values.
     *
     * @param hsl
     *            array containing HSL values
     * @param alpha
     *            the alpha value between 0 - 1
     */
    public HSLColor(double[] hsl, double alpha) {
        this.hsl = hsl;
        this.alpha = alpha;
        rgb = toRGB(hsl, alpha);
    }

    /**
     * Create a RGB Color object based on this HSLColor with a different Hue
     * value. The degrees specified is an absolute value.
     *
     * @param degrees
     *            - the Hue value between 0 - 360
     * @return the RGB Color object
     */
    public Color adjustHue(double degrees) {
        return toRGB(degrees, hsl[1], hsl[2], alpha);
    }

    /**
     * Create a RGB Color object based on this HSLColor with a different
     * Luminance value. The percent specified is an absolute value.
     *
     * @param percent
     *            - the Luminance value between 0 - 100
     * @return the RGB Color object
     */
    public Color adjustLuminance(double percent) {
        return toRGB(hsl[0], hsl[1], percent, alpha);
    }

    /**
     * Create a RGB Color object based on this HSLColor with a different
     * Saturation value. The percent specified is an absolute value.
     *
     * @param percent
     *            - the Saturation value between 0 - 100
     * @return the RGB Color object
     */
    public Color adjustSaturation(double percent) {
        return toRGB(hsl[0], percent, hsl[2], alpha);
    }

    /**
     * Create a RGB Color object based on this HSLColor with a different Shade.
     * Changing the shade will return a darker color. The percent specified is a
     * relative value.
     *
     * @param percent
     *            - the value between 0 - 100
     * @return the RGB Color object
     */
    public Color adjustShade(double percent) {
        double multiplier = (100.0f - percent) / 100.0f;
        double l = Math.max(0.0f, hsl[2] * multiplier);

        return toRGB(hsl[0], hsl[1], l, alpha);
    }

    /**
     * Create a RGB Color object based on this HSLColor with a different Tone.
     * Changing the tone will return a lighter color. The percent specified is a
     * relative value.
     *
     * @param percent
     *            - the value between 0 - 100
     * @return the RGB Color object
     */
    public Color adjustTone(double percent) {
        double multiplier = (100.0f + percent) / 100.0f;
        double l = Math.min(100.0f, hsl[2] * multiplier);

        return toRGB(hsl[0], hsl[1], l, alpha);
    }

    /**
     * Get the Alpha value.
     *
     * @return the Alpha value.
     */
    public double getAlpha() {
        return alpha;
    }

    /**
     * Create a RGB Color object that is the complementary color of this
     * HSLColor. This is a convenience method. The complementary color is
     * determined by adding 180 degrees to the Hue value.
     * 
     * @return the RGB Color object
     */
    public Color getComplementary() {
        double hue = (hsl[0] + 180.0f) % 360.0f;
        return toRGB(hue, hsl[1], hsl[2]);
    }

    /**
     * Get the Hue value.
     *
     * @return the Hue value.
     */
    public double getHue() {
        return hsl[0];
    }

    /**
     * Get the HSL values.
     *
     * @return the HSL values.
     */
    public double[] getHSL() {
        return hsl;
    }

    /**
     * Get the Luminance value.
     *
     * @return the Luminance value.
     */
    public double getLuminance() {
        return hsl[2];
    }

    /**
     * Get the RGB Color object represented by this HDLColor.
     *
     * @return the RGB Color object.
     */
    public Color getColor() {
        return rgb;
    }

    /**
     * Get the Saturation value.
     *
     * @return the Saturation value.
     */
    public double getSaturation() {
        return hsl[1];
    }

    public String toString() {
        String toString = "HSLColor[h=" + hsl[0] + ",s=" + hsl[1] + ",l=" + hsl[2] + ",alpha=" + alpha + "]";

        return toString;
    }

    /**
     * Convert a RGB Color to it corresponding HSL values.
     *
     * @return an array containing the 3 HSL values.
     */
    public static double[] fromRGB(Color color) {
        // Get RGB values in the range 0 - 1

        // double[] rgb = new double[]{};
        double r = color.getRed();
        double g = color.getGreen();
        double b = color.getBlue();

        // Minimum and Maximum RGB values are used in the HSL calculations

        double min = Math.min(r, Math.min(g, b));
        double max = Math.max(r, Math.max(g, b));

        // Calculate the Hue

        double h = 0.0;

        if (max == min)
            h = 0.0;
        else if (max == r)
            h = ((60.0 * (g - b) / (max - min)) + 360.0) % 360.0;
        else if (max == g)
            h = (60.0 * (b - r) / (max - min)) + 120.0;
        else if (max == b)
            h = (60.0 * (r - g) / (max - min)) + 240.0;

        // Calculate the Luminance

        double l = (max + min) / 2.0;

        // Calculate the Saturation

        double s = 0;

        if (max == min)
            s = 0;
        else if (l <= .5f)
            s = (max - min) / (max + min);
        else
            s = (max - min) / (2 - max - min);

        return new double[] { h, s * 100, l * 100 };
    }

    /**
     * Convert HSL values to a RGB Color with a default alpha value of 1. H
     * (Hue) is specified as degrees in the range 0 - 360. S (Saturation) is
     * specified as a percentage in the range 1 - 100. L (Lumanance) is
     * specified as a percentage in the range 1 - 100.
     *
     * @param hsl
     *            an array containing the 3 HSL values
     *
     * @returns the RGB Color object
     */
    public static Color toRGB(double[] hsl) {
        return toRGB(hsl, 1.0f);
    }

    /**
     * Convert HSL values to a RGB Color. H (Hue) is specified as degrees in the
     * range 0 - 360. S (Saturation) is specified as a percentage in the range 1
     * - 100. L (Lumanance) is specified as a percentage in the range 1 - 100.
     *
     * @param hsl
     *            an array containing the 3 HSL values
     * @param alpha
     *            the alpha value between 0 - 1
     *
     * @returns the RGB Color object
     */
    public static Color toRGB(double[] hsl, double alpha) {
        return toRGB(hsl[0], hsl[1], hsl[2], alpha);
    }

    /**
     * Convert HSL values to a RGB Color with a default alpha value of 1.
     *
     * @param h
     *            Hue is specified as degrees in the range 0 - 360.
     * @param s
     *            Saturation is specified as a percentage in the range 1 - 100.
     * @param l
     *            Lumanance is specified as a percentage in the range 1 - 100.
     *
     * @returns the RGB Color object
     */
    public static Color toRGB(double h, double s, double l) {
        return toRGB(h, s, l, 1.0f);
    }

    /**
     * Convert HSL values to a RGB Color.
     *
     * @param h
     *            Hue is specified as degrees in the range 0 - 360.
     * @param s
     *            Saturation is specified as a percentage in the range 1 - 100.
     * @param l
     *            Lumanance is specified as a percentage in the range 1 - 100.
     * @param alpha
     *            the alpha value between 0 - 1
     *
     * @returns the RGB Color object
     */
    public static Color toRGB(double h, double s, double l, double alpha) {
        if (s < 0.0f || s > 100.0f) {
            String message = "Color parameter outside of expected range - Saturation";
            throw new IllegalArgumentException(message);
        }

        if (l < 0.0f || l > 100.0f) {
            String message = "Color parameter outside of expected range - Luminance";
            throw new IllegalArgumentException(message);
        }

        if (alpha < 0.0f || alpha > 1.0f) {
            String message = "Color parameter outside of expected range - Alpha";
            throw new IllegalArgumentException(message);
        }

        // Formula needs all values between 0 - 1.

        h = h % 360.0f;
        h /= 360f;
        s /= 100f;
        l /= 100f;

        double q = 0;

        if (l < 0.5)
            q = l * (1 + s);
        else
            q = (l + s) - (s * l);

        double p = 2 * l - q;

        double r = Math.max(0, HueToRGB(p, q, h + (1.0f / 3.0f)));
        double g = Math.max(0, HueToRGB(p, q, h));
        double b = Math.max(0, HueToRGB(p, q, h - (1.0f / 3.0f)));

        r = Math.min(r, 1.0f);
        g = Math.min(g, 1.0f);
        b = Math.min(b, 1.0f);

        return new Color(r, g, b, alpha);
    }

    private static double HueToRGB(double p, double q, double h) {
        if (h < 0)
            h += 1;

        if (h > 1)
            h -= 1;

        if (6 * h < 1) {
            return p + ((q - p) * 6 * h);
        }

        if (2 * h < 1) {
            return q;
        }

        if (3 * h < 2) {
            return p + ((q - p) * 6 * ((2.0f / 3.0f) - h));
        }

        return p;
    }
}

'Решение' - это пользовательское преобразование, упомянутое выше как:

Кажется, что Java на самом деле анализируется в HSV, а не в сети.HSL, как указано в документе и название метода.

...