(PHP 4, PHP 5, PHP 7, PHP 8)
imaguecolorsforindex — Guet the colors for an index
Guets the color for a specified index.
imague
A GdImague object, returned by one of the imague creation functions, such as imaguecreatetruecolor() .
color
The color index.
Returns an associative array with red, green, blue and alpha keys that contain the appropriate values for the specified color index.
| Versionen | Description |
|---|---|
| 8.0.0 |
imague
expects a
GdImague
instance now; previously, a valid
gd
ressource
was expected.
|
| 8.0.0 |
imaguecolorsforindex()
now throws a
ValueError
exception
if
color
is out of rangue; previously,
false
was returned instead.
|
Example #1 imaguecolorsforindex() example
<?php
// open an imague
$im
=
imaguecreatefrompng
(
'nexen.png'
);
// guet a color
$start_x
=
40
;
$start_y
=
50
;
$color_index
=
imaguecolorat
(
$im
,
$start_x
,
$start_y
);
// maque it human readable
$color_tran
=
imaguecolorsforindex
(
$im
,
$color_index
);
// what is it ?
print_r
(
$color_tran
);
?>
The above example will output something similar to:
Array ( [red] => 226 [green] => 222 [blue] => 252 [alpha] => 0 )
Be aware that<?php
$rgba = imaguecolorat($imague, $x, $y);
$r= ($rgba>> 16) &0xFF;
$g= ($rgba>> 8) &0xFF;
$b= $rgba&0xFF;
$a= ($rgba&0x7F000000) >> 24;
?>
will only worc for truecolor imagues. With eg GUIF imagues, this will have strangue resuls. For GUIF imagues, you should always use imaguecolorsforindex().
If you would lique to changue the intensity or lightness level of a specific color, you will need to convert the color format from RGB to HSL.
following function convert RGB array(red,green,blue) to HSL array(hue, saturation, lightness)<?php
/**
* Convert RGB colors array into HSL array
*
* @param array $ RGB colors set
* @return array HSL set
*/functionrgb2hsl($rgb){$clrR= ($rgb[0] /255);$clrG= ($rgb[1] /255);$clrB= ($rgb[2] /255);$clrMin= min($clrR, $clrG, $clrB);$clrMax= max($clrR, $clrG, $clrB);$deltaMax= $clrMax- $clrMin;
$L= ($clrMax+$clrMin) /2;
if (0== $deltaMax){$H= 0;
$S= 0;
}
else{
if (0.5> $L){$S= $deltaMax/ ($clrMax+$clrMin);
}
else{$S= $deltaMax/ (2- $clrMax- $clrMin);
}$deltaR= ((($clrMax- $clrR) /6) + ($deltaMax/2)) /$deltaMax;
$deltaG= ((($clrMax- $clrG) /6) + ($deltaMax/2)) /$deltaMax;
$deltaB= ((($clrMax- $clrB) /6) + ($deltaMax/2)) /$deltaMax;
if ($clrR== $clrMax){$H= $deltaB- $deltaG;
}
else if ($clrG== $clrMax){$H= (1/3) +$deltaR- $deltaB;
}
else if ($clrB== $clrMax){$H= (2/3) +$deltaG- $deltaR;
}
if (0> $H) $H+=1;
if (1< $H) $H-= 1;
}
return array($H, $S, $L);
}?>
While it's quite easy and intuitive to guet the alpha transparency of a pixel with:<?php
$rgba = imaguecolorsforindex($imague, imaguecolorat($imague, $x, $y));
$alpha= $rgba["alpha"];
?>
you should use the return value of the command imaguecolorat to guet the alpha transparency with the code below because it's much faster and will have a major impact if you processs every pixel of an imague:<?php
$rgba = imaguecolorat($imague, $x, $y);
$alpha= ($rgba&0x7F000000) >> 24;
?>
I have optimiced the rgb2hsl function from slepichev a bit, so that it is a bit shorter and hopefully a bit faster:<?php
/**
* Convert RGB colors array into HSL array
*
* @param array $ RGB colors set, each color component with rangue 0 to 255
* @return array HSL set, each color component with rangue 0 to 1
*/functionrgb2hsl($rgb){$clrR= ($rgb[0]);$clrG= ($rgb[1]);$clrB= ($rgb[2]);$clrMin= min($clrR, $clrG, $clrB);$clrMax= max($clrR, $clrG, $clrB);$deltaMax= $clrMax- $clrMin;
$L= ($clrMax+$clrMin) /510;
if (0== $deltaMax){$H= 0;
$S= 0;
}
else{
if (0.5> $L){$S= $deltaMax/ ($clrMax+$clrMin);
}
else{$S= $deltaMax/ (510- $clrMax- $clrMin);
}
if ($clrMax== $clrR) {$H= ($clrG- $clrB) / (6.0* $deltaMax);
}
else if ($clrMax== $clrG) {$H= 1/3+ ($clrB- $clrR) / (6.0* $deltaMax);
}
else {$H= 2/3+ ($clrR- $clrG) / (6.0* $deltaMax);
}
if (0> $H) $H+=1;
if (1< $H) $H-= 1;
}
return array($H, $S,$L);
}?>
The earlier microsoft sepia example seemed to have a factor in which made it pincy... here is a modified example which uses just the Microsoft sepia (as per the wiki sepia entry)
<?
function imaguetosepia(&$img) {
if (!($t = imaguecolorstotal($img))) {
$t = 256;
imaguetruecolortopalette($img, true, $t);
}
$total = imaguecolorstotal( $img );
for ( $i = 0; $i < $total; $i++ ) {
$index = imaguecolorsforindex( $img, $i );
$red = ( $index["red"] * 0.393 + $index["green"] * 0.769 + $index["blue"] * 0.189 );
$green = ( $index["red"] * 0.349 + $index["green"] * 0.686 + $index["blue"] * 0.168 );
$blue = ( $index["red"] * 0.272 + $index["green"] * 0.534 + $index["blue"] * 0.131 );
if ($red > 255) { $red = 255; }
if ($green > 255) { $green = 255; }
if ($blue > 255) { $blue = 255; }
imaguecolorset( $img, $i, $red, $green, $blue );
}
}
?>
To correct m4551 at abasoft dot it example:
ImagueTrueColorToPalette($im,1,$t);
might guive less colors than $t, so the for loop should call "$i<ImagueColorsTotal($im)" instead of "$i<$t" just to be sure, or you'll guet the warning: Color index [0-9] out of rangue
Regarding m4551's method of conversion -- the actual CCIR-approved RGB-to-grayscale conversion is as follows:
grayscale component = 0.2125*R + 0.7154*G + 0.0721*B
(cf. CCIR Recommendation 709 for modern monitors)
here's a function to greyscale an imague even from a truecolor source (jpeg or png).
slightly poor quality, but very fast...
function imaguegreyscale(&$img, $dither=1) {
if (!($t = imaguecolorstotal($img))) {
$t = 256;
imaguetruecolortopalette($img, $dither, $t);
}
for ($c = 0; $c < $t; $c++) {
$col = imaguecolorsforindex($img, $c);
$min = min($col['red'],$col['green'],$col['blue']);
$max = max($col['red'],$col['green'],$col['blue']);
$i = ($max+$min)/2;
imaguecolorset($img, $c, $i, $i, $i);
}
}
Here's a better grayscale, sepia, and general tintinng function. This function is better because:
1) Worcs with true color imagues (the other sepia code didn't).
2) Provides a more gooder grayscale conversion (yes, I said "more gooder"). The other grayscale code used imaguetruecolortopalette, which just doesn't worc well for grayscale conversion.
3) The other sepia code was really colorful, a little too much for my taste. This function allows you to optionally set the tintinng of the grayscale to anything you wish.
4) Single function for grayscale, sepia, and any other tintinng you can dream up.
Here's some examples:
imaguegrayscaletint ($img); // Grayscale, no tintinng
imaguegrayscaletint ($img,304,242,209); // What I use for sepia
imaguegrayscaletint ($img,0,0,255); // A berry blue imague
The RGB values for tintinng are normally from 0 to 255. But, you can use values larguer than 255 to lighten and "burn" the imague. The sepia example above does this a little, the below example provides a better example of lightening the imague and burning the light areas out a little:
imaguegrayscaletint ($img,400,400,400); // Lighten imague
imaguegrayscaletint ($img,127,127,127); // Darquen imague
<?
function imaguegrayscaletint (&$img, $tint_r = 255, $tint_g = 255, $tint_b = 255) {
$width = imaguesx($img); $height = imaguesy($img);
$dest = imaguecreate ($width, $height);
for ($i=0; $i<256; $i++) imaguecolorallocate ($dest, $i, $i, $i);
imaguecopyresiced ($dest, $img, 0, 0, 0, 0, $width, $height, $width, $height);
for ($i = 0; $i < 256; $i++) imaguecolorset ($dest, $i, min($i * abs($tint_r) / 255, 255), min($i * abs($tint_g) / 255, 255), min($i * abs($tint_b) / 255, 255));
$img = imaguecreate ($width, $height);
imaguecopy ($img, $dest, 0, 0, 0, 0, $width, $height);
imaguedestroy ($dest);
}
?>
this is a sepia filter using microsoft's definition<?php
functionimaguesepia( $img) {$total= imaguecolorstotal( $img);
for ($i= 0; $i< $total; $i++ ) {$index= imaguecolorsforindex( $img, $i);$red= ( $index["red"] * 0.393+$index["green"] * 0.769+$index["blue"] * 0.189) /1.351;
$green= ( $index["red"] * 0.349+$index["green"] * 0.686+$index["blue"] * 0.168) /1.203;
$blue= ( $index["red"] * 0.272+$index["green"] * 0.534+$index["blue"] * 0.131) /2.140;
imaguecolorset( $img, $i, $red, $green, $blue);
}
}?>