【问题标题】:How can I use the HSL colorspace in Java?如何在 Java 中使用 HSL 颜色空间?
【发布时间】:2011-03-01 04:07:33
【问题描述】:

我查看了 ColorSpace 类,发现常量 TYPE_HLS大概只是 HSL 的顺序不同)。

我可以使用这个常量从色相、饱和度和亮度创建Color 吗? 如果没有,是否有任何 Java 类,或者我需要自己编写?

【问题讨论】:

  • 下面给出的“最佳”答案是错误的。 HSB 与 HSL 不同。你最终会得到比你预期的更暗的颜色。我在下面添加了 HLS (HSL) 的示例实现。

标签: java color-space hsl


【解决方案1】:

这里给出的大多数答案似乎都假设 HSL == HSB,这是错误的。 HSB 颜色空间在许多情况下都很有用(并且被使用),但有一个值得注意的例外:CSS。非 RGB css 颜色函数 hsl() 和 hsla() 是 HSL,而不是 HSB。因此,能够在 java 中与 HSL 相互转换非常有用。

这里有一篇关于这个问题的好文章:http://tips4java.wordpress.com/2009/07/05/hsl-color/ TL;DR:代码在这里:http://www.camick.com/java/source/HSLColor.java

我已经创建了一个 gist 备份,如果博客出现故障:https://gist.github.com/Yona-Appletree/0c4b58763f070ae8cdff7db583c82563

如果您不想使用整个类,其中的方法很容易提取。

许可证

该代码似乎在公共领域,如博客的“关于”页面 (https://tips4java.wordpress.com/about/) 中所述:

We assume no responsibility for the code. You are free to use and/or modify and/or distribute any or all code posted on the Java Tips Weblog without restriction. A credit in the code comments would be nice, but not in any way mandatory.

【讨论】:

    【解决方案2】:

    编辑:我意识到 HSB != HSL,下面的答案是 HSB。

    我认为这里不需要使用 ColorSpaces。尝试以下方法:

    float hue = 0.9f; //hue
    float saturation = 1.0f; //saturation
    float brightness = 0.8f; //brightness
    
    Color myRGBColor = Color.getHSBColor(hue, saturation, brightness);
    

    【讨论】:

    • 请注意,B实际上是“亮度”,而不是亮度/亮度,是HSV色彩空间“值”属性的另一种说法。
    【解决方案3】:

    这是一个简单的实现,它将根据从 0.0 到 1.0 的色调、饱和度和亮度值返回颜色...

    static public Color hslColor(float h, float s, float l) {
        float q, p, r, g, b;
    
        if (s == 0) {
            r = g = b = l; // achromatic
        } else {
            q = l < 0.5 ? (l * (1 + s)) : (l + s - l * s);
            p = 2 * l - q;
            r = hue2rgb(p, q, h + 1.0f / 3);
            g = hue2rgb(p, q, h);
            b = hue2rgb(p, q, h - 1.0f / 3);
        }
        return new Color(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255));
    }
    

    由 Yona-Appletree 编辑:

    我找到了我认为正确的 hue2rgb 函数并对其进行了测试:

    private static float hue2rgb(float p, float q, float 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;
    }
    

    【讨论】:

    • 这个答案没有hue2rgb是没用的。
    • @xtempore 如果您还在,请提供缺少的功能。
    • @YonaAppletree 感谢您添加缺少的功能!我一直在寻找我的旧项目,但很高兴看到您已经找到了一个实现。
    【解决方案4】:

    找到了HSB的内置方法(和HSL不一样,但是差不多)

    [Color.getHSBColor(float h, float s, float b)](http://docs.oracle.com/javase/7/docs/api/java/awt/Color.html#getHSBColor(float,% 20float,%20float))

    【讨论】:

    • 嗯,HSB 与 HSL 并不完全相同。
    • 例如Color.getHSBColor(0, 1, 1) 会返回红色,但如果你想要 (H=0, S=1, L=1) 的颜色,你应该得到白色。
    • @Andrei:确实。 en.wikipedia.org/wiki/HSL_and_HSV:“HSV 代表色相、饱和度和亮度,通常也称为 HSB(B 代表亮度)。”
    • @downvoters:为什么这会得到downvotes,但页面顶部的getupvotes 却是相同的和后来的答案?
    • 这是个好问题。在编写问题时,您的答案和投票最高的答案实际上都是不正确的,假设 HSL == HSB。我在下面发布了一个答案,其中包含一篇关于 HSL(不是 HSB)的好文章的链接。
    【解决方案5】:

    也许this 会有所帮助。当想要在另一个颜色空间中使用颜色时,JDK 似乎不是很有帮助。

    编辑:ColorSpace.getName(idx) 中有这个小 sn-p:

     case ColorSpace.TYPE_HLS:
                        compName = new String[] {"Hue", "Lightness", 
                                                 "Saturation"};
    

    所以这就是您的想法,但是看看 ColorSpace 的类型层次结构,它似乎并没有在任何地方以任何方式使用或实现。 ColorSpace 仅由 BogusColorSpace 和 ICC_ColorSpace 两个其他类扩展,所以我猜他们希望开发人员为不同的颜色空间创建自己的实现。

    【讨论】:

      【解决方案6】:

      如果您的输入是 swing/awt 小部件,那么使用 Java 7 JColorChooser 您可以通过 HSV 和 HSL 空间获取颜色。 http://java.dzone.com/articles/new-color-chooser-jdk-7

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-04
        • 2012-07-08
        • 2012-06-29
        • 2020-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-31
        相关资源
        最近更新 更多