在PHP中计算两种颜色之间的平均颜色,使用索引号作为参考值

发布于 2024-10-09 16:40:39 字数 447 浏览 2 评论 0原文

在 PHP 中,我试图计算不同十六进制颜色之间的平均颜色(以十六进制表示)。但是,我还需要能够提供 0.0 到 1.0 之间的索引号。

例如:

如果我

$color1 = "#ffffff" 
$color2 = "#0066CC"

编写一个函数来获取平均颜色,并且我将提供 0.0 作为索引号,则该函数需要返回“#ffffff”。如果我提供 1.0 作为索引号,该函数将需要返回“#0066CC”。但是,如果我提供 0.2,该函数将需要返回两种颜色之间的平均颜色,但仍然更接近于 $color1 而不是 $color2。如果我提供索引号 0.5,我将获得两种颜色的精确平均颜色。

我已经尝试完成这个任务好几天了,但我似乎无法弄清楚!因此,任何帮助将不胜感激!

In PHP, I am trying to calculate the average color (in hex) between to different hex colors. However, I also need to be able to supply an index number between 0.0 and 1.0.

So for example:

I have

$color1 = "#ffffff" 
$color2 = "#0066CC"

If I would write a function to get the average color and I would supply 0.0 as the index number, the function would need to return "#ffffff". If I would supply 1.0 as the index number, the function would need to return "#0066CC". However if I would supply 0.2, the function would need to return an average color between the two colors, but still closer to $color1 than to $color2. If I would supply index number 0.5, I would get the exact average color of both colors.

I have been trying to accomplish this for several days now but I can't seem to figure it out! Any help would therefor be greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

蘸点软妹酱 2024-10-16 16:40:39

为了讨论的目的,我们假设每种颜色都有一个“值”。然后,您想要做的事情就足够简单了:

$index = 0.2;
$val1 = get_value_of_color($color1);
$val2 = get_value_of_color($color2);
$newval = $val1 * $index + $val2 * (1 - $index);
$newcolor = get_color_from_value($newval);

因此,困难的部分是弄清楚每种颜色的“值”是什么。

您可以使用简单的 RGB 值,其中每种颜色的“值”是一组三个整数:

function get_value_of_color($color) {
    // assume $color is in the form #xxxxxx
    return array(
        hexdec(substr($color, 1, 2)),
        hexdec(substr($color, 3, 2)),
        hexdec(substr($color, 5, 2)),
    );
}

function get_color_from_value($value) {
    return sprintf('#%02x%02x%02x', $value[0], $value[1], $value[2]);
}

此处需要分别对每个数组元素进行乘法和加法。我认为现在应该很容易制作一个简单易用的函数来自己混合颜色。

如果这不是您所需要的,那么您可以使用 HSL 值或更适合您的应用程序的其他一些指标。这个想法将保持不变。

Let's assume that each color has a "value" for the purposes of this discussion. Then, what you want would be simple enough to do:

$index = 0.2;
$val1 = get_value_of_color($color1);
$val2 = get_value_of_color($color2);
$newval = $val1 * $index + $val2 * (1 - $index);
$newcolor = get_color_from_value($newval);

So, the hard part is figuring out what the "value" of each color is.

You could go with simple RGB values, where the "value" of each color is a set of three integers:

function get_value_of_color($color) {
    // assume $color is in the form #xxxxxx
    return array(
        hexdec(substr($color, 1, 2)),
        hexdec(substr($color, 3, 2)),
        hexdec(substr($color, 5, 2)),
    );
}

function get_color_from_value($value) {
    return sprintf('#%02x%02x%02x', $value[0], $value[1], $value[2]);
}

The multiplications and addition would need to be done on each array element separately here. I think at this point it should be easy to make a simple-to-use function to mix colors yourself.

If this is not what you need, then you can go with HSL values or some other metric that better suits your application. The idea would remain the same.

看轻我的陪伴 2024-10-16 16:40:39

我不确定它是否会编译,但如果你想要背后的数学原理,它会是这样的:

为了简单起见,总是让 $color1 大于 $color2

$dec1 = hexdec($hex_color1);
$dec2 = hexdec($hex_color2);

$dec1 = ($dec1 < $dec2) ? $dec1^=$dec2^=$dec1^=$dec2 : $dec1;

$new_hex_color = dechex($dec1 - ($dec1 - $dec2)*index_number)

