Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Image Functions : imagecolorat

imagecolorat

Get the index of the color of a pixel (PHP 4, PHP 5)
int imagecolorat ( resource image, int x, int y )

Example 991. Access distinct RGB values

<?php
$im
= imagecreatefrompng("php.png");
$rgb = imagecolorat($im, 10, 15);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
?>

The above example will output something similar to:

int(119)
int(123)
int(180)

Code Examples / Notes » imagecolorat

ceresatdivxmaniadotit

To get RGB values of a pixel in a truecolor image:
<?
$image=imageCreateFromJPEG('image.jpg');
$x = 10;
$y = 15;
$colorindex = imagecolorat($image,$x,$y);
$colorrgb = imagecolorsforindex($image,$colorindex);
echo "RGB values of the pixel at position $x - $y are: $colorrgb['red'] $colorrgb['green'] $colorrgb['blue'] \n Apha value is: $colorrgb['alpha']";
?>


pocze_zsolt

This is a histogram-stretching function to get a better contrast:
function contrast_stretch( $img ) {
   $x = imagesx($img);
   $y = imagesy($img);
   $min=255.0;
   $max=0.0;
   for($i=0; $i<$y; $i++) {
   for($j=0; $j<$x; $j++) {
       $pos = imagecolorat($img, $j, $i);
       $f = imagecolorsforindex($img, $pos);
       $gst = $f["red"]*0.15 + $f["green"]*0.5 + $f["blue"]*0.35;
       if($gst>$max) $max=$gst;
       if($gst<$min) $min=$gst;
   }
   }
   $distance = $max-$min;
   for($i=0; $i<$y; $i++) {
   for($j=0; $j<$x; $j++) {
       $pos = imagecolorat($img, $j, $i);
       $f = imagecolorsforindex($img, $pos);
       $red = 255*($f["red"]-$min)/$distance;
       $green = 255*($f["green"]-$min)/$distance;
       $blue = 255*($f["blue"]-$min)/$distance;
       if($red<0) $red = 0.0;
       elseif($red>255) $red=255.0;
       if($green<0) $green = 0.0;
       elseif($green>255) $green=255.0;
       if($blue<0) $blue = 0.0;
       elseif($blue>255) $blue=255.0;
       $color = imagecolorresolve($img, $red, $green, $blue);
       imagesetpixel($img, $j, $i, $color);
   }
   }
}


swimgod

this function i made will compare two($start-$finish) images and change the pixels with diffrent colors in the "finish" image
then displays them both next to each other in one image
another feature is "display" which will echo text
"50% on
50% off"-% count(if the number is lower then 1 it will go into one decamil count
or type "2" will be
"10023 on
3000 off"-pixel count
one last feature is "color"
which you define in an array
$color = array("r" => "244","g" => "122","b" => "100");
to finish up the discrpition im gonna show this "map" of my function
compare($start, $finish[, $color[, $display[, $type]]])
image-url($start) - base image URL
image-url($finish) - compare image URL
array($color) - array with keys "r", "g", "b" r being RED 0-255 g being GREEN 0-255 b being BLUE 0-255
bool($display) - 1 OR TRUE will return text stats from compare
int($type) - 1 OR 0 | 1 being % results | 0 being pixel results
<?
function compare($start, $finish, $color, $display, $type){
$im = ImageCreateFrompng($start);
$im2 = ImageCreateFrompng($finish);
$img['x'] = imagesx($im);
$img['y'] = imagesy($im);
$img2['x'] = imagesx($im2);
$img2['y'] = imagesy($im2);
if(($img['x'] == $img2['x']) && ($img['y'] == $img2['y'])){
//get and set image hieght and width
$i = array("width" =>  $img['x']*2, "height" => $img['y']);
$im3 = imagecreatetruecolor($i['width'], $i['height']);
if($color){
$color = imagecolorallocate($im3, $color['r'], $color['g'], $color['b']);
}else{
$color = imagecolorallocate($im3, 255, 255, 255);
}
for($y = $img['y'];$y > 0; $y--){
for($x = $img['x'];$x > 0; $x--){
if(ImageColorAt($im, $x, $y) == ImageColorAt($im2, $x, $y)){
$on = $on+1;
$rgb = ImageColorAt($im, $x, $y);
Imagesetpixel($im3, $img['x']+$x, $y, $rgb);
}else{
$off = $off+1;
imagesetpixel($im3, $img['x']+$x, $y , $color);
}
}
}
if($display == true){
if(($type == "1") || (!$type)){
$off2 = (round(($off / $on)*10));
if(($off2 == 0) && ($off > 0)){
$off2 = round(($off / $on)*10)*10;
}
$on2 = (100-$off2);
$off2 .="%";
$on2 .="%";
}else{
$off2 = $off;
$on2 = $on;
}
echo $off2 ." off
". $on2 ." on";
}else{
imagecopy($im3, $im, 0, 0, 0, 0, $img['x'], $img['y']);
@header("Content-type: image/png");
imagepng($im3);
imagedestroy($im3);
}
imagedestroy($im);
imagedestroy($im2);
return TRUE;
}else{
return False;
}
}
?>


