Skip to content

Instantly share code, notes, and snippets.

@rcarmo
Created March 30, 2012 10:33
Show Gist options
  • Save rcarmo/2250686 to your computer and use it in GitHub Desktop.
Save rcarmo/2250686 to your computer and use it in GitHub Desktop.
Naïve image color sampling
<?php
function get_color_palette($name, $count = 8) {
$fmap = array(
'gif' => 'imagecreatefromgif',
'png' => 'imagecreatefrompng',
'jpg' => 'imagecreatefromjpg',
'jpeg' => 'imagecreatefromjpg'
);
$path = pathinfo($name);
$colors = array();
try {
list($sw,$sh) = getimagesize($name);
$ext = strtolower($path['extension']);
$im = $fmap[$ext]($name);
} catch (Exception $e) {
error_log('Error reading image: ' . $name . ' ' . $e->getMessage());
return $colors;
}
// build true color images that are at most 400x300
$w = min(400,$sw);
$h = min(300,$sh);
$tc = imagecreatetruecolor($w,$h);
$qi = imagecreatetruecolor($w,$h);
// render a true color representation of the source image
imagecopyresampled($tc,$im,0,0,0,0,$w,$h,$sw,$sh);
// dump a sample so we can watch
imagepng($tc, "/tmp/dump1.png");
// make a copy
imagecopy($qi,$tc,0,0,0,0,$w,$h);
// smooth it
imagefilter($qi, IMG_FILTER_SMOOTH, 2048);
// pixelate it so we can loop through less pixels
imagefilter($qi, IMG_FILTER_PIXELATE, 10, 1);
// try to "quantize" it by creating a palette that is at least 4 times as big as what we need
imagetruecolortopalette($qi, false, $count * 8);
// tune the palette based on the true color image
imagecolormatch($tc,$qi);
// dump a copy
imagepng($qi, "/tmp/dump2.png");
// do a quick pixel scan
for($x = 0; $x < $w; $x+=10) {
for($y = 0; $y < $h; $y+=10) {
$c = imagecolorsforindex($qi, imagecolorat($qi, $x, $y));
array_push($colors, sprintf("#%02X%02X%02X", $c['red'], $c['green'], $c['blue']));
}
}
// count unique values
$dist = array_count_values($colors);
arsort($dist);
echo "<pre>";
var_dump($dist);
echo "</pre>";
// take the $count most popular values
$colors = array_merge(array_slice($dist, 0, $count/2), array_slice($dist, count($dist) - ($count), $count));
$colors = array_keys($colors);
arsort($colors);
echo "<pre>";
var_dump($colors);
echo "</pre>";
imagedestroy($tc);
imagedestroy($im);
return $colors;
}
$p = get_color_palette("./screenshot.png");
foreach($p as $i) {
echo '<span style="background-color: '.$i.'">&nbsp;&nbsp;&nbsp;&nbsp;</span>';
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment