Blurring an image - Advanced convolution [56kb warning]

Need help with Photoshop, the GIMP, Illustrator, or others? Want to show off your work? Looking for advice on your newest Flash stuff?

Moderator: General Moderators

Post Reply
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Blurring an image - Advanced convolution [56kb warning]

Post by onion2k »

Note to mods: Don't move this to code snippets coz it's unoptimized and not useable yet. It'll undergo improvements.

Note: Updated the convolution code .. approx 8 times faster now. Still slow though.

I've been working on a new and improved image convolution script .. so far so good so I thought I'd share some results:

Image

What's going on in the image there then?

By taking a 7*7 convolution matrix as follows and multipling all the pixels in the image against it you can calculate the values of new pixels as an "average" of the pixels around it .. hence the blur effect.

The Matrix:

Code: Select all

$m = array(	array(1,0,0,0,0,0,1),
				array(0,2,0,0,0,2,0),
				array(0,0,2,4,2,0,0),
				array(0,0,4,8,4,0,0),
				array(0,0,2,4,2,0,0),
				array(0,2,0,0,0,2,0),
				array(1,0,0,0,0,0,1)
			  );
The convolution script:

Code: Select all

$time_start = microtime_float();

	// Blur
	$m = array(	array(1,0,0,0,0,0,1),
				array(0,2,0,0,0,2,0),
				array(0,0,2,4,2,0,0),
				array(0,0,4,8,4,0,0),
				array(0,0,2,4,2,0,0),
				array(0,2,0,0,0,2,0),
				array(1,0,0,0,0,0,1)
			  );
	$f = array_sum_multi($m);
	$c = 0;
	
	$m_elements = count($m);
	$m_offset = floor($m_elements/2);
  
	for ($m_y=0;$m_y<$m_elements;$m_y++) {
		for ($m_x=0;$m_x<$m_elements;$m_x++) {			
			$mx[$m[$m_x][$m_y]][] = array($m_x-$m_offset,$m_y-$m_offset);
		}
	}

	$original = imagecreatefromjpeg("xxx.jpg");
	
	$source = imagecreatetruecolor(imagesx($original)+($m_offset*2),imagesy($original)+($m_offset*2));
	$red = imagecolorallocate($source,255,0,0);
	imagecopy($source, $original, $m_offset, $m_offset, 0, 0, imagesx($original),imagesy($original));

	imagecopyresampled($source, $original, 0, 0, 0, 0, imagesx($original)+($m_offset*2), $m_offset, imagesx($original), $m_offset);
	imagecopyresampled($source, $original, 0, imagesy($original)+$m_offset, 0, imagesy($original)-$m_offset, imagesx($original)+($m_offset*2), $m_offset, imagesx($original), $m_offset);
	imagecopy($source, $original, 0, $m_offset, 0, 0, $m_offset, imagesy($original));
	imagecopy($source, $original, imagesx($original)+$m_offset, $m_offset, imagesx($original)-$m_offset, 0, $m_offset, imagesy($original));

	$image = imagecreatetruecolor(imagesx($original),imagesy($original));

	for ($y=0;$y<imagesy($source);$y++) {
		for ($x=0;$x<imagesx($source);$x++) {
			$t1 = imagecolorat($source,$x,$y);
			$p[$x][$y]['r'] = ($t1 >> 16) & 0xFF;
			$p[$x][$y]['g'] = ($t1 >>  & 0xFF;
			$p[$x][$y]['b'] = $t1 & 0xFF;
		}
	}

	for ($y=$m_offset;$y<imagesy($original)+$m_offset;$y++) {
		for ($x=$m_offset;$x<imagesx($original)+$m_offset;$x++) {
		
			$pixel_r = 0;
			$pixel_g = 0;
			$pixel_b = 0;

		// Slooooooooooooooooooooow
		//	for ($m_y=0;$m_y<$m_elements;$m_y++) {
		//		for ($m_x=0;$m_x<$m_elements;$m_x++) {			
		//			$pixel_r += ($p[$x+($m_x-$m_offset)][$y+($m_y-$m_offset)]['r']*$m[$m_x][$m_y]);
		//			$pixel_g += ($p[$x+($m_x-$m_offset)][$y+($m_y-$m_offset)]['g']*$m[$m_x][$m_y]);
		//			$pixel_b += ($p[$x+($m_x-$m_offset)][$y+($m_y-$m_offset)]['b']*$m[$m_x][$m_y]);
		//		}
		//	}

		// Bit quicker
			foreach ($mx as $m => $a)	{
				if ($m != 0) {
					$pixel_r_temp = 0;
					$pixel_g_temp = 0;
					$pixel_b_temp = 0;
					foreach ($a as $avals) {
					
						$xt = $x+$avals[0];
						$yt = $y+$avals[1];

						$pixel_r_temp += ($p[$xt][$yt]['r']);
						$pixel_g_temp += ($p[$xt][$yt]['g']);
						$pixel_b_temp += ($p[$xt][$yt]['b']);

					}
					$pixel_r += $pixel_r_temp*$m;
					$pixel_g += $pixel_g_temp*$m;
					$pixel_b += $pixel_b_temp*$m;
				}
			}

			$pixel_r = ($pixel_r/$f)+$c;
			$pixel_g = ($pixel_g/$f)+$c;
			$pixel_b = ($pixel_b/$f)+$c;

			$col = imagecolorallocate($image,$pixel_r,$pixel_g,$pixel_b);

			imagesetpixel($image,$x-$m_offset,$y-$m_offset,$col);
		}
	}
	
	$black = imagecolorallocate($image,0,0,0);

	$time_end = microtime_float();
	$time = $time_end - $time_start;

	imagestring($image, 3, 5, 5, $time, $black);

	header("Content-Type: image/jpeg");
	imageJPEG($image,"",100);


	function array_sum_multi($a) {
		if(!is_array($a)) return $a;
		foreach($a as $key=>$value) {
			$total += array_sum_multi($value);
		}
		return $total;
	}

	function microtime_float() {
		list($usec, $sec) = explode(" ", microtime());
		return ((float)$usec + (float)$sec);
	}
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Post by malcolmboston »

bloody awesome, as usual
User avatar
hawleyjr
BeerMod
Posts: 2170
Joined: Tue Jan 13, 2004 4:58 pm
Location: Jax FL & Spokane WA USA

Post by hawleyjr »

You blurred her face but left her ear??? I vote for showing the face and blurring the ear.

:lol: :lol: :lol: :lol: :lol:

Very nice :)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

