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

使用索引号作为参考值,计算PHP中两种颜色之间的平均颜色,php,colors,hex,Php,Colors,Hex,在PHP中,我试图计算不同十六进制颜色之间的平均颜色(十六进制)。但是,我还需要能够提供一个介于0.0和1.0之间的索引号 例如: 我有 $color1 = "#ffffff" $color2 = "#0066CC" 如果我编写一个函数来获得平均颜色,并提供0.0作为索引号,那么该函数需要返回“#ffffff”。如果我提供1.0作为索引号,函数将需要返回“#0066CC”。但是,如果我提供0.2,函数将需要返回两种颜色之间的平均颜色,但仍然更接近$color1,而不是$color2。如果我提

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

例如:

我有

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


我已经试着完成这几天了,但我似乎不明白!任何帮助都将不胜感激

在本次讨论中,我们假设每种颜色都有一个“值”。然后,您想要的是足够简单的操作:

$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值或其他更适合您的应用程序的度量。这个想法将保持不变。

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

为简单起见,请始终使
$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)
$dec1=hexdec($hex_color1);
$dec2=hexdec($hex\u color2);
$dec1=($dec1<$dec2)$dec1^=$dec2^=$dec1^=$dec2:$dec1;
$new\u hex\u color=dechex($dec1-($dec1-$dec2)*索引号)
您可以尝试:

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;
}

我尝试使用上述功能:

/* 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);
/*24位RGB*/
/*(a+b)/2=(a^b)>>1+(a&b)*/
函数averageRGB($a,$b){
返回(($a^$b)和0xFFFEFE)>>1)+($a和$b);
}
$index=0.5;
$val1=获取颜色的值('ffffffff');
$val2=获取颜色的值('000000');
$aIndexed=array();
对于($i=0;$i<3;$i++){
如果($index==0.5){
$aIndexed[$i]=平均GB($val1[$i],$val2[$i]);
}否则{
$aIndexed[$i]=$val1[$i]*$index+$val2[$i]*(1-$index);
}    
}
echo从值中获取颜色($aIndexed);

或使用数组作为输入:

 $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; }
$color\u arr=
数组(“#FF0000”、“#0000FF”、“#FF0000”、“#0000FF”、“#0000FF”、“#0000FF”、“#0000FF”);
$newcolor=colorDiffArr($color\u arr);foreach($color\u arr as$color){
回显“.$color.”;}
回显“.$newcolor.”;
函数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(圆形($red)/计数($color_arr));
$green=
十进制(圆形($绿色)/计数($颜色);$蓝色=
十进制(圆形($蓝色)/计数($color_arr));如果(斯特伦($red)==1){
$red='0'.$red;}如果(strlen($green)==1){$green='0'.$green;}
如果(strlen($blue)==1){$blue='0'.$blue;}$newcolor=
“#”。$红色。“$绿色”。$蓝色;返回$newcolor;}

删除了我的答案,因为它与十六进制RGB颜色的设计方式不兼容。你的答案更简单。也删除了我的答案,并了解了sprintf函数,谢谢!对于这个代码,它意味着你不必检查十进制数是否只有1位,因为你用0填充它。嘿,伙计们!老实说,我用了安迪的版本,效果非常好!!正是我需要的。。但你们是说我应该用乔恩的版本来代替吗?@Roel:用你们喜欢的。我的回答是故意解释性的,而不是功能性的,所以我并不是说这是复制/粘贴的最佳解决方案。@Junky:这样的代码看起来很不错。。。如果你不需要维护,有什么需要维护的?只有一行+1用于
str\u split
。我不知道PHP有一个574字符串操作函数!
 $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; }