简体   繁体   English

HSL到RGB颜色转换问题

[英]HSL to RGB color conversion problems

I am fond of random generation - and random colors - so I decided to combine them both and made a simple 2d landscape generator. 我喜欢随机生成-​​和随机颜色-因此我决定将两者结合起来,制作了一个简单的2D景观生成器。 What my idea was is to, depending on how high a block is, (yes, the terrain is made of blocks) make it lighter or darker, where things nearest the top are lighter, and towards the bottom are darker. 我的想法是,根据块的高度,(是的,地形是由块组成的)使它变亮或变暗,最靠近顶部的事物变亮,而靠近底部的事物变暗。 I got it working in grayscale, but as I figured out, you cannot really use a base RGB color and make it lighter, given that the ratio between RGB values, or anything of the sort, seem to be unusable. 我知道它是在灰度下工作的,但是正如我发现的那样,鉴于RGB值之间的比率或任何类似的值似乎不可用,您不能真正使用基本的RGB颜色并使它更亮。 Solution? 解? HSL. HSL。 Or perhaps HSV, to be honest I still don't know the difference. 也许HSV,说实话,我仍然不知道两者之间的区别。 I am referring to H 0-360, S & V/L = 0-100. 我指的是H 0-360,S&V / L = 0-100。 Although... well, 360 = 0, so that is 360 values, but if you actually have 0-100, that is 101. Is it really 0-359 and 1-100 (or 0-99?), but color selection editors (currently referring to GIMP... MS paint had over 100 saturation) allow you to input such values? 虽然...好吧,360 = 0,所以就是360个值,但是如果您实际上有0-100,那就是101。它真的是0-359和1-100(或0-99吗?),但是颜色选择编辑器(当前指的是GIMP ... MS paint具有超过100的饱和度)可以输入这些值吗?

