Ever wanted to programmatically deploy a color palette or compare two images based on their primary colors. There are many ways to achieve this, but PHP and Imagick could be handy for sure. Say we have a picture like this:
and want to extract the main colors like this:
than this is the code to follow:
/* 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;