I'm trying to come up with a script that will programmatically run through an image and tell me it's primary color(s).
Currently the script gets the RGB value of each pixel. Compares them against predefined rules and attempts to count up the number of pixels of each colour.
My problem is the script is a little hit and miss. Does anyone know of a better way of doing this (maybe using a different colour coding system that's easier to translate to english) or an existing set of rules defining colours via their 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, "var" => 0.3),
"Green" => array("rel" => true, "r" => 0, "g" => 0.67,"b" => 0.33, "var" => 0.3),
"Black" => array("rel" => false, "r" => 0, "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));
?>