geat

The HTML image renderer didn't work for me for some reason, but here's a version that does...
echo '<table border="0" cellspacing="0" cellpadding="0">';
$im = ImageCreateFromJPEG("IMAGE NAME");
$width = imagesx($im);
$height = imagesy($im);
for ($cy=0;$cy<$height;$cy++) {
 echo '<tr>';
 for ($cx=0;$cx<$width;$cx++) {
   $rgb = ImageColorAt($im, $cx, $cy);
   $col = imagecolorsforindex($im, $rgb);
   printf('<td width="2" height="2" bgcolor=#%02x%02x%02x></td>', $col["red"], $col["green"], $col["blue"]);
 }
echo '</tr>';
}
echo '</table>';


bpgordon

The following code converts a png image to an html table made up of colored 1x1 cells. Put the path (relative to the location of the script) to the image to be converted in the query, like this: http://yoursite.com/conv.php?image.png
Remember that you can only use a remote path if remote fopen is enabled.
<?php
print "&lt;table border=0 cellpadding=0 cellspacing=0&gt;&lt;tr&gt;";
$image = imagecreatefrompng($_ENV["QUERY_STRING"]);
$xdim = imagesx($image);
$ydim = imagesy($image);
for ($x = 1; $x &lt;= $xdim-1; $x++) {
for ($y = 1; $y &lt;= $ydim-1; $y++) {
$rgb = imagecolorat($image, $x, $y);
$r = ($rgb &gt;&gt; 16) & 0xFF;
$g = ($rgb &gt;&gt; 8) & 0xFF;
$b = $rgb & 0xFF;
print "&lt;td width=\"1\" height=\"1\" style=\"background-color: rgb($r, $g, $b);\"&gt;&lt;/td&gt;";
}
print "&lt;/tr&gt;&lt;tr&gt;";
}
print "&lt;/tr&gt;&lt;/table&gt;";
?>


markignore.atsymbol.ignorepnod.co.uk

The example given for returning the RGB values from the function (using & 0xFF) didn't work for me for PNG or GIF images. If you have this problem, try the following (which works):
<?php
 $pixelrgb = imagecolorat($source,$x,$y);
 $cols = imagecolorsforindex($source, $pixelrgb);
 $r = $cols['red'];
 $g = $cols['green'];
 $b = $cols['blue'];
?>


18-jan-2005 10:08

Optimal:
<?php
$rgb = imagecolorat($im, $x, $y);
$r = ($rgb >> 16);
$g = ($rgb >> 8) & 255;
$b = $rgb & 255;
?>
As you see, you can also use decimal values (faster).


robert

Look mom, no tables :)
I made some changes to the code from 'hazard AT krankteil DOTTILLYDO de' so the function would output a div that displays the image.
As for the size of the outputted file I can say the original png file was lots smaller, but maybe its a nice feature for small buttons or such.
The way you can use it is the same as the code from 'hazard AT krankteil DOTTILLYDO de'.
litle note: each div contains a bogus image. When this is not in IE will screw up the output.
<?
   function hexcolor($c) {
       $r = ($c >> 16) & 0xFF;
       $g = ($c >> 8) & 0xFF;
       $b = $c & 0xFF;
       return '#'.str_pad(dechex($r), 2, '0', STR_PAD_LEFT).str_pad(dechex($g), 2, '0', STR_PAD_LEFT).str_pad(dechex($b), 2, '0', STR_PAD_LEFT);
   }
   
 
   function png2div($filename) {
    $img = imagecreatefrompng($filename);
       $width = imagesx($img);
       $height = imagesy($img);
       $div_width = 1;
       $previous_color = 0;
       
       $output = '<div style="position:relative;width:' . $width . 'px;height:'. $height .'px;">';
       
       for($y = 0;$y < $height;++$y){
       
        for($x = 0;$x < $width;++$x){
$current_color = ImageColorAt($img, $x, $y);

if($current_color == $previous_color && $x < $width-1){
++$div_width;
}
else{
$output .= '<div style="position:relative;float:left;width:' . $div_width . 'px;height:1px;background-color:' . hexcolor((($div_width > 1)? $previous_color:$current_color)) . '"><img src="bogus.gif" alt="" width="1" height="1" /></div>';
        $previous_color = $current_color;
        $div_width = 1;
}
        }
        ob_flush();
       }
     
       $output .= '</div>';
       
       return $output;
   
   }
?>


sys no spam coder

Just for fun: another snippet for drawing images using html only X)
<html>
<head>
<style>
<!--
body {
font-family: courier new, courier;
font-size: 7pt;
background: #000000;
color: #000000;
}
-->
</style>
</head>
<body>
<font color="#000000">
<?php
$im = ImageCreateFromPng($_GET['img']);
$lastcolor=0;
for($y=0;$y<imagesy($im);$y++)
{
 for($x=0;$x<imagesx($im);$x++)
 {
   $pixel = ImageColorAt($im, $x, $y);
   if($lastcolor != $pixel)
   {
     printf('</font><font color="#%06x">', $pixel);
     $lastcolor = $pixel;
   }
   echo "*";
 }
 echo "<br />";
}
?>
</font>
</body>
</html>


28-may-2003 04:54

Just for fun, here is a little snippet that "paints" a image in html only. Try it out with very small images, as this is a real browser-killer. mozilla > 120mb ram, ie > 100mb with a 300x200 image :-)
$file = "image.png";
$im = imagecreatefrompng($file);
$size_arr = getimagesize($file);
echo "<table width=".$size_arr[0]." height=".$size_arr[1]." cellpadding=0 cellspacing=0 border=0>";
for ($y=0; $y<$size_arr[1]; $y++) {
echo "<tr>";
for ($x=0; $x<$size_arr[0]; $x++) {
$rgb = ImageColorAt($im, $x, $y);
printf("<td width=1 bgcolor=%06x><img width=1></td>", $rgb);
}
echo "</tr>";
}
echo "</table>";


lachy

It seems that if you don not have GD 2.0.1+ then the alpha value will not be available.

jed

In my various play stages with photomosaics I ended up writing this function that works with GD 2. The conversion from RGB to HSL is straightforward and there are a number of papers on it on our beloved Internet; however, this function simply finds the lightness value for a pixel and works exactly the same as imagecolorat().
<?php
/* Computes the lightness of a pixel. Lightness is used in HSL notation, as well
* as in various operations on images. This function returns a normalized value
* for lightness between 0 and 1, inclusive (0.0 being black, 1.0 being white).
*
* double imagelightnessat(resource img, int x, int y)
* img An open image resource to operate on (true color or palette)
* x, y The coordinates of the pixel to work on
*
* by Jed Smith <?php $u = "jed"; $d = "bz"; printf("<%s@%s.%s>", $u, $u, $d) ?>
*/
function imagelightnessat($img, $x, $y)
{
if(!is_resource($img))
{
trigger_error("imagelightnessat(): supplied argument is not a valid "
. "Image resource", E_USER_WARNING);
return 0.0;
}
$c = @imagecolorat($img, $x, $y);
if($c === false) return false;
if(imageistruecolor($img))
{
$red = ($c >> 16) & 0xFF;
$green = ($c >> 8) & 0xFF;
$blue = $c & 0xFF;
}
else
{
$i = imagecolorsforindex($img, $c);
$red = $i['red'];
$green = $i['green'];
$blue = $i['blue'];
}
$m = min($red, $green, $blue);
$n = max($red, $green, $blue);
/* Because RGB isn't normalized in GD, we divide by 510 here.
*  Lightness = (Max(RGB) + Min(RGB)) / 2
* But that's assuming red, green, and blue are 0 through 1 inclusive.
* Red, green, and blue are actually 0-255 (255 + 255 = 510).
*/
$lightness = (double)(($m + $n) / 510.0);
return($lightness);
}
?>


t. dekker

In GD 2.x there is support for true color images complete with an alpha channel. GD 2.x has a 7-bit (0-127) alpha channel.
While most people are used to an 8-bit (0-255) alpha channel, it is actually quite handy that GD's is 7-bit (0-127). Each pixel is represented by a 32-bit signed integer, with the four 8-bit bytes arranged like this:
High Byte <--> Low Byte
{Alpha Channel} {Red} {Green} {Blue}
For a signed integer, the leftmost bit, or the highest bit, is used to indicate whether the value is negative, thus leaving only 31 bits of actual information. PHP's default integer value is a signed long into which we can store a single GD palette entry. Whether that integer is positive or negative tells us whether antialiasing is enabled for that palette entry.


mumig

imagecolorat() works differently for png's with true color and for paletted png's - for true color it returns value of color, for paletted it returns index number and you have to use  imagecolorsforindex() to get rgb color value.

gromitt

imagecolorat() will display a Notice if you attempt to query a pixel which is out of bounds, and will return false :
<?php
$img = imagecreatefromjpeg('test.jpg');
var_dump(imagecolorat($img, -1, 0));
?>
Output :
Notice: imagecolorat(): -1,0 is out of bounds in /test.php on line 4
bool(false)


creamdog

If you look in the gd library for C in gd.h you have the following defined for truecolor images.
#define gdTrueColorGetAlpha(c) (((c) & 0x7F000000) >> 24)
#define gdTrueColorGetRed(c) (((c) & 0xFF0000) >> 16)
#define gdTrueColorGetGreen(c) (((c) & 0x00FF00) >> 8)
#define gdTrueColorGetBlue(c) ((c) & 0x0000FF)
So in php you could just do it as so:
$rgba = imagecolorat($im,$x,$y);
$alpha = ($rgba & 0x7F000000) >> 24;
$red = ($rgba & 0xFF0000) >> 16;
$green = ($rgba & 0x00FF00) >> 8;
$blue = ($rgba & 0x0000FF);
And there you have what you would need if you have a truecolor image with an alpha channel.


pete

If you have a truecolor image and absolutely need to get the actual color of a pixel, it seems like you could create a 16x16 indexed color image from a part of the True Color image containing the pixel(s) in question. Then you should be able to guarantee that the indexed sample has the indentical colors to the True Color image. you can then use this function to get the color index of a pixel in the sample.
Obviously, this would be an intensive way to get pixel colors, especially for a large image, but as far as I can tell, it's one of the very few ways to do it right now.


hazard

