Some image filters for PHP GD

2011-07-23

I have recently written a few image filters for PHP GD: grayscale, invert colors and sepia tone. I can’t take all the credit for these functions. I found the method to get the RGB value for a pixel in the PHP documentation, and I have rewritten the sepia filter from another language. I wrote the two other functions myself. I guessed a little when I wrote the function for grayscale, but I think it looks quite good. There is an example and the function itself for each filter. This is the original image used in my examples:

Original Image

Original Image

Grayscale

Grayscale

Grayscale

<?php
function image_filter_grayscale(&$image){
	$width = imagesx($image);
	$height = imagesy($image);
	for($x = 0; $x < $width; $x++){
		for($y = 0; $y < $height; $y++){
			$rgb = imagecolorat($image, $x, $y);
			$r = ($rgb>>16)&0xFF;
			$g = ($rgb>>8)&0xFF;
			$b = $rgb&0xFF;
			$bw = (int)(($r+$g+$b)/3);
			$color = imagecolorallocate($image, $bw, $bw, $bw);
			imagesetpixel($image, $x, $y, $color);
		}
	}
}
?>

Inverted Colors

Inverted Colors

Inverted Colors

<?php
function image_filter_invert(&$image){
	$width = imagesx($image);
	$height = imagesy($image);
	for($x = 0; $x < $width; $x++){
		for($y = 0; $y < $height; $y++){
			$rgb = imagecolorat($image, $x, $y);
			$r = 0xFF-(($rgb>>16)&0xFF);
			$g = 0xFF-(($rgb>>8)&0xFF);
			$b = 0xFF-($rgb&0xFF);
			$color = imagecolorallocate($image, $r, $g, $b);
			imagesetpixel($image, $x, $y, $color);
		}
	}
}

?>

Sepia Tone

Sepia Tone

Sepia Tone

<?php
function image_filter_sepia(&$image){
	$width = imagesx($image);
	$height = imagesy($image);
	for($_x = 0; $_x < $width; $_x++){
		for($_y = 0; $_y < $height; $_y++){
			$rgb = imagecolorat($image, $_x, $_y);
			$r = ($rgb>>16)&0xFF;
			$g = ($rgb>>8)&0xFF;
			$b = $rgb&0xFF;

			$y = $r*0.299 + $g*0.587 + $b*0.114;
			$i = 0.15*0xFF;
			$q = -0.001*0xFF;

			$r = $y + 0.956*$i + 0.621*$q;
			$g = $y - 0.272*$i - 0.647*$q;
			$b = $y - 1.105*$i + 1.702*$q;

			if($r<0||$r>0xFF){$r=($r<0)?0:0xFF;}
			if($g<0||$g>0xFF){$g=($g<0)?0:0xFF;}
			if($b<0||$b>0xFF){$b=($b<0)?0:0xFF;}

			$color = imagecolorallocate($image, $r, $g, $b);
			imagesetpixel($image, $_x, $_y, $color);
		}
	}
}
?>

The image object is sent as a reference to the functions. Here is an example on how to call them:

<?php
header("Content-type: image/png");

$image = imagecreatefrompng("logo.png");

image_filter_grayscale($image);
image_filter_invert($image);
image_filter_sepia($image);

imagepng($image);
imagedestroy($image);
?>

If there is something wrong with the functions, or if you have a better way of doing it, please leave a comment.