5

是否可以根据定义的“中心值”检查某个十六进制颜色是否更接近 FFF 或 000?

我想根据 #888 检查颜色是否更接近 #FFF 或 #000。因此,如果我检查#EFEFEF,它应该返回#FFF,如果我尝试#878787,它应该返回#000。

如何做到这一点?我不知道在 Google 上搜索什么...

提前致谢

4

4 回答 4

3

您可以将颜色转换为数字:

$color_num = hexdec(substr($color, 1)); // skip the initial #

然后将它们与0x0或进行比较0xffffff

您也可以将它们分解为R,G和B并进行三个比较;然后平均它们?不知道你想要这个东西有多精确:)

于 2012-05-11T12:22:46.963 回答
2

解决问题的最简单方法是使用它们的灰度值计算颜色之间的距离(还有其他方法,但这很简单)。所以像:

// returns a distance between two colors by comparing each component
// using average of the RGB components, eg. a grayscale value
function color_distance($a, $b)
{
    $decA = hexdec(substr($a, 1));
    $decB = hexdec(substr($a, 1));
    $avgA = (($decA & 0xFF) + (($decA >> 8) & 0xFF) + (($decA >> 16) & 0xFF)) / 3;
    $avgB = (($decB & 0xFF) + (($decB >> 8) & 0xFF) + (($decB >> 16) & 0xFF)) / 3;
    return abs($avgA - $avgB);
}

// I am going to leave the naming of the function to you ;)
// How this works is that it'll return $minColor if $color is closer to $refColorMin
// and $maxColor if $color is closer to $refColorMax
// all colors should be passed in format #RRGGBB
function foo($color, $refColorMin, $refColorMax, $minColor, $maxColor)
{
    $distMin = color_distance($color, $refColorMin);
    $distMax = color_distance($color, $refColorMax);
    return ($distMin < $distMax) ? $minColor : $maxColor;
}

// Example usage to answer your original question:
$colorA = foo('#EFEFEF', '#888888', '#FFFFFF', '#000000', '#FFFFFF');
$colorA = foo('#898989', '#888888', '#FFFFFF', '#000000', '#FFFFFF');
// Check the values
var_dump($colorA, $colorB);

输出是:

string(7) "#FFFFFF"
string(7) "#000000"
于 2012-05-11T12:38:06.133 回答
1

您可以执行以下操作:

function hex2rgb($hex) {
   $hex = str_replace("#", "", $hex);

   if(strlen($hex) == 3) {
      $r = hexdec(substr($hex,0,1).substr($hex,0,1));
      $g = hexdec(substr($hex,1,1).substr($hex,1,1));
      $b = hexdec(substr($hex,2,1).substr($hex,2,1));
   } else {
      $r = hexdec(substr($hex,0,2));
      $g = hexdec(substr($hex,2,2));
      $b = hexdec(substr($hex,4,2));
   }
   $rgb = array($r, $g, $b);
   //return implode(",", $rgb); // returns the rgb values separated by commas
   return $rgb; // returns an array with the rgb values
}

$rgb = hex2rgb("#cc0");

从中您可以获取 $rgb 的值,看看它们的值是否平均大于或小于 122.5。如果它大于 122.5 你会更接近#FFFFFF,低于 122.5 你会更接近 #000000。

于 2012-05-11T12:25:40.260 回答
0

感谢大家的帮助!

在我的 startpost 中,我犯了 oezi 提到的一个小错字。对我来说,解决方案是对已接受答案的小修改(由 reko_t 提供):

function color_distance($sColor1, $sColor2)
{
    $decA = hexdec(substr($sColor1, 1));
    $decB = hexdec(substr($sColor2, 1));
    $avgA = (($decA & 0xFF) + (($decA >> 8) & 0xFF) + (($decA >> 16) & 0xFF)) / 3;
    $avgB = (($decB & 0xFF) + (($decB >> 8) & 0xFF) + (($decB >> 16) & 0xFF)) / 3;
    return abs($avgA - $avgB);
}

function determine_color($sInputColor, $sRefColor, $sMinColor, $sMaxColor)
{
    $distRef    = color_distance($sInputColor, $sRefColor);
    $distMin    = color_distance($sInputColor, $sMinColor);
    $distMax    = color_distance($sInputColor, $sMaxColor);

    return $distMax - $distRef <  $distMin - $distRef ? $sMinColor : $sMaxColor;
}

我需要这个函数来确定背景颜色上的文本颜色,可以通过一些设置来设置。谢谢!:) 归功于 reko_t!

于 2012-05-11T13:22:20.437 回答