Get image color

Check out the GD functions.

Here’s a solution of looping through the pixels to find the most common color. However, you could just resize the image to 1 pixel – that should be the average color – right?

An example of the 1px method (now including test page):

<?php
  $filename = $_GET['filename'];    
  $image = imagecreatefromjpeg($filename);
  $width = imagesx($image);
  $height = imagesy($image);
  $pixel = imagecreatetruecolor(1, 1);
  imagecopyresampled($pixel, $image, 0, 0, 0, 0, 1, 1, $width, $height);
  $rgb = imagecolorat($pixel, 0, 0);
  $color = imagecolorsforindex($pixel, $rgb);
?>
<html>
  <head>
    <title>Test Image Average Color</title>
  </head>
  <body style="background-color: rgb(<?php echo $color["red'] ?>, <?php echo $color['green'] ?>, <?php echo $color['blue'] ?>)'>
    <form action='' method='get'>
      <input type="text" name="filename"><input type="submit">
    </form>
    <img src="https://stackoverflow.com/questions/1746530/<?php echo $filename ?>">
  </body>
</html>

Here’s some example code for finding the average border color, similar to the first link. For your use this may work better (I know this code is inefficient, but hopefully it’s easy to follow):

<?php
  $filename = $_GET['filename'];    
  $image = imagecreatefromjpeg($filename);
  $width = imagesx($image);
  $height = imagesy($image);

  for($y = 0; $y < $height; $y++){
    $rgb = imagecolorat($image, 0, $y);
    $color = imagecolorsforindex($image, $rgb);
    $red += $color['red'];
    $green += $color['green'];
    $blue += $color['blue'];

    $rgb = imagecolorat($image, $width -1, $y);
    $color = imagecolorsforindex($image, $rgb);
    $red += $color['red'];
    $green += $color['green'];
    $blue += $color['blue'];
  }

  for($x = 0; $x < $height; $x++){
    $rgb = imagecolorat($image, $x, 0);
    $color = imagecolorsforindex($image, $rgb);
    $red += $color['red'];
    $green += $color['green'];
    $blue += $color['blue'];

    $rgb = imagecolorat($image, $x, $height -1);
    $color = imagecolorsforindex($image, $rgb);
    $red += $color['red'];
    $green += $color['green'];
    $blue += $color['blue'];
  }

  $borderSize = ($height=$width)*2;
  $color['red'] = intval($red/$borderSize);
  $color['green'] = intval($green/$borderSize);
  $color['blue'] = intval($blue/$borderSize);

?>

Update: I put some more refined code on github. This includes both averaging the border, and averaging the entire image. It should be noted that resizing to 1px is far more resource friendly than scanning every pixel (although I haven’t run any real time tests), but the code does show the three different methods.

Leave a Comment