簡體   English   中英

HSL到RGB顏色轉換問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM