Hudzilla.org - the homepage of Paul Hudson
Contents > Multimedia > Images Wish List | Report Bug | About Me ]

11.2.25     Special FX, Blur

This is NOT the latest copy of this book; click here for the latest version.

If you managed to understand the improved pixelate algorithm, blurring an image will not be a problem as it follows almost exactly the same procedure. To blur an image, you need to iterate through each pixel in a picture and read the colour value of all pixels surrounding it. The new colour for each pixel is an average of its own plus the colours of those around it, however we need to set the colour of each pixel individually rather than just using a filled rectangle as in the pixelate algorithm.

Without further ado, here is the code:

function blur (&$image) {
    
$imagex = imagesx($image);
    
$imagey = imagesy($image);
    
$dist = 1;

    for (
$x = 0; $x < $imagex; ++$x) {
        for (
$y = 0; $y < $imagey; ++$y) {
            
$newr = 0;
            
$newg = 0;
            
$newb = 0;

            
$colours = array();
            
$thiscol = imagecolorat($image, $x, $y);

            for (
$k = $x - $dist; $k <= $x + $dist; ++$k) {
                for (
$l = $y - $dist; $l <= $y + $dist; ++$l) {
                    if (
$k < 0) { $colours[] = $thiscol; continue; }
                    if (
$k >= $imagex) { $colours[] = $thiscol; continue; }
                    if (
$l < 0) { $colours[] = $thiscol; continue; }
                    if (
$l >= $imagey) { $colours[] = $thiscol; continue; }
                    
$colours[] = imagecolorat($image, $k, $l);
                }
            }

            foreach(
$colours as $colour) {
                
$newr += ($colour >> 16) & 0xFF;
                
$newg += ($colour >> 8) & 0xFF;
                
$newb += $colour & 0xFF;
            }

            
$numelements = count($colours);
            
$newr /= $numelements;
            
$newg /= $numelements;
            
$newb /= $numelements;

            
$newcol = imagecolorallocate($image, $newr, $newg, $newb);
            
imagesetpixel($image, $x, $y, $newcol);
        }
    }
}

As you can see, that is almost identical to the pixelate function. The differences are that each pixel is looped through individually as opposed to incrementing the loop variables by $blocksize. Also, note that the $dist variable is used to decide how many adjacent pixels should be read. In the example above, $dist is set to 1, which means the algorithm averages the colour values of the current pixel, as well as the pixels immediately above, below, left, right, above-left, above-right, below-left, and below-right. Increasing that to two will read the values from the two pixels immediately above the current one, the two to the left, etc.

Below is image produced by running my test image through the blur effect.



My test image was 700 pixels wide by 400 high, making a total of 280,000 pixels. With $dist set to 1, PHP will read average nine values for each pixel, giving a total of 2,520,000 pixel reads. Once you add into that all the looping, dividing, colour allocation, and array manipulation, it should become clear that blurring an image is a very slow process and not one you want be do doing each time a page is requested. Just increasing $dist to 2 will make the script take a lot longer to execute.

However, there are benefits to increasing the $dist value. For example, the larger $dist is, the more blurred the final image is. The reason for this is because a large block of pixels is averaged to get the colour for the same one pixel, which means it is less likely to have its original colour. For sufficiently large values of $dist, the colour of each pixel will be calculated as the average of every other pixel in the image, essentially making the entire image the same colour.





<< 11.2.24 Special FX, Pixelate   11.2.26 Special FX, Other special effects >>
Table of Contents
Want to see this stuff in print? PHP in a Nutshell takes the core topics covered here, adds in thousands of edits from the editorial team and myself, and combines them to make an unbeatable reference for PHP programmers at all levels.



My latest book has hundreds more tips on how to use PHP, Apache, and MySQL, plus Perl, Python, shell scripts, performance tuning, and more!



Top-right shadow
 
Bottom-left shadow Bottom shadow

Comments from other readers
Justin - 08 Sep 2008

This is a great function for detailed images, but it doesn't work quite well for one of the scrips I was compiling. I made a script which took images, resized them to be smaller and fit into little image frames for thumbnail purposes. Now transparent images would show up as black where the transparency was meant to be, so I changed this to display as which, which was more appropriate for the frames. I was left with a thick black outline around the original image, and when I use a blur effect on this, it merely makes the black outline even thicker instead of actually toning it down, or helping it blend in a bit more.

Aside from that problem, this is a handy function to have.



Add comment
Please note that by posting a comment here you are committing it to the public domain. This is important so that others can make use of your code themselves, and also so that I can incorporate helpful notes directly into the main text. Comments are limited to 2000 characters in length.

If you are reporting an error in the content, please tell me directly.

Your name/email address:
Your comment:
 
Now, in order to verify that you're a real person, please answer this simple question: what is one plus four?
The answer is:
(please write in
numbers, eg 19)


Top-right shadow
 
Bottom-left shadow Bottom shadow