Detect Main Colors in an Image with PHP

Detect main colors in an image with PHP

Here's exactly what you're looking for in PHP: https://github.com/thephpleague/color-extractor

Example :

use League\ColorExtractor\Palette;

$palette = Palette::fromFilename('some/image.png');

$topEightColors = $palette->getMostUsedColors(8);

Detecting colors for an Image using PHP

Here's a script that will give you the list:

function detectColors($image, $num, $level = 5) {
$level = (int)$level;
$palette = array();
$size = getimagesize($image);
if(!$size) {
return FALSE;
}
switch($size['mime']) {
case 'image/jpeg':
$img = imagecreatefromjpeg($image);
break;
case 'image/png':
$img = imagecreatefrompng($image);
break;
case 'image/gif':
$img = imagecreatefromgif($image);
break;
default:
return FALSE;
}
if(!$img) {
return FALSE;
}
for($i = 0; $i < $size[0]; $i += $level) {
for($j = 0; $j < $size[1]; $j += $level) {
$thisColor = imagecolorat($img, $i, $j);
$rgb = imagecolorsforindex($img, $thisColor);
$color = sprintf('%02X%02X%02X', (round(round(($rgb['red'] / 0x33)) * 0x33)), round(round(($rgb['green'] / 0x33)) * 0x33), round(round(($rgb['blue'] / 0x33)) * 0x33));
$palette[$color] = isset($palette[$color]) ? ++$palette[$color] : 1;
}
}
arsort($palette);
return array_slice(array_keys($palette), 0, $num);
}

$img = 'icon.png';
$palette = detectColors($img, 6, 1);
echo '<img src="' . $img . '" />';
echo '<table>';
foreach($palette as $color) {
echo '<tr><td style="background:#' . $color . '; width:36px;"></td><td>#' . $color . '</td></tr>';
}
echo '</table>';

Detect overall average color of the picture

You can use PHP to get an array of the color palette like so:

<?php 
function colorPalette($imageFile, $numColors, $granularity = 5)
{
$granularity = max(1, abs((int)$granularity));
$colors = array();
$size = @getimagesize($imageFile);
if($size === false)
{
user_error("Unable to get image size data");
return false;
}
$img = @imagecreatefromjpeg($imageFile);
// Andres mentioned in the comments the above line only loads jpegs,
// and suggests that to load any file type you can use this:
// $img = @imagecreatefromstring(file_get_contents($imageFile));

if(!$img)
{
user_error("Unable to open image file");
return false;
}
for($x = 0; $x < $size[0]; $x += $granularity)
{
for($y = 0; $y < $size[1]; $y += $granularity)
{
$thisColor = imagecolorat($img, $x, $y);
$rgb = imagecolorsforindex($img, $thisColor);
$red = round(round(($rgb['red'] / 0x33)) * 0x33);
$green = round(round(($rgb['green'] / 0x33)) * 0x33);
$blue = round(round(($rgb['blue'] / 0x33)) * 0x33);
$thisRGB = sprintf('%02X%02X%02X', $red, $green, $blue);
if(array_key_exists($thisRGB, $colors))
{
$colors[$thisRGB]++;
}
else
{
$colors[$thisRGB] = 1;
}
}
}
arsort($colors);
return array_slice(array_keys($colors), 0, $numColors);
}
// sample usage:
$palette = colorPalette('rmnp8.jpg', 10, 4);
echo "<table>\n";
foreach($palette as $color)
{
echo "<tr><td style='background-color:#$color;width:2em;'> </td><td>#$color</td></tr>\n";
}
echo "</table>\n";

Which gives you an array whose values are higher for how often that color has been used.

EDIT
A commenter asked how to use this on all files in a directory, here it is:

    if ($handle = opendir('./path/to/images')) {

while (false !== ($file = readdir($handle))) {
$palette = colorPalette($file, 10, 4);
echo "<table>\n";
foreach($palette as $color) {
echo "<tr><td style='background-color:#$color;width:2em;'> </td><td>#$color</td></tr>\n";
}
echo "</table>\n";
}
closedir($handle);
}

might not want to do this on too many files, but it's your server.

Alternatively if you'd rather use Javascript Lokesh's Color-Theif library does exactly what you're looking for.

How to find the Dominant color in image?

To find the most "dominant" color in an image, meaning the color that is most prevalent in the image: you'd need to create a histogram of the image.

Here is an the code from this article on how to create a histogram in PHP. (Website has gone off line several times)

<?php
$source_file = "test_image.jpg";

// histogram options

$maxheight = 300;
$barwidth = 2;

$im = ImageCreateFromJpeg($source_file);

$imgw = imagesx($im);
$imgh = imagesy($im);

// n = total number or pixels

$n = $imgw*$imgh;

$histo = array();

for ($i=0; $i<$imgw; $i++)
{
for ($j=0; $j<$imgh; $j++)
{

// get the rgb value for current pixel

$rgb = ImageColorAt($im, $i, $j);

// extract each value for r, g, b

$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;

// get the Value from the RGB value

$V = round(($r + $g + $b) / 3);

// add the point to the histogram

$histo[$V] += $V / $n;

}
}

// find the maximum in the histogram in order to display a normated graph

$max = 0;
for ($i=0; $i<255; $i++)
{
if ($histo[$i] > $max)
{
$max = $histo[$i];
}
}

echo "<div style='width: ".(256*$barwidth)."px; border: 1px solid'>";
for ($i=0; $i<255; $i++)
{
$val += $histo[$i];

$h = ( $histo[$i]/$max )*$maxheight;

echo "<img src=\"img.gif\" width=\"".$barwidth."\"
height=\"".$h."\" border=\"0\">";
}
echo "</div>";
?>

In that example $max is your most "dominant" color.

PHP how to detect if image contains color?

You'd have to walk through every pixel using imagecolorat() (see example #2).

Grayscale colours will have the same value for Red, Green, and Blue. If you find a pixel where the values differ, it's an image that contains a colour (at least technically - with a colour like RGB(100,102,103) it will look grey to the human eye.).

Determine website main colors

As a general strategy, get a screenshot of the website and store it in a lossless image format (e.g. PNG but not JPEG). Then loop over all the pixels and get their colour. Store the results in an associated array (( 'colour code' => 'count of pixels with that colour' )). Loop over that array and find the highest counts. Those are your colours.



Related Topics



Leave a reply



Submit