Skip to content

Instantly share code, notes, and snippets.

@BenMorel
Last active December 3, 2020 14:48
Show Gist options
  • Save BenMorel/fcdc4449e023ae2fe83b65e8eb4a04e5 to your computer and use it in GitHub Desktop.
Save BenMorel/fcdc4449e023ae2fe83b65e8eb4a04e5 to your computer and use it in GitHub Desktop.
Get dominant color from an Imagick image
<?php
/**
* Two methods to get the dominant color from an image.
* Useful to create placeholders while loading an image.
*
* Method 1 yields more bright colors than method 2.
*/
/**
* Method 1, using average R,G,B values from image channel statistics.
*/
function getDominantColor1(Imagick $imagick): string
{
/** @var int $quantumRange */
$quantumRange = $imagick::getQuantumRange()['quantumRangeLong'];
/** @psalm-var array<Imagick::CHANNEL_*, array{mean: float}> $channelStats */
$channelStats = $imagick->getImageChannelStatistics();
$getValue = function(int $channel) use ($quantumRange, $channelStats): int {
$mean = $channelStats[$channel]['mean'];
$mean = (int) round($mean / $quantumRange * 255);
assert($mean >= 0 && $mean <= 255);
return $mean;
};
$r = $getValue(Imagick::CHANNEL_RED);
$g = $getValue(Imagick::CHANNEL_GREEN);
$b = $getValue(Imagick::CHANNEL_BLUE);
return sprintf('%02x%02x%02x', $r, $g, $b);
}
/**
* Method 2, using quantizeImage().
*
* Adapted from https://manu.ninja/dominant-colors-for-lazy-loading-images/
*/
function getDominantColor2(Imagick $imagick): string
{
$imagick = clone $imagick;
$imagick->resizeImage(250, 250, Imagick::FILTER_GAUSSIAN, 1);
$imagick->quantizeImage(1, Imagick::COLORSPACE_RGB, 0, false, false);
$color = $imagick->getImagePixelColor(0, 0)->getColor(true);
$r = (int) round($color['r'] * 255.0);
$g = (int) round($color['g'] * 255.0);
$b = (int) round($color['b'] * 255.0);
return sprintf('%02x%02x%02x', $r, $g, $b);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment