[英]HSL to RGB color conversion problems
我喜欢随机生成-和随机颜色-因此我决定将两者结合起来,制作了一个简单的2D景观生成器。 我的想法是,根据块的高度,(是的,地形是由块组成的)使它变亮或变暗,最靠近顶部的事物变亮,而靠近底部的事物变暗。 我知道它是在灰度下工作的,但是正如我发现的那样,鉴于RGB值之间的比率或任何类似的值似乎不可用,您不能真正使用基本的RGB颜色并使它更亮。 解? HSL。 也许HSV,说实话,我仍然不知道两者之间的区别。 我指的是H 0-360,S&V / L = 0-100。 虽然...好吧,360 = 0,所以就是360个值,但是如果您实际上有0-100,那就是101。它真的是0-359和1-100(或0-99吗?),但是颜色选择编辑器(当前指的是GIMP ... MS paint具有超过100的饱和度)可以输入这些值吗?
无论如何,我找到了用于HSL-> RGB转换的公式( 在这里和这里 。据我所知,最终公式是相同的,但是尽管如此,我仍将提供代码(请注意,这是来自后者的easyrgb.com链接) :
色调_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 );
}
和另一段代码:
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 ) );
}
抱歉,不确定在这些空格上修复空白的好方法。
我用自己的名称,色相,饱和度和亮度替换了H,S,L值。 我回头看了一下,但是除非丢失了某些东西,否则请正确更换它。 但是,除了C ++所需的部分外,hue_2_RGB函数是完全未编辑的。 (例如变量类型)。 我以前也对所有内容都有整数(R,G,B,H,S,L),然后在我身上出现了……HSL是公式的浮点数,或者至少看起来应该是。 因此,我将变量(var_1,var_2,所有v,R,G,B,色相,饱和度,亮度)用于浮点数。 所以我不相信这是某种数据丢失错误。 此外,在输入公式之前,我的色相/ = 360,饱和度/ = 100,亮度/ =100。请注意,在此之前,我的色相= 59,饱和度= 100,亮度=70。我相信将色相权设置为360以确保0-1,但是尝试使用/ = 100也不能解决该问题。
所以,我的问题是,为什么公式不起作用? 谢谢您的帮助。
编辑:如果问题不清楚,请对此发表评论。
你的前提是错的。 您可以缩放RGB颜色。 例如,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);
}
简而言之,将所有三种颜色乘以相同的静态因子,您将获得相同的颜色比率。 这是一种有损操作,您需要确保将颜色卷曲以保持在范围内(这比舍入误差更大)。
坦率地说,任何将RGB转换为HSV都是数学运算,而更改HSV V因子只是数学运算,而将其更改回则是更多数学运算。 您不需要任何。 你可以做数学。 这将使最大成分颜色更大,而不会弄乱颜色之间的比率。
-
如果问题更具体,而您只是想要更好的结果。 有更好的方法来计算此值。 您可以将亮度转换为亮度分量,而不用静态缩放亮度(L不表示亮度)。 基本上以特定方式加权。 色彩科学和计算正在与人类观察者打交道,它们比实际数学更重要。 为了解决其中的一些怪癖,有必要“修正问题”,使其更类似于普通人的感知。 亮度缩放如下:
Y = 0.2126 R + 0.7152 G + 0.0722 B
同样地,在权重30、59、11中也反映了这一点,它们被错误地认为是良好的色距权重。 这些权重是颜色对人类对亮度的感知的贡献。 例如,人类看到的最亮的蓝色很暗。 而黄色(与蓝色恰好相反)被认为是如此明亮,以至于您甚至无法在白色背景下辨认出它。 包括的许多色彩空间Y'CbCr通过缩放解决了亮度感知方面的这些差异。 然后,您可以更改该值,并且在将其缩减时将再次进行缩放。
导致产生不同的颜色,这应该更类似于人类会说是相同颜色的“较浅”版本。 该人类系统的逼近性越来越好,因此使用更好和更高级的数学进行解释通常会为您带来越来越好的结果。
有关这些问题的概述。 http://www.compuphase.com/cmetric.htm
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.