I am not sure if it will compile but if you want the math behind this it would go something like this:

For simplicity, always have $color1 be bigger than $color2.

$dec1 = hexdec($hex_color1);
$dec2 = hexdec($hex_color2);

$dec1 = ($dec1 < $dec2) ? $dec1^=$dec2^=$dec1^=$dec2 : $dec1;

$new_hex_color = dechex($dec1 - ($dec1 - $dec2)*index_number)
兔姬 2024-10-16 16:40:39

您可以尝试:

function color_avg($color1,$color2,$factor) {

        // extract RGB values for color1.
        list($r1,$g1,$b1) = str_split(ltrim($color1,'#'),2);
        // extract RGB values for color2.
        list($r2,$g2,$b2) = str_split(ltrim($color2,'#'),2);

        // get the average RGB values.
        $r_avg = (hexdec($r1)*(1-$factor)+hexdec($r2)*$factor);
        $g_avg = (hexdec($g1)*(1-$factor)+hexdec($g2)*$factor);
        $b_avg = (hexdec($b1)*(1-$factor)+hexdec($b2)*$factor);

        // construct the result color.    
        $color_avg = '#'.sprintf("%02s",dechex($r_avg)).
                        sprintf("%02s",dechex($g_avg)).
                        sprintf("%02s",dechex($b_avg));


        // return it.
        return $color_avg;
}

查看

You can try:

function color_avg($color1,$color2,$factor) {

        // extract RGB values for color1.
        list($r1,$g1,$b1) = str_split(ltrim($color1,'#'),2);
        // extract RGB values for color2.
        list($r2,$g2,$b2) = str_split(ltrim($color2,'#'),2);

        // get the average RGB values.
        $r_avg = (hexdec($r1)*(1-$factor)+hexdec($r2)*$factor);
        $g_avg = (hexdec($g1)*(1-$factor)+hexdec($g2)*$factor);
        $b_avg = (hexdec($b1)*(1-$factor)+hexdec($b2)*$factor);

        // construct the result color.    
        $color_avg = '#'.sprintf("%02s",dechex($r_avg)).
                        sprintf("%02s",dechex($g_avg)).
                        sprintf("%02s",dechex($b_avg));


        // return it.
        return $color_avg;
}

See it

提笔书几行 2024-10-16 16:40:39

我尝试使用上面提到的功能:

/* 24-bit RGB */
/* (a + b) / 2 = ((a ^ b) >> 1) + (a & b) */
function averageRGB($a, $b){
  return ((($a ^ $b) & 0xfffefefe) >> 1) + ($a & $b);
}

$index = 0.5;
$val1 = get_value_of_color('#FFFFFF');
$val2 = get_value_of_color('#000000');

$aIndexed = array();

for($i=0; $i < 3; $i++){
     if($index == 0.5){
        $aIndexed[$i] = averageRGB($val1[$i],$val2[$i]);
     }else{
        $aIndexed[$i] = $val1[$i] * $index + $val2[$i] * (1 - $index);
     }    
}

echo get_color_from_value($aIndexed);

I tried this using the functions mentioned above:

/* 24-bit RGB */
/* (a + b) / 2 = ((a ^ b) >> 1) + (a & b) */
function averageRGB($a, $b){
  return ((($a ^ $b) & 0xfffefefe) >> 1) + ($a & $b);
}

$index = 0.5;
$val1 = get_value_of_color('#FFFFFF');
$val2 = get_value_of_color('#000000');

$aIndexed = array();

for($i=0; $i < 3; $i++){
     if($index == 0.5){
        $aIndexed[$i] = averageRGB($val1[$i],$val2[$i]);
     }else{
        $aIndexed[$i] = $val1[$i] * $index + $val2[$i] * (1 - $index);
     }    
}