hawleyjr wrote:You blurred her face but left her ear??? I vote for showing the face and blurring the ear.

:lol: :lol: :lol: :lol: :lol:

Very nice :)
I agree....she's pretty hot 8)
Ree
Forum Regular
Posts: 592
Joined: Fri Jun 10, 2005 1:43 am
Location: LT

Post by Ree »

It would have been nice if you showed two full pics (blurred and original) rather than half of both.

Cool stuff, 'nuff said.
deano_1987
Forum Newbie
Posts: 1
Joined: Sun Aug 15, 2010 12:40 pm
Location: Cannock, United Kingdom

Re: Blurring an image - Advanced convolution [56kb warning]

Post by deano_1987 »

Hey guys, I made some small changes to this script so I could load a GIF with transparency :) I will post again soon with a more updated version for handling any file you chuck at it (with reason...).

Hope this is useful to people :)

Code: Select all

<?php
//Blur Script
//Created by: onion2k
//From Fourms: http://forums.devnetwork.net
//Modified by: Dean Williams
//Website: http://dean.resplace.net

//Filename
$name="mygif.gif";

//$time_start = microtime_float();
// Blur
$m = array(     array(1,0,0,0,0,0,1),
                        array(0,2,0,0,0,2,0),
                        array(0,0,2,4,2,0,0),
                        array(0,0,4,8,4,0,0),
                        array(0,0,2,4,2,0,0),
                        array(0,2,0,0,0,2,0),
                        array(1,0,0,0,0,0,1)
                  );
