我试图想出一个脚本,它将以编程方式运行图像并告诉我它的主要颜色.
目前,脚本获取每个像素的RGB值.将它们与预定义规则进行比较,并尝试计算每种颜色的像素数.
我的问题是脚本有点受打击.有没有人知道更好的方法(可能使用更容易翻译成英语的不同颜色编码系统)或通过RGB定义颜色的现有规则集?
<?PHP $file = "8629.jpg"; $colors = array("Red" => array("rel" => true,"r" => 0.65,"g" => 0.09,"b" => 0.25,"var" => 0.3),"Blue" => array("rel" => true,"r" => 0.21,"g" => 0.32,"b" => 0.46,"Green" => array("rel" => true,"r" => 0,"g" => 0.67,"b" => 0.33,"Black" => array("rel" => false,"g" => 0,"b" => 0,"var" => 30),"White" => array("rel" => false,"r" => 255,"g" => 255,"b" => 255,"var" => 30)); $total = 0; $im = imagecreatefromjpeg($file); $size = getimagesize($file); if (!$im) { exit("No image found."); } for ($x = 1; $x <= $size[0]; $x++) { for($y = 1; $y <= $size[1]; $y++) { $rgb = imagecolorat($im,$x,$y); $r = ($rgb >> 16) & 0xFF; $g = ($rgb >> 8) & 0xFF; $b = $rgb & 0xFF; $colorTotal = $r + $g + $b; $rRatio = $r > 0 ? $r / $colorTotal : 0; $gRatio = $g > 0 ? $g / $colorTotal : 0; $bRatio = $b > 0 ? $b / $colorTotal : 0; foreach($colors as $key => $color) { if ($color["rel"]) { if ((($color["r"] - $color["var"]) <= $rRatio && $rRatio <= ($color["r"] + $color["var"])) && (($color["g"] - $color["var"]) <= $gRatio && $gRatio <= ($color["g"] + $color["var"])) && (($color["b"] - $color["var"]) <= $bRatio && $bRatio <= ($color["b"] + $color["var"]))) { $colourCount[$key]++; $total++; } } else { if ((($color["r"] - $color["var"]) <= $r && $r <= ($color["r"] + $color["var"])) && (($color["g"] - $color["var"]) <= $g && $g <= ($color["g"] + $color["var"])) && (($color["b"] - $color["var"]) <= $b && $b <= ($color["b"] + $color["var"]))) { $colourCount[$key]++; $total++; } } } } } var_dump($colourCount); foreach($colourCount as $key => $color) { $colourPrecent[$key] = $color / $total; } arsort($colourPrecent); var_dump($colourPrecent); foreach($colourPrecent as $key => $color) { if ($prevVal) { if ($color < ($prevVal - 0.1)) { break; } } $primary[] = $key; $prevVal = $color; } echo("The primary colours in this image are " . implode(" and ",$primary)); ?>
解决方案是按照赫伯特的建议将RGB转换为HSL.转换为人类的功能仍然需要稍微调整/完成,但这里是:
function hslToHuman($h,$s,$l) { $colors = array(); // Gray if ($s <= 10 && (9 <= $l && $l <= 90)) { $colors[] = "gray"; } $l_var = $s / 16; // White $white_limit = 93; if (($white_limit + $l_var) <= $l && $l <= 100) { $colors[] = "white"; } // Black $black_limit = 9; if (0 <= $l && $l <= ($black_limit - $l_var)) { $colors[] = "black"; } // If we have colorless colors stop here if (sizeof($colors) > 0) { return $colors; } // Red if (($h <= 8 || $h >= 346)) { $colors[] = "red"; } // Orange && Brown // TODO // Yellow if (40 <= $h && $h <= 65) { $colors[] = "yellow"; } // Green if (65 <= $h && $h <= 170) { $colors[] = "green"; } // Blue if (165 <= $h && $h <= 260) { $colors[] = "blue"; } // Pink && Purple // TODO return $colors; }