echo get_color_from_value($aIndexed);
黎夕旧梦 2024-10-16 16:40:39
function colorDiff($color1,$color2) {
    $color1=    ltrim($color1,'#');
    $color2=    ltrim($color2,'#'); 
    $red1 =     hexdec(substr($color1,0,2));
    $green1 =  hexdec(substr($color1,2,2));
    $blue1 =    hexdec(substr($color1,4,2));
    $red2 =     hexdec(substr($color2,0,2));
    $green2 =  hexdec(substr($color2,2,2));
    $blue2 =   hexdec(substr($color2,4,2));
    $red =  dechex(round(($red1+$red2)/2));
    $green =    dechex(round(($green1+$green2)/2));
    $blue =     dechex(round(($blue1+$blue2)/2));
    if (strlen($red) == 1) { $red = '0'.$red; }
    if (strlen($green) == 1) { $green = '0'.$green; }
    if (strlen($blue) == 1) { $blue = '0'.$blue; }
    $newcolor = '#'.$red.''.$green.''.$blue;
    return $newcolor;
}
function colorDiff($color1,$color2) {
    $color1=    ltrim($color1,'#');
    $color2=    ltrim($color2,'#'); 
    $red1 =     hexdec(substr($color1,0,2));
    $green1 =  hexdec(substr($color1,2,2));
    $blue1 =    hexdec(substr($color1,4,2));
    $red2 =     hexdec(substr($color2,0,2));
    $green2 =  hexdec(substr($color2,2,2));
    $blue2 =   hexdec(substr($color2,4,2));
    $red =  dechex(round(($red1+$red2)/2));
    $green =    dechex(round(($green1+$green2)/2));
    $blue =     dechex(round(($blue1+$blue2)/2));
    if (strlen($red) == 1) { $red = '0'.$red; }
    if (strlen($green) == 1) { $green = '0'.$green; }
    if (strlen($blue) == 1) { $blue = '0'.$blue; }
    $newcolor = '#'.$red.''.$green.''.$blue;
    return $newcolor;
}
余生一个溪 2024-10-16 16:40:39

或者使用数组作为输入:

 $color_arr =
array('#FF0000','#0000FF','#FF0000','#0000FF','#0000FF','#0000FF');
$newcolor = colorDiffArr($color_arr); foreach ($color_arr as $color) {
    echo '<div style="display:block; background:'.$color.';"
 bgcolor="'.$color.'; width:10px; height:10px;">'.$color.'</div>'; }
 echo '<div style="display:block; background:'.$newcolor.';"
 bgcolor="'.$newcolor.'; width:10px;
 height:10px;">'.$newcolor.'</div>';
 function colorDiffArr($color_arr) {    
       $red = 0; $green = 0; $blue = 0;
       foreach ($color_arr as $color) {         
          $color= ltrim($color,'#');
          $red+=hexdec(substr($color,0,2));         
          $green+=hexdec(substr($color,2,2));       
          $blue+=hexdec(substr($color,4,2));    }
       $red =       dechex(round(($red)/count($color_arr)));    
          $green =
    dechex(round(($green)/count($color_arr)));  $blue =
    dechex(round(($blue)/count($color_arr)));       if (strlen($red) == 1) {
 $red = '0'.$red; }     if (strlen($green) == 1) { $green = '0'.$green; }
    if (strlen($blue) == 1) { $blue = '0'.$blue; }  $newcolor =
 '#'.$red.''.$green.''.$blue;   return $newcolor; }

Or using an array as input :

 $color_arr =
array('#FF0000','#0000FF','#FF0000','#0000FF','#0000FF','#0000FF');
$newcolor = colorDiffArr($color_arr); foreach ($color_arr as $color) {
    echo '<div style="display:block; background:'.$color.';"
 bgcolor="'.$color.'; width:10px; height:10px;">'.$color.'</div>'; }
 echo '<div style="display:block; background:'.$newcolor.';"
 bgcolor="'.$newcolor.'; width:10px;
 height:10px;">'.$newcolor.'</div>';
 function colorDiffArr($color_arr) {    
       $red = 0; $green = 0; $blue = 0;
       foreach ($color_arr as $color) {         
          $color= ltrim($color,'#');
          $red+=hexdec(substr($color,0,2));         
          $green+=hexdec(substr($color,2,2));       
          $blue+=hexdec(substr($color,4,2));    }
       $red =       dechex(round(($red)/count($color_arr)));    
          $green =
    dechex(round(($green)/count($color_arr)));  $blue =
    dechex(round(($blue)/count($color_arr)));       if (strlen($red) == 1) {
 $red = '0'.$red; }     if (strlen($green) == 1) { $green = '0'.$green; }
    if (strlen($blue) == 1) { $blue = '0'.$blue; }  $newcolor =
 '#'.$red.''.$green.''.$blue;   return $newcolor; }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文