$f = array_sum_multi($m);
$c = 0;
$m_elements = count($m);
$m_offset = floor($m_elements/2);
for ($m_y=0;$m_y<$m_elements;$m_y++) {
        for ($m_x=0;$m_x<$m_elements;$m_x++) {                 
                $mx[$m[$m_x][$m_y]][] = array($m_x-$m_offset,$m_y-$m_offset);
        }
}
//Un-comment for accepting filename via $_GET.
//$name=str_replace(array("/","\\"),array("",""),$_GET['f']);
$original = imagecreatefromgif($name);
imagealphablending($original, false);
imagesavealpha($original, true);
$source = imagecreatetruecolor(imagesx($original)+($m_offset*2),imagesy($original)+($m_offset*2));
imagealphablending($source, true);
$bg = ImageColorAllocateAlpha($source, 255, 255, 255, 127); // (PHP 4 >= 4.3.2, PHP 5)
ImageFill($source, 0, 0 , $bg);
$red = imagecolorallocate($source,255,0,0);
imagecopyresampled($source, $original, $m_offset, $m_offset, 0, 0, imagesx($original),imagesy($original), imagesx($original),imagesy($original));
imagecopyresampled($source, $original, 0, 0, 0, 0, imagesx($original)+($m_offset*2), $m_offset, imagesx($original), $m_offset);
imagecopyresampled($source, $original, 0, imagesy($original)+$m_offset, 0, imagesy($original)-$m_offset, imagesx($original)+($m_offset*2), $m_offset, imagesx($original), $m_offset);
imagecopyresampled($source, $original, 0, $m_offset, 0, 0, $m_offset, imagesy($original), $m_offset, imagesy($original));
imagecopyresampled($source, $original, imagesx($original)+$m_offset, $m_offset, imagesx($original)-$m_offset, 0, $m_offset, imagesy($original), $m_offset, imagesy($original));
$image = imagecreatetruecolor(imagesx($original),imagesy($original));
$bg = ImageColorAllocateAlpha($image, 255, 255, 255, 127); // (PHP 4 >= 4.3.2, PHP 5)
ImageFill($image, 0, 0 , $bg);
for ($y=0;$y<imagesy($source);$y++) {
        for ($x=0;$x<imagesx($source);$x++) {
                $t1 = imagecolorat($source,$x,$y);
                $p[$x][$y]['r'] = ($t1 >> 16) & 0xFF;
                $p[$x][$y]['g'] = ($t1 >> 8) & 0xFF;
                $p[$x][$y]['b'] = $t1 & 0xFF; 
        }
}
for ($y=$m_offset;$y<imagesy($original)+$m_offset;$y++) {
        for ($x=$m_offset;$x<imagesx($original)+$m_offset;$x++) {
       
                $pixel_r = 0;
                $pixel_g = 0;
                $pixel_b = 0;
        // Slooooooooooooooooooooow
        //      for ($m_y=0;$m_y<$m_elements;$m_y++) {
        //              for ($m_x=0;$m_x<$m_elements;$m_x++) {                 
        //                      $pixel_r += ($p[$x+($m_x-$m_offset)][$y+($m_y-$m_offset)]['r']*$m[$m_x][$m_y]);
        //                      $pixel_g += ($p[$x+($m_x-$m_offset)][$y+($m_y-$m_offset)]['g']*$m[$m_x][$m_y]);
        //                      $pixel_b += ($p[$x+($m_x-$m_offset)][$y+($m_y-$m_offset)]['b']*$m[$m_x][$m_y]);
        //              }
        //      }
        // Bit quicker
                foreach ($mx as $m => $a)       {
                        if ($m != 0) {
                                $pixel_r_temp = 0;
                                $pixel_g_temp = 0;
                                $pixel_b_temp = 0;
                                foreach ($a as $avals) {
                               
                                        $xt = $x+$avals[0];
                                        $yt = $y+$avals[1];
                                        $pixel_r_temp += ($p[$xt][$yt]['r']);
                                        $pixel_g_temp += ($p[$xt][$yt]['g']);
                                        $pixel_b_temp += ($p[$xt][$yt]['b']);
                                }
                                $pixel_r += $pixel_r_temp*$m;
                                $pixel_g += $pixel_g_temp*$m;
                                $pixel_b += $pixel_b_temp*$m;
                        }
                }
                $pixel_r = ($pixel_r/$f)+$c;
                $pixel_g = ($pixel_g/$f)+$c;
                $pixel_b = ($pixel_b/$f)+$c;
                $col = imagecolorallocate($image,$pixel_r,$pixel_g,$pixel_b);
                imagesetpixel($image,$x-$m_offset,$y-$m_offset,$col);
        }
}
$black = imagecolorallocate($image,0,0,0);
$time_end = microtime_float();
$time = $time_end - $time_start;
//imagestring($image, 3, 5, 5, $time, $black);
header("Content-Type: image/png");
imagePNG($image);
function array_sum_multi($a) {
        if(!is_array($a)) return $a;
        foreach($a as $key=>$value) {
                $total += array_sum_multi($value);
        }
        return $total;
}
function microtime_float() {
        list($usec, $sec) = explode(" ", microtime());
        return ((float)$usec + (float)$sec);
}
?>
Post Reply