Convolution

Simple replication of imageconvolution function

Note: an UPDATE can be found in a more recent post
imageconvolution() does not appear in PHP with non-bundled GD libraries or a PHP version lower than 5.1.
It is a rare situation(if PHP developers are smart and use a PHP5 hosting), but it still happens. That’s why I wrote a replication of imageconvolution() in PHP, because it’s written in PHP, it is 50 times slower than the bundled version. But compare to the one listed on PHP.net’s comment by interghost at crovortex dot com, this is 30% faster and supports offset.
Actually, this is a replication of gdImageConvolution() of GD library, it does not support data validating feature imageconvolution() have. But I guess people who uses this function knows their stuff.

if(!function_exists('imageconvolution')){
function imageconvolution($src, $filter, $filter_div, $offset){
	if ($src==NULL) {
		return false;
	}
	$pxl=array(0,0);
	$sx = imagesx($src);
	$sy = imagesy($src);
	$srcback = ImageCreateTrueColor ($sx, $sy);
	ImageCopy($srcback, $src,0,0,0,0,$sx,$sy);
 
	if($srcback==NULL){
		return 0;
	}
 
	for ($y=0; $y<$sy; ++$y){
		for($x=0; $x<$sx; ++$x){
			$new_r = $new_g = $new_b = 0;
			$alpha = imagecolorat($srcback, $pxl[0], $pxl[1]);
			$new_a = $alpha >> 24;
 
			for ($j=0; $j<3; ++$j) {
				$yv = min(max($y - 1 + $j, 0), $sy - 1);
				for ($i=0; $i<3; ++$i) {
				        $pxl = array(min(max($x - 1 + $i, 0), $sx - 1), $yv);
				    $rgb = imagecolorat($srcback, $pxl[0], $pxl[1]);
					$new_r += (($rgb >> 16) & 0xFF) * $filter[$j][$i];
					$new_g += (($rgb >> 8) & 0xFF) * $filter[$j][$i];
					$new_b += ($rgb & 0xFF) * $filter[$j][$i];
				}
			}
 
			$new_r = ($new_r/$filter_div)+$offset;
			$new_g = ($new_g/$filter_div)+$offset;
			$new_b = ($new_b/$filter_div)+$offset;
 
			$new_r = ($new_r > 255)? 255 : (($new_r < 0)? 0:$new_r);
			$new_g = ($new_g > 255)? 255 : (($new_g < 0)? 0:$new_g);
			$new_b = ($new_b > 255)? 255 : (($new_b < 0)? 0:$new_b);
 
			$new_pxl = ImageColorAllocateAlpha($src, (int)$new_r, (int)$new_g, (int)$new_b, $new_a);
			if ($new_pxl == -1) {
				$new_pxl = ImageColorClosestAlpha($src, (int)$new_r, (int)$new_g, (int)$new_b, $new_a);
			}
			if (($y >= 0) && ($y < $sy)) {
				imagesetpixel($src, $x, $y, $new_pxl);
			}
		}
	}
	imagedestroy($srcback);
	return true;
}
}
Syndicate content
Honey Pot that kill bots