(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)
imagecolorclosesthwb — Get the index of the color which has the hue, white and blackness
Get the index of the color which has the hue, white and blackness nearest the given color.
image
A GdImage object, returned by one of the image creation functions, such as imagecreatetruecolor() .
red
Value of red component.
green
Value of green component.
blue
Value of blue component.
Returns an integer with the index of the color which has the hue, white and blackness nearest the given color.
Version | Description |
---|---|
8.0.0 |
image expects a GdImage
instance now; previously, a valid gd resource was expected.
|
Example #1 Example of using imagecolorclosesthwb()
<?php
$im = imagecreatefromgif('php.gif');
echo 'HWB: ' . imagecolorclosesthwb($im, 116, 115, 152);
?>
The above example will output something similar to:
HWB: 33
I have written a function which uses the deltaE-function of the CMC.
It returns much better results than imagecolorclosestHWB() or imageColorClosest().
A test-script is online on http://www.fuhrpark-software.de/spielwiese/color.php?color=ffff00
<?php
/*
* Returns the index of the palette-color which is most similar
* to $givenColor.
*
* $givenColor and the colors in $palette should be either
* formatted as (#)rrggbb
* (e. g. "ff0000", "4da4f3" or "#b5d7f3")
* or arrays with values for red, green and blue
* (e. g. $givenColor = array( 0xff, 0x00, 0x00 ) )
*
* References:
* function rgb2lab
* - http://www.f4.fhtw-berlin.de/~barthel/ImageJ/ImageJ.htm
*
* function rgb2lab & function deltaE
* - http://www.brucelindbloom.com
*/
function getNearestColor(
$givenColor,
$palette = array( 'blue' => '43aafd','red' => 'fe6256','green' => '64b949','yellow' => 'fcf357',
'black' => '656565','white' => 'fdfdfd','orange' => 'fea800','purple' => '9773fe')
) {
if(!function_exists('rgb2lab')) {
function rgb2lab($rgb) {
$eps = 216/24389; $k = 24389/27;
// reference white D50
$xr = 0.964221; $yr = 1.0; $zr = 0.825211;
$rgb[0] = $rgb[0]/255; //R 0..1
$rgb[1] = $rgb[1]/255; //G 0..1
$rgb[2] = $rgb[2]/255; //B 0..1
// assuming sRGB (D65)
$rgb[0] = ($rgb[0] <= 0.04045)?($rgb[0]/12.92):pow(($rgb[0]+0.055)/1.055,2.4);
$rgb[1] = ($rgb[1] <= 0.04045)?($rgb[1]/12.92):pow(($rgb[1]+0.055)/1.055,2.4);
$rgb[2] = ($rgb[2] <= 0.04045)?($rgb[2]/12.92):pow(($rgb[2]+0.055)/1.055,2.4);
// sRGB D50
$x = 0.4360747*$rgb[0] + 0.3850649*$rgb[1] + 0.1430804 *$rgb[2];
$y = 0.2225045*$rgb[0] + 0.7168786*$rgb[1] + 0.0606169 *$rgb[2];
$z = 0.0139322*$rgb[0] + 0.0971045*$rgb[1] + 0.7141733 *$rgb[2];
$xr = $x/$xr; $yr = $y/$yr; $zr = $z/$zr;
$fx = ($xr > $eps)?pow($xr, 1/3):($fx = ($k * $xr + 16) / 116);
$fy = ($yr > $eps)?pow($yr, 1/3):($fy = ($k * $yr + 16) / 116);
$fz = ($zr > $eps)?pow($zr, 1/3):($fz = ($k * $zr + 16) / 116);
$lab = array();
$lab[] = round(( 116 * $fy ) - 16);
$lab[] = round(500*($fx-$fy));
$lab[] = round(200*($fy-$fz));
return $lab;
}
}
if(!function_exists('deltaE')) {
function deltaE($lab1, $lab2) {
// CMC 1:1
$l = 1; $c = 1;
$c1 = sqrt($lab1[1]*$lab1[1]+$lab1[2]*$lab1[2]);
$c2 = sqrt($lab2[1]*$lab2[1]+$lab2[2]*$lab2[2]);
$h1 = (((180000000/M_PI) * atan2($lab1[1],$lab1[2]) + 360000000) % 360000000)/1000000;
$t = (164 <= $h1 AND $h1 <= 345)?(0.56 + abs(0.2 * cos($h1+168))):(0.36 + abs(0.4 * cos($h1+35)));
$f = sqrt(pow($c1,4)/(pow($c1,4) + 1900));
$sl = ($lab1[0] < 16)?(0.511):((0.040975*$lab1[0])/(1 + 0.01765*$lab1[0]));
$sc = (0.0638 * $c1)/(1 + 0.0131 * $c1) + 0.638;
$sh = $sc * ($f * $t + 1 -$f);
return sqrt(
pow(($lab1[0]-$lab2[0])/($l * $sl),2) +
pow(($c1-$c2)/($c * $sc),2) +
pow(sqrt(
($lab1[1]-$lab2[1])*($lab1[1]-$lab2[1]) +
($lab1[2]-$lab2[2])*($lab1[2]-$lab2[2]) +
($c1-$c2)*($c1-$c2)
)/$sh,2)
);
}
}
if(!function_exists('str2rgb')) {
function str2rgb($str)
{
$str = preg_replace('~[^0-9a-f]~','',$str);
$rgb = str_split($str,2);
for($i=0;$i<3;$i++)
$rgb[$i] = intval($rgb[$i],16);
return $rgb;
}
}
$givenColorRGB = is_array($givenColor?$givenColor:str2rgb($givenColor);
$min = 0xffff;
$return = NULL;
foreach($palette as $key => $color) {
$color = is_array($color)?$color:str2rgb($color);
if($min >= ($deltaE = deltaE(rgb2lab($color),rgb2lab($givenColorRGB))))
{
$min = $deltaE;
$return = $key;
}
}
return $return;
}
?>