23

i want to find the dominant color in image, how can i do it ?

it would be great if i can get this in HEX code (exm: #eeeeee)

hakre
  • 193,403
  • 52
  • 435
  • 836
motioz
  • 662
  • 2
  • 11
  • 21

9 Answers9

18

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.

tkone
  • 22,092
  • 5
  • 54
  • 78
  • This link goes to an adult website now :( – Rich Bradshaw Sep 14 '13 at 16:38
  • Note that the linked code basically converts the image to b/w and doesn't distinguish between colors, i.e. a completely blue image will result in the same histogram than a red image. To get the dominant color I'd recommend converting the RGB values to HSL first and create the histogram for the hue value. – florian h Aug 05 '14 at 16:41
  • In case it shows something else again, here's the [archived version](https://web.archive.org/web/20120502052644/http://bubble.ro/How_to_create_the_histogram_of_an_image_using_PHP.html) of the post closest to the date this answer was posted. – Jed Burke Apr 08 '18 at 00:05
3

Try this: http://www.coolphptools.com/color_extract.

The Image Color Extract PHP class pulls the most common colors (in percentages) out of an image file. The color values are in hexadecimal.

3

There is a PHP class developed that handles this, named color extract. However, know that doing this on the server side will require substantial system resources. You may wish to instead do this with canvas.

Community
  • 1
  • 1
Zachary Schuessler
  • 3,644
  • 2
  • 28
  • 43
  • If you're looking to do that in JavScript, here's an already answered stack overflow question which answers that exactly: http://stackoverflow.com/questions/8329765/determine-if-image-is-grayscale-or-color-using-javascript/8329821#8329821 – tkone Jan 04 '12 at 17:03
2

In regard to tkone answer, the $max is just a parameter showing density of the color at an image. I would change the code a bit to return the HEX color:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Empty Document</title>
</head>

<body>
<?php

error_reporting(0);
function rgb2hex($rgb) {
   $hex = "#";
   $hex .= str_pad(dechex($rgb[0]), 2, "0", STR_PAD_LEFT);
   $hex .= str_pad(dechex($rgb[1]), 2, "0", STR_PAD_LEFT);
   $hex .= str_pad(dechex($rgb[2]), 2, "0", STR_PAD_LEFT);

   return $hex; // returns the hex value including the number sign (#)
}


$source_file = "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);
                //echo $rgb."<br>";
                // 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);
                //echo $V."<br>";
                // add the point to the histogram

                $histo[$V] += $V / $n;
                $histo_color[$V] = rgb2hex([$r,$g,$b]);

        }
}

// 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>";

$key = array_search ($max, $histo);
$col = $histo_color[$key];
?> 

<p style="min-width:100px; min-height:100px; background-color:<?php echo $col?>;"></p>
<img src="<?php echo $source_file?>">
</body>
</html>

Also, it is worth mentioning that this is just the most 'repeated' color at the image that cannot absolutely considered 'dominant' color.

Shahroq
  • 969
  • 1
  • 8
  • 15
2

PHP Simple Color Thief

Detect the Dominant Color used in an Image

Works very fast!

PHP:

require 'color.php';
$image = 'https://cdn.pixabay.com/photo/2012/11/24/07/43/colorful-67134_960_720.jpg'
$default_color = 'ffffff';
echo simple_color_thief($image, $default_color);

Will return the Hex Color: e0a654

The color.php File:

/*
PHP Simple Color Thief
======================
Detect the Dominant Color used in an Image
Copyright 2019 Igor Gaffling
*/

function simple_color_thief($img, $default='eee') {
  if(@exif_imagetype($img)) { // CHECK IF IT IS AN IMAGE
    $type = getimagesize($img)[2]; // GET TYPE
    if ($type === 1) { // GIF
      $image = imagecreatefromgif($img);
      // IF IMAGE IS TRANSPARENT (alpha=127) RETURN fff FOR WHITE
      if (imagecolorsforindex($image, imagecolorstotal($image)-1)['alpha'] == 127) return 'fff';
    } else if ($type === 2) { // JPG
      $image = imagecreatefromjpeg($img);
    } else if ($type === 3) { // PNG
      $image = imagecreatefrompng($img);
      // IF IMAGE IS TRANSPARENT (alpha=127) RETURN fff FOR WHITE
      if ((imagecolorat($image, 0, 0) >> 24) & 0x7F === 127) return 'fff';
    } else { // NO CORRECT IMAGE TYPE (GIF, JPG or PNG)
      return $default;
    }
  } else { // NOT AN IMAGE
    return $default;
  }
  $newImg = imagecreatetruecolor(1, 1); // FIND DOMINANT COLOR
  imagecopyresampled($newImg, $image, 0,0,0,0,1,1, imagesx($image), imagesy($image));
  return dechex(imagecolorat($newImg, 0, 0)); // RETURN HEX COLOR
}
// DEMO
foreach(glob('./*.{jpg,png,gif}', GLOB_BRACE) as $i) {
  echo '<div style="width:26%;padding:50px;background:#'.
  simple_color_thief($i,'f00').
  ';display:inline-block"><img style="height:200px" src="'.
  $i.'"></div>';
}

Source: https://github.com/gaffling/PHP-Simple-Color-Thief/

adilbo
  • 910
  • 14
  • 22
2

Sounds like a delightful code to write! I made a function awhile back that goes through every pixel and adds a shade to each one. What you could do is:

For Each Pixel, find the highest color (r,g,or b) and do the math ($colorG++ or something)

at the end, find out what one is the largest, and there would be your highest rgb shade.

I wonder what color would come out if you used the resulting rgb value...

Adam Fowler
  • 1,750
  • 1
  • 17
  • 18
0

You give an image ressouce as argument.

Ex:

$im=imagecreatefromjpeg("path/to/image");
getDominantcolor($im);

NB: This function will little bit slow down your page since it will compare each color of the image to all other color to make the statistic. It returns rgb value of the dominant color as array

function getDominantcolor($im){

        $width=imagesx($im);
        $height=imagesy($im);
        $colorArr=[];
        $comparArr=[];
        $colCount=0;

        //fixed height
        for ($j=0; $j < $height; $j++) { 
            //fetching color on widths
            for ($i=0; $i < $height; $i++) { 
                $colorArr[]=imagecolorat ( $im ,$i ,$j );
            }

        }


        //fixed height
        for ($col=0; $col < count($colorArr); $col++) { 
            for ($cel=0; $cel <  count($colorArr); $cel++) { 
                if($colorArr[$col]===$colorArr[$cel]){
                    $colCount+=1;
                }
            }
            $comparArr[]=$colCount;
            $colCount=0;
        }


        foreach ($comparArr as $key => $value) {
            if($value===max($comparArr)){
                $max_index=$key;
                break;
            }
        }
        $rgb=$colorArr[$max_index];
        $r = ($rgb >> 16) & 0xFF;
        $g = ($rgb >> 8) & 0xFF;
        $b = $rgb & 0xFF;
        return ['r'=>$r,'g'=>$g,'b'=>$b];

    }
0

You should have a look at GD and Image Functions.

There is a similar question on SO about extracting color information from an image with PHP, and it links to this class on github.

Community
  • 1
  • 1
afaf12
  • 5,163
  • 9
  • 35
  • 58
-3

Though its in javascript but color-thief is best for getting dominant color in image.

https://github.com/lokesh/color-thief

Ajeet Lakhani
  • 3,768
  • 2
  • 22
  • 37