Anyhow, I found a formula for HSL->RGB conversion ( here & here . As far as I know, the final formulas are the same, but nonetheless I will provide the code (note that this is from the latter easyrgb.com link): 无论如何,我找到了用于HSL-> RGB转换的公式( 在这里这里 。据我所知,最终公式是相同的,但是尽管如此,我仍将提供代码(请注意,这是来自后者的easyrgb.com链接) :

Hue_2_RGB 色调_2_RGB

float Hue_2_RGB(float v1, float v2, float vH)             //Function Hue_2_RGB
{
if ( vH < 0 )
    vH += 1;

if ( vH > 1 )
    vH -= 1;

if ( ( 6 * vH ) < 1 )
    return ( v1 + ( v2 - v1 ) * 6 * vH );

if ( ( 2 * vH ) < 1 )
    return ( v2 );

if ( ( 3 * vH ) < 2 )
    return ( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6 );

return ( v1 );
}

and the other piece of code: 和另一段代码:

float var_1 = 0, var_2 = 0;

        if (saturation == 0)                       //HSL from 0 to 1
        {
           red = luminosity * 255;                      //RGB results from 0 to 255
           green = luminosity * 255;
           blue = luminosity * 255;
        }
        else
        {
            if ( luminosity < 0.5 )
                var_2 = luminosity * (1 + saturation);
            else
                var_2 = (luminosity + saturation) - (saturation * luminosity);

            var_1 = 2 * luminosity - var_2;

            red = 255 * Hue_2_RGB(var_1, var_2, hue + ( 1 / 3 ) );
            green = 255 * Hue_2_RGB( var_1, var_2, hue );
            blue = 255 * Hue_2_RGB( var_1, var_2, hue - ( 1 / 3 ) );
        }

Sorry, not sure of a good way to fix the whitespace on those. 抱歉,不确定在这些空格上修复空白的好方法。

I replaced H, S, L values with my own names, hue, saturation, and luminosity. 我用自己的名称,色相,饱和度和亮度替换了H,S,L值。 I looked it back over, but unless I am missing something I replaced it correctly. 我回头看了一下,但是除非丢失了某些东西,否则请正确更换它。 The hue_2_RGB function, though, is completely unedited, besides the parts needed for C++. 但是,除了C ++所需的部分外,hue_2_RGB函数是完全未编辑的。 (eg variable type). (例如变量类型)。 I also used to have ints for everything - R, G, B, H, S, L - then it occured to me... HSL was a floating point for the formula - or at least, it would seem it should be. 我以前也对所有内容都有整数(R,G,B,H,S,L),然后在我身上出现了……HSL是公式的浮点数,或者至少看起来应该是。 So I made variable used (var_1, var_2, all the v's, R, G, B, hue, saturation, luminosity) to floats. 因此,我将变量(var_1,var_2,所有v,R,G,B,色相,饱和度,亮度)用于浮点数。 So I don't beleive it is some sort of data loss error here. 所以我不相信这是某种数据丢失错误。 Additionally, before entering the formula, I have hue /= 360, saturation /= 100, and luminosity /= 100. Note that before that point, I have hue = 59, saturation = 100, and luminosity = 70. I believe I got the hue right as 360 to ensure 0-1, but trying /= 100 didn't fix it either. 此外,在输入公式之前,我的色相/ = 360,饱和度/ = 100,亮度/ =100。请注意,在此之前,我的色相= 59,饱和度= 100,亮度=70。我相信将色相权设置为360以确保0-1,但是尝试使用/ = 100也不能解决该问题。

and so, my question is, why is the formula not working? 所以,我的问题是,为什么公式不起作用? Thanks if you can help. 谢谢您的帮助。

EDIT: if the question is not clear, please comment on it. 编辑:如果问题不清楚,请对此发表评论。

Your premise is wrong. 你的前提是错的。 You can just scale the RGB color. 您可以缩放RGB颜色。 The Color class in Java for example includes commands called .darker() and .brighter(), these use a factor of .7 but you can use anything you want. 例如,Java中的Color类包含名为.darker()和.brighter()的命令,它们使用的系数是.7,但是您可以使用任何所需的命令。

public Color darker() {
    return new Color(Math.max((int)(getRed()  *FACTOR), 0),
                     Math.max((int)(getGreen()*FACTOR), 0),
                     Math.max((int)(getBlue() *FACTOR), 0),
                     getAlpha());
}

public Color brighter() {
    int r = getRed();
    int g = getGreen();
    int b = getBlue();
    int alpha = getAlpha();

    /* From 2D group:
     * 1. black.brighter() should return grey
     * 2. applying brighter to blue will always return blue, brighter
     * 3. non pure color (non zero rgb) will eventually return white
     */
    int i = (int)(1.0/(1.0-FACTOR));
    if ( r == 0 && g == 0 && b == 0) {
        return new Color(i, i, i, alpha);
    }
    if ( r > 0 && r < i ) r = i;
    if ( g > 0 && g < i ) g = i;
    if ( b > 0 && b < i ) b = i;

    return new Color(Math.min((int)(r/FACTOR), 255),
                     Math.min((int)(g/FACTOR), 255),
                     Math.min((int)(b/FACTOR), 255),
                     alpha);
}

In short, multiply all three colors by the same static factor and you will have the same ratio of colors. 简而言之,将所有三种颜色乘以相同的静态因子,您将获得相同的颜色比率。 It's a lossy operation and you need to be sure to crimp the colors to stay in range (which is more lossy than the rounding error). 这是一种有损操作,您需要确保将颜色卷曲以保持在范围内(这比舍入误差更大)。

Frankly any conversion to RGB to HSV is just math, and changing the HSV V factor is just math and changing it back is more math. 坦率地说,任何将RGB转换为HSV都是数学运算,而更改HSV V因子只是数学运算,而将其更改回则是更多数学运算。 You don't need any of that. 您不需要任何。 You can just do the math. 你可以做数学。 Which is going to be make the max component color greater without messing up the ratio between the colors. 这将使最大成分颜色更大,而不会弄乱颜色之间的比率。

-- -

If the question is more specific and you simply want better results. 如果问题更具体,而您只是想要更好的结果。 There are better ways to calculate this. 有更好的方法来计算此值。 You rather than static scaling the lightness (L does not refer to luminosity) you can convert to a luma component. 您可以将亮度转换为亮度分量,而不用静态缩放亮度(L不表示亮度)。 Which is basically weighted in a specific way. 基本上以特定方式加权。 Color science and computing is dealing with human observers and they are more important than the actual math. 色彩科学和计算正在与人类观察者打交道,它们比实际数学更重要。 To account for some of these human quirks there's a need to "fix things" to be more similar to what the average human perceives. 为了解决其中的一些怪癖,有必要“修正问题”,使其更类似于普通人的感知。 Luma scales as follows: 亮度缩放如下:

Y = 0.2126 R + 0.7152 G + 0.0722 B Y = 0.2126 R + 0.7152 G + 0.0722 B

This similarly is reflected in the weights 30,59,11 which are wrongly thought to be good color distance weights. 同样地,在权重30、59、11中也反映了这一点,它们被错误地认为是良好的色距权重。 These weighs are the color's contribution to the human perception of brightness. 这些权重是颜色对人类对亮度的感知的贡献。 For example the brightest blue is seen by humans to be pretty dark. 例如,人类看到的最亮的蓝色很暗。 Whereas yellow (exactly opposed to blue) is seen to be so damned bright that you can't even make it out against a white background. 而黄色(与蓝色恰好相反)被认为是如此明亮,以至于您甚至无法在白色背景下辨认出它。 A number of colorspaces Y'CbCr included account for these differences in perception of lightness by scaling. 包括的许多色彩空间Y'CbCr通过缩放解决了亮度感知方面的这些差异。 Then you can change that value and it will be scaled again when you scale it back. 然后,您可以更改该值,并且在将其缩减时将再次进行缩放。

Resulting in a different color, which should be more akin to what humans would say is a "lighter" version of the same color. 导致产生不同的颜色,这应该更类似于人类会说是相同颜色的“较浅”版本。 There are better and better approximations of this human system and so using better and fancier math to account for it will typically give you better and better results. 该人类系统的逼近性越来越好,因此使用更好和更高级的数学进行解释通常会为您带来越来越好的结果。

For a good overview that touches on these issues. 有关这些问题的概述。 http://www.compuphase.com/cmetric.htm http://www.compuphase.com/cmetric.htm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM