如何根据另一种颜色计算某种颜色?

时间:2011-11-04 14:03:31

标签: php javascript math colors

例如,我有一个蓝色:

#049cd9rgba(4, 156, 218)

如何计算相应的颜色,在这种情况下它会是深蓝色:

#004ea0rgba(0, 78, 160)

通常我不知道第二种颜色(我想知道的),所以我想找到一种方法来获得基于第一种颜色的较暗颜色。

enter image description here

是否有某种公式或某种东西可以通过以某种方式减去两种颜色来生成?


所以我找到了HEX to HSL and HSL to HEX functions

function hex_to_hue($hexcode)
{
    $redhex  = substr($hexcode,0,2);
    $greenhex = substr($hexcode,2,2);
    $bluehex = substr($hexcode,4,2);

    // $var_r, $var_g and $var_b are the three decimal fractions to be input to our RGB-to-HSL conversion routine
    $var_r = (hexdec($redhex)) / 255;
    $var_g = (hexdec($greenhex)) / 255;
    $var_b = (hexdec($bluehex)) / 255;

    // Input is $var_r, $var_g and $var_b from above
    // Output is HSL equivalent as $h, $s and $l — these are again expressed as fractions of 1, like the input values

    $var_min = min($var_r,$var_g,$var_b);
    $var_max = max($var_r,$var_g,$var_b);
    $del_max = $var_max - $var_min;

    $l = ($var_max + $var_min) / 2;

    if ($del_max == 0) {
        $h = 0;
        $s = 0;
    } else {
        if ($l < 0.5) {
            $s = $del_max / ($var_max + $var_min);
        } else {
            $s = $del_max / (2 - $var_max - $var_min);
        }
        ;

        $del_r = ((($var_max - $var_r) / 6) + ($del_max / 2)) / $del_max;
        $del_g = ((($var_max - $var_g) / 6) + ($del_max / 2)) / $del_max;
        $del_b = ((($var_max - $var_b) / 6) + ($del_max / 2)) / $del_max;

        if ($var_r == $var_max) {
            $h = $del_b - $del_g;
        } else if ($var_g == $var_max) {
            $h = (1 / 3) + $del_r - $del_b;
        } else if ($var_b == $var_max) {
            $h = (2 / 3) + $del_g - $del_r;
        }
        ;

        if ($h < 0) {
            $h += 1;
        }
        ;

        if ($h > 1) {
            $h -= 1;
        }
        ;
    }
    ;

    return array($h, $s, $l);

    /*
// Calculate the opposite hue, $h2
$h2 = $h + 0.5;
if ($h2 > 1)
{
$h2 -= 1;
};

return array($h2, $s, $l);
*/

}



function hue_to_hex($hue = array())
{
    function hue_2_rgb($v1,$v2,$vh)
    {
        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);
    }
    ;


    list($h2, $s, $l) = $hue;

    // Input is HSL value of complementary colour, held in $h2, $s, $l as fractions of 1
    // Output is RGB in normal 255 255 255 format, held in $r, $g, $b
    // Hue is converted using function hue_2_rgb, shown at the end of this code

    if ($s == 0) {
        $r = $l * 255;
        $g = $l * 255;
        $b = $l * 255;
    } else {
        if ($l < 0.5) {
            $var_2 = $l * (1 + $s);
        } else {
            $var_2 = ($l + $s) - ($s * $l);
        }
        ;

        $var_1 = 2 * $l - $var_2;
        $r = 255 * hue_2_rgb($var_1,$var_2,$h2 + (1 / 3));
        $g = 255 * hue_2_rgb($var_1,$var_2,$h2);
        $b = 255 * hue_2_rgb($var_1,$var_2,$h2 - (1 / 3));
    }
    ;


    $rhex = sprintf("%02X",round($r));
    $ghex = sprintf("%02X",round($g));
    $bhex = sprintf("%02X",round($b));

    return $rhex.$ghex.$bhex;
}