I saw this png to table code.. and i had written one before =)
My code does nearly the same as the one posted.. but it will compress the table with the help of colspan :)
http://hazard.krankteil.de/stuff/pngtable/imgtest.php
Code:
http://hazard.krankteil.de/stuff/pngtable/imgtest.phps
http://hazard.krankteil.de/stuff/pngtable/image.phps
It's senseless? Well maybe but kinda cool :) Try 5 or 10 as second argument for pngtable() =)


luciano ropero

I made a function that calculates the average color of a given image resource and returns it in "#rrggbb" format (hex):
function average($img) {
$w = imagesx($img);
$h = imagesy($img);
$r = $g = $b = 0;
for($y = 0; $y < $h; $y++) {
for($x = 0; $x < $w; $x++) {
$rgb = imagecolorat($img, $x, $y);
$r += $rgb >> 16;
$g += $rgb >> 8 & 255;
$b += $rgb & 255;
}
}
$pxls = $w * $h;
$r = dechex(round($r / $pxls));
$g = dechex(round($g / $pxls));
$b = dechex(round($b / $pxls));
if(strlen($r) < 2) {
$r = 0 . $r;
}
if(strlen($g) < 2) {
$g = 0 . $g;
}
if(strlen($b) < 2) {
$b = 0 . $b;
}
return "#" . $r . $g . $b;
}
Although, I've noticed that you can also get a fairly good average color generating a 1px by 1px copy with imagecopyresampled (the pixel generated is colored with the average color).


super moi

Here is a contribution for change tint.
function colorize($path_image, $red, $green, $blue)
{
  $im = imagecreatefrompng($path_image);
$pixel = array();

$n_im = imagecreatetruecolor(imagesx($im),imagesy($im));
$fond = imagecolorallocatealpha($n_im, 255, 255, 255, 0);
imagefill($n_im, 0, 0, $fond);

for($y=0;$y<imagesy($n_im);$y++)
{
for($x=0;$x<imagesx($n_im);$x++)
{
$rgb = imagecolorat($im, $x, $y);
$pixel = imagecolorsforindex($im, $rgb);

$r = min(round($red*$pixel['red']/169),255);
$g = min(round($green*$pixel['green']/169),255);
$b = min(round($blue*$pixel['blue']/169),255);
$a = $pixel['alpha'];
//echo('red : '.$pixel['red'].' => '.$r.', green : '.$pixel['green'].' => '.$g.', blue : '.$pixel['blue'].' => '.$b.', alpha : '.$pixel['alpha'].' => '.$a.'
');

$pixelcolor = imagecolorallocatealpha($n_im, $r, $g, $b, $a);

imagealphablending($n_im, TRUE);
imagesetpixel($n_im, $x, $y, $pixelcolor);
}
}

  imagepng($n_im,'test.png');
  imagedestroy($n_im);
}


nuclearflux

code part from robert:
  $output .= '<div style="position:relative;float:left;width:' .
  $div_width . 'px;height:1px;background-color:' .
  hexcolor((($div_width > 1)?
  $previous_color:$current_color)) . '"><img src="bogus.gif"
  alt="" width="1" height="1" /></div>';
i've optimized this part so that no image is needed:
  $output .= '<div
  style="position:relative;float:left;max-width:1px>;
  max-height:1px;background-color:'.
  hexcolor((($div_width > 1)?
  $previous_color:$current_color)).'">&nbsp;</div>';
//sorry for my english, i'm a german xD


morten

A better way of encoding a color value to #rrggbb:
<?php
 printf('#%06x',$c);
?>
or
<?php
 $rgb = sprintf('#%06x',$c);
?>


29-nov-2006 12:45

