The idea for today’s example comes from Jonathan. Jonathan was asking: “I’d like to request a tutorial. One thing I’d really like to know how to do is analyze an image for it’s color “palette”, or in other words, to find what the primary colors are that are used in an image.”

I don’t know if this is exactly what he meant but I hope this example can be used as a kickstart for color analysis. The code in the example reduces the image colors to 10, then discards all but one pixel of every color and then creates the palettes out of those colors. This might not be the most accurate way to do this, but at least it’s fast :)

The code creates three different “palettes” from image; average palette, dark palette and bright palette. I got the idea for three different palettes from MarcosBL at freenode.

Here is the code:

  1. <?php
  2.  
  3. /* The original image is the average colors */
  4. $average = new Imagick( "test.png" );
  5.  
  6. /* Reduce the amount of colors to 10 */
  7. $average->quantizeImage( 10, Imagick::COLORSPACE_RGB, 0, false, false );
  8.  
  9. /* Only save one pixel of each color */
  10. $average->uniqueImageColors();
  11.  
  12. /* Clone the average and modulate to brighter */
  13. $bright = $average->clone();
  14. $bright->modulateImage ( 125, 200, 100 );
  15.  
  16. /* Clone the average and modulate to darker */
  17. $dark = $average->clone();
  18. $dark->modulateImage ( 80, 100, 100 );
  19.  
  20. /* Helper function to create the mini-images */
  21. function createImages( Imagick $composite, Imagick $im )
  22. {
  23.     /* Get ImagickPixelIterator */
  24.     $it = $im->getPixelIterator();
  25.    
  26.     /* Reset the iterator to begin */
  27.     $it->resetIterator();
  28.  
  29.     /* Loop trough rows */
  30.     while( $row = $it->getNextIteratorRow() )
  31.     {
  32.         /* Loop trough columns */
  33.         foreach ( $row as $pixel )
  34.         {      
  35.             /* Create a new image which contains the color */
  36.             $composite->newImage( 20, 20, $pixel );
  37.             $composite->borderImage( new ImagickPixel( "black" ), 1, 1 );
  38.         }
  39.     }
  40. }
  41. /* This object holds the color images */
  42. $composite = new Imagick();
  43.  
  44. /* Create "icons" for each palette */
  45. createImages( $composite, $dark );
  46. createImages( $composite, $average );
  47. createImages( $composite, $bright );
  48.  
  49. /* Montage the color images into single image
  50.    Ten images per row, three rows */
  51. $montage = $composite->montageImage( new imagickdraw(), "10x3+0+0",
  52.                                       "20x20+4+3>", imagick::MONTAGEMODE_UNFRAME,
  53.                                       "0x0+3+3" );
  54.  
  55. /* Free some resources */
  56. $composite->destroy();
  57.  
  58. /* Create an empty canvas */
  59. $canvas = new Imagick();
  60. $canvas->newImage( $montage->getImageWidth() + 55,
  61.                    $montage->getImageHeight(),
  62.                    new ImagickPixel( "white" ) );
  63.  
  64. /* Display the canvas as png */
  65. $canvas->setImageFormat( "png" );
  66.  
  67. /* Set font size to 12 points */
  68. $draw = new ImagickDraw();
  69. $draw->setFontSize( 12 );
  70.  
  71. /* Create legends for each palette */
  72. $canvas->annotateImage( $draw, 5, 20, 0, "Dark: " );
  73. $canvas->annotateImage( $draw, 5, 45, 0, "Average: " );
  74. $canvas->annotateImage( $draw, 5, 70, 0, "Bright: " );
  75.  
  76. /* Composite the montaged images next to texts */
  77. $canvas->compositeImage( $montage, Imagick::COMPOSITE_OVER, 55, 0 );
  78.  
  79. /* Output the image */
  80. header( "Content-Type: image/png" );
  81. echo $canvas;
  82.  
  83. ?>

Edited the example to work with 2.0.x

The first source image:

strawberry

The created palette:

strawberry_palette

The second source image:

strawberry

And the palette:

strawberry

And one more:

chev

Palette:

chev