PHP imagesharpen()
The following example codes are
for very small, 16 × 16 pixel images (favicons) and thumbnails mainly.
It's not that difficult to adopt this code for larger images
(basically replace all
16
with $height
/$width
in the for
loops, see below).
However, it's not a good idea
to sharpen large images using these functions
because they are horrible slow.
favicon_sharpen_fast()
takes 0.0039 seconds
for a 16 × 16 pixel image
(on my machine, of course).
It uses only two surrounding pixels for the calculations.
favicon_sharpen_precise()
takes 0.0043 seconds.
That's 15% slower but looks a little bit better.
It uses all four surrounding pixels for the calculations.
These functions are based on code by Alex R. Austin
found in the user notes at
php.net
but are faster (even imagesharpen_precise()
is faster
than the code at php.net,
e.g. 8 instead of 9 seconds for a 800 × 600 pixel image).
Example script
<?php $thumbnail = imagecreatefromjpeg("thumbnail.jpg"); $favicon = imagecreatetruecolor(16, 16); imagecopyresampled($favicon, $thumbnail, 0, 0, 0, 0, 16, 16, imagesx($thumbnail), imagesy($thumbnail)); favicon_sharpen_precise($favicon); header("Content-type: image/png"); imagepng($favicon); imagedestroy($favicon); imagedestroy($thumbnail);
Fast sharpen a 16 × 16 pixel image
<?php function favicon_sharpen_fast($favicon) { $rs = array(); $gs = array(); $bs = array(); for ($y = 0; $y < 16; ++$y) { for ($x = 0; $x < 16; ++$x) { $rgb = imagecolorat($favicon, $x, $y); $rs[$y][$x] = $rgb >> 0x10; $gs[$y][$x] = $rgb >> 0x08 & 0xFF; $bs[$y][$x] = $rgb & 0xFF; } } for ($y = 1; $y < 16; ++$y) { $rd = $rs[$y][0]; $gd = $gs[$y][0]; $bd = $bs[$y][0]; $yd = $y - 1; for ($x = 1; $x < 16; ++$x) { $r = -($rs[$yd][$x] + $rd) / 2; $g = -($gs[$yd][$x] + $gd) / 2; $b = -($bs[$yd][$x] + $bd) / 2; $r += 2 * $rd = $rs[$y][$x]; $g += 2 * $gd = $gs[$y][$x]; $b += 2 * $bd = $bs[$y][$x]; if ($r < 0) $r = 0; elseif ($r > 255) $r = 255; if ($g < 0) $g = 0; elseif ($g > 255) $g = 255; if ($b < 0) $b = 0; elseif ($b > 255) $b = 255; imagesetpixel($favicon, $x, $y, $r << 0x10 | $g << 0x08 | $b); } } }
Precise sharpen a 16 × 16 pixel image
<?php function favicon_sharpen_precise($favicon) { $rs = array(); $gs = array(); $bs = array(); for ($y = 0; $y < 16; ++$y) { for ($x = 0; $x < 16; ++$x) { $rgb = imagecolorat($favicon, $x, $y); $rs[$y][$x] = $rgb >> 0x10; $gs[$y][$x] = $rgb >> 0x08 & 0xFF; $bs[$y][$x] = $rgb & 0xFF; } } for ($y = 1; $y < 15; ++$y) { $rd = $rs[$y][0]; $gd = $gs[$y][0]; $bd = $bs[$y][0]; $yd = $y - 1; $yi = $y + 1; for ($x = 1; $x < 15; ++$x) { $r = -($rs[$yd][$x] + $rs[$yi][$x] + $rd + $rs[$y][$x + 1]) / 4; $g = -($gs[$yd][$x] + $gs[$yi][$x] + $gd + $gs[$y][$x + 1]) / 4; $b = -($bs[$yd][$x] + $bs[$yi][$x] + $bd + $bs[$y][$x + 1]) / 4; $r += 2 * $rd = $rs[$y][$x]; $g += 2 * $gd = $gs[$y][$x]; $b += 2 * $bd = $bs[$y][$x]; if ($r < 0) $r = 0; elseif ($r > 255) $r = 255; if ($g < 0) $g = 0; elseif ($g > 255) $g = 255; if ($b < 0) $b = 0; elseif ($b > 255) $b = 255; imagesetpixel($favicon, $x, $y, $r << 0x10 | $g << 0x08 | $b); } } }
Precise sharpen any image
<?php function imagesharpen_precise($image) { $height = imagesy($image); $width = imagesx($image); $rs = array(); $gs = array(); $bs = array(); for ($y = 0; $y < $height; ++$y) { for ($x = 0; $x < $width; ++$x) { $rgb = imagecolorat($image, $x, $y); $rs[$y][$x] = $rgb >> 0x10; $gs[$y][$x] = $rgb >> 0x08 & 0xFF; $bs[$y][$x] = $rgb & 0xFF; } } $height--; $width--; for ($y = 1; $y < $height; ++$y) { $rd = $rs[$y][0]; $gd = $gs[$y][0]; $bd = $bs[$y][0]; $yd = $y - 1; $yi = $y + 1; for ($x = 1; $x < $width; ++$x) { $r = -($rs[$yd][$x] + $rs[$yi][$x] + $rd + $rs[$y][$x + 1]) / 4; $g = -($gs[$yd][$x] + $gs[$yi][$x] + $gd + $gs[$y][$x + 1]) / 4; $b = -($bs[$yd][$x] + $bs[$yi][$x] + $bd + $bs[$y][$x + 1]) / 4; $r += 2 * $rd = $rs[$y][$x]; $g += 2 * $gd = $gs[$y][$x]; $b += 2 * $bd = $bs[$y][$x]; if ($r < 0) $r = 0; elseif ($r > 255) $r = 255; if ($g < 0) $g = 0; elseif ($g > 255) $g = 255; if ($b < 0) $b = 0; elseif ($b > 255) $b = 255; imagesetpixel($image, $x, $y, $r << 0x10 | $g << 0x08 | $b); } } }