他们工作是因为我通过来回转换颜色来测试它们。

但我不知道如何像在Photoshop中一样更改Hue和Luminosity属性? 深色为H +13和L -28。

上面的hex_to_hsl函数返回0到1之间的浮点值......

5 个答案:

答案 0 :(得分:4)

有一些公式可以将RGB颜色转换为HSV(色调,饱和度和值)。从HSV,您可以更改任何HSV组件,然后转换回RGB。我在网上找到了东西并且之前做过这件事。如果您想了解算法的详细信息,请告诉我。如果您愿意,我可以为您挖掘它们。

答案 1 :(得分:1)

#XXXXXX表示RED,GREEN和BLUE颜色的六进制十进制数,如果增加数字,则从左到右每两个字符,如果减少数字,它将变暗。

答案 2 :(得分:1)

您需要将RGB值转换为HSL或HSV,然后您可以根据需要减小L(亮度)或V(值)分量,然后转换回RGB。

请参阅此答案以获取示例代码: RGB to HSV in PHP

答案 3 :(得分:1)

修补颜色​​感知方式(即更亮,更暗,更亮,更暗淡等)的最简单方法是将其转换为HSL。网上有大量资源可以将RGB转换为HSL,然后再转发回PHPJavaScript。 Google会根据您的需要为您找到尽可能多的实施。然后减少亮度,减少L值(乘以0.75或类似值)并转换回RGB。

答案 4 :(得分:-1)

function hex_to_hue($hexcode, $percent) {
        $redhex = substr($hexcode, 0, 2);
        $greenhex = substr($hexcode, 2, 2);
        $bluehex = substr($hexcode, 4, 2);

        // $var_r, $var_g and $var_b are the three decimal fractions to be input to our RGB-to-HSL conversion routine
        $var_r = (hexdec($redhex)) / 255;
        $var_g = (hexdec($greenhex)) / 255;
        $var_b = (hexdec($bluehex)) / 255;

        // Input is $var_r, $var_g and $var_b from above
        // Output is HSL equivalent as $h, $s and $l — these are again expressed as fractions of 1, like the input values

        $var_min = min($var_r, $var_g, $var_b);
        $var_max = max($var_r, $var_g, $var_b);
        $del_max = $var_max - $var_min;

        $l = ($var_max + $var_min) / 2;

        if ($del_max == 0) {
            $h = 0;
            $s = 0;
        } else {
            if ($l < 0.5) {
                $s = $del_max / ($var_max + $var_min);
            } else {
                $s = $del_max / (2 - $var_max - $var_min);
            }
            ;

            $del_r = ((($var_max - $var_r) / 6) + ($del_max / 2)) / $del_max;
            $del_g = ((($var_max - $var_g) / 6) + ($del_max / 2)) / $del_max;
            $del_b = ((($var_max - $var_b) / 6) + ($del_max / 2)) / $del_max;

            if ($var_r == $var_max) {
                $h = $del_b - $del_g;
            } else if ($var_g == $var_max) {
                $h = (1 / 3) + $del_r - $del_b;
            } else if ($var_b == $var_max) {
                $h = (2 / 3) + $del_g - $del_r;
            }
            ;

            if ($h < 0) {
                $h += 1;
            }
            ;

            if ($h > 1) {
                $h -= 1;
            }
            ;
        }
        ;

        //return array($h, $s, $l);
// Calculate the opposite hue, $h2
        $h2 = $h + $percent;
        if ($h2 > 1) {
            $h2 -= 1;
        }

// Calculate the opposite hue, $s2
        $s2 = $s + $percent;
        if ($s2 > 1) {
            $s2 -= 1;
        }

// Calculate the opposite hue, $s2
        $l2 = $l + $percent;
        if ($l2 > 1) {
            $l2 -= 1;
        }
        return array($h2, $s2, $l2);
    }