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:
- <?php
- /* The original image is the average colors */
- $average = new Imagick( "test.png" );
- /* Reduce the amount of colors to 10 */
- $average->quantizeImage( 10, Imagick::COLORSPACE_RGB, 0, false, false );
- /* Only save one pixel of each color */
- $average->uniqueImageColors();
- /* Clone the average and modulate to brighter */
- $bright = $average->clone();
- $bright->modulateImage ( 125, 200, 100 );
- /* Clone the average and modulate to darker */
- $dark = $average->clone();
- $dark->modulateImage ( 80, 100, 100 );
- /* Helper function to create the mini-images */
- function createImages( Imagick $composite, Imagick $im )
- {
- /* Get ImagickPixelIterator */
- $it = $im->getPixelIterator();
- /* Reset the iterator to begin */
- $it->resetIterator();
- /* Loop trough rows */
- while( $row = $it->getNextIteratorRow() )
- {
- /* Loop trough columns */
- foreach ( $row as $pixel )
- {
- /* Create a new image which contains the color */
- $composite->newImage( 20, 20, $pixel );
- $composite->borderImage( new ImagickPixel( "black" ), 1, 1 );
- }
- }
- }
- /* This object holds the color images */
- $composite = new Imagick();
- /* Create "icons" for each palette */
- createImages( $composite, $dark );
- createImages( $composite, $average );
- createImages( $composite, $bright );
- /* Montage the color images into single image
- Ten images per row, three rows */
- $montage = $composite->montageImage( new imagickdraw(), "10x3+0+0",
- "20x20+4+3>", imagick::MONTAGEMODE_UNFRAME,
- "0x0+3+3" );
- /* Free some resources */
- $composite->destroy();
- /* Create an empty canvas */
- $canvas = new Imagick();
- $canvas->newImage( $montage->getImageWidth() + 55,
- $montage->getImageHeight(),
- new ImagickPixel( "white" ) );
- /* Display the canvas as png */
- $canvas->setImageFormat( "png" );
- /* Set font size to 12 points */
- $draw = new ImagickDraw();
- $draw->setFontSize( 12 );
- /* Create legends for each palette */
- $canvas->annotateImage( $draw, 5, 20, 0, "Dark: " );
- $canvas->annotateImage( $draw, 5, 45, 0, "Average: " );
- $canvas->annotateImage( $draw, 5, 70, 0, "Bright: " );
- /* Composite the montaged images next to texts */
- $canvas->compositeImage( $montage, Imagick::COMPOSITE_OVER, 55, 0 );
- /* Output the image */
- header( "Content-Type: image/png" );
- echo $canvas;
- ?>
Edited the example to work with 2.0.x
The first source image:

The created palette:

The second source image:

And the palette:

And one more:

Palette:

Pingback: Colour Analysis | THONKE
#1 by vladi on June 10, 2009 - 10:56 am
Quote
Is there some way to convert the colors from the image to color name -> mediumblue is blue, darkblue is blue …….
Thanks!
I think the only way is to create table with color names and the codes, but if someone know better way …
#2 by Anthony Thyssen on July 8, 2009 - 5:55 am
Quote
You may like to look at the discussion on the ImageMagick Discussion Forums which is about this exact problem.
http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=12818
#3 by Steffen on September 29, 2009 - 9:56 pm
Quote
I have found another helpful tool for generating a color palette out of a given image. http://www.degraeve.com/color-palette. May this is also helpful for someone.
#4 by xPheRe on December 15, 2009 - 1:53 am
Quote
Hi, Mikko, I’m having trouble with the montageImage() method in Imagick.
I’m unable to create a sprite with transparent background from a list of png’s.
This is the code I used:
// PNG files with transparency
$files = array(‘filename.png’, …);
$im = new Imagick($files);
$draw = new ImagickDraw();
$montage = $im->montageImage($draw, ’5×0+0+0′, ‘+1+1′, Imagick::MONTAGEMODE_UNFRAME, 0);
The result has a white background instead.
Is there a way to make it transparent?
Have I missed something?
Thanks in advance and congrats for the blog!
Pingback: Quer-durch-asien.de – Update | Stefan Kendlbacher | priv. Website
#5 by chicken coops for sale on September 8, 2011 - 9:13 am
Quote
I know this is a discussion on hard core computing.
I am also a computer science graduate but now know only the spelling of HTML.
What prompted me to write this comment is the beautiful picture of the frog? I don’t know what it is called exactly however, it looks fantastic.
I am going to take a screenshot, better yet download that image itself .
Thanks.