//test if a Jpeg is greyscale or color
function iscolor($pic_adress){
   
// A Pixel is Greyscale if the r = B = G
   //example: colorpixel R=250, G=140 , B=19  Greyscale Pixel R=110, G= 110, B=110
   
   //we do a check of 10 Pixels to find out if the Picture is Greyscale
   $tocheck = 10;
   
   $iscolor=false;
   
   $temp= getimagesize($pic_adress);
   
   $x= $temp[0];
   $y= $temp[1];
   
   $im= imagecreatefromjpeg($pic_adress);
   //now check out the Pixels    
   for( $i = 0 ; $i< $tocheck && !$iscolor; $i++){
   
   
   // Here a Random Pixel is chosen
   $color = imagecolorat($im,rand(0,$x),rand(0,$y));
   
   //Problem color is an int
   //The Hex view on the number is RRGGBB
   // Here we get the blue part of the Pixel
   $blue = 0x0000ff & $color;
   
   $green = 0x00ff00 & $color;
  //The Green part we have to push 8 bits to the right to get an Compareable result
   $green = $green >> 8;
   $red =0xff0000 & $color;
   //red part needs to be pushed 16 bit
   $red = $red >> 16;
   // if one of the Pixels isnt Greyscale it breaks an you know this is a color picture
   if( $red!= $green || $green!= $blue){
       $iscolor = true;
       break;
       }
   }
   return $iscolor;
}


bpgordon

(the previous post was mistyped; please delete)
The following code converts a png image to an html table made up of colored 1x1 cells. Put the path (relative to the location of the script) to the image to be converted in the query, like this: http://yoursite.com/conv.php?image.png
Remember that you can only use a remote path if remote fopen is enabled.
<?php
print "<table border=0 cellpadding=0 cellspacing=0><tr>";
$image = imagecreatefrompng($_ENV["QUERY_STRING"]);
$xdim = imagesx($image);
$ydim = imagesy($image);
for ($x = 1; $x <= $xdim-1; $x++) {
for ($y = 1; $y <= $ydim-1; $y++) {
$rgb = imagecolorat($image, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
print "<td width=\"1\" height=\"1\" style=\"background-color: rgb($r, $g, $b);\"></td>";
}
print "</tr><tr>";
}
print "</tr></table>";
?>


Change Language


Follow Navioo On Twitter
gd_info
getimagesize
image_type_to_extension
image_type_to_mime_type
image2wbmp
imagealphablending
imageantialias
imagearc
imagechar
imagecharup
imagecolorallocate
imagecolorallocatealpha
imagecolorat
imagecolorclosest
imagecolorclosestalpha
imagecolorclosesthwb
imagecolordeallocate
imagecolorexact
imagecolorexactalpha
imagecolormatch
imagecolorresolve
imagecolorresolvealpha
imagecolorset
imagecolorsforindex
imagecolorstotal
imagecolortransparent
imageconvolution
imagecopy
imagecopymerge
imagecopymergegray
imagecopyresampled
imagecopyresized
imagecreate
imagecreatefromgd2
imagecreatefromgd2part
imagecreatefromgd
imagecreatefromgif
imagecreatefromjpeg
imagecreatefrompng
imagecreatefromstring
imagecreatefromwbmp
imagecreatefromxbm
imagecreatefromxpm
imagecreatetruecolor
imagedashedline
imagedestroy
imageellipse
imagefill
imagefilledarc
imagefilledellipse
imagefilledpolygon
imagefilledrectangle
imagefilltoborder
imagefilter
imagefontheight
imagefontwidth
imageftbbox
imagefttext
imagegammacorrect
imagegd2
imagegd
imagegif
imagegrabscreen
imagegrabwindow
imageinterlace
imageistruecolor
imagejpeg
imagelayereffect
imageline
imageloadfont
imagepalettecopy
imagepng
imagepolygon
imagepsbbox
imagepsencodefont
imagepsextendfont
imagepsfreefont
imagepsloadfont
imagepsslantfont
imagepstext
imagerectangle
imagerotate
imagesavealpha
imagesetbrush
imagesetpixel
imagesetstyle
imagesetthickness
imagesettile
imagestring
imagestringup
imagesx
imagesy
imagetruecolortopalette
imagettfbbox
imagettftext
imagetypes
imagewbmp
imagexbm
iptcembed
iptcparse
jpeg2wbmp
png2wbmp
eXTReMe Tracker