1 <?php
2 /**
3 * @author Gasper Kozak
4 * @copyright 2007-2011
5
6 This file is part of WideImage.
7
8 WideImage is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 WideImage is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with WideImage; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
22 * @package Internal/Operations
23 **/
24
25 /**
26 * Unsharp filter
27 *
28 * This filter was taken from http://vikjavev.no/computing/ump.php,
29 * the original author Torstein Hønsi. Adapted to fit better within
30 * the Wideimage package.
31 *
32 * @package Internal/Operations
33 */
34 class WideImage_Operation_Unsharp {
35 /**
36 * Returns sharpened image
37 *
38 * @param WideImage_Image $image
39 * @param float $amount
40 * @param int $radius
41 * @param float $threshold
42 * @return WideImage_Image
43 */
44 function execute($image, $amount, $radius, $threshold) {
45
46 // Attempt to calibrate the parameters to Photoshop:
47 if ($amount > 500) $amount = 500;
48 $amount = $amount * 0.016;
49 if ($radius > 50) $radius = 50;
50 $radius = $radius * 2;
51 if ($threshold > 255) $threshold = 255;
52
53 $radius = abs(round($radius)); // Only integers make sense.
54 if ($radius == 0) {
55 return $image;
56 }
57
58 // Gaussian blur matrix
59
60 $matrix = array(
61 array(1, 2, 1),
62 array(2, 4, 2),
63 array(1, 2, 1)
64 );
65
66 $blurred = $image->applyConvolution($matrix, 16, 0);
67
68 if($threshold > 0) {
69 // Calculate the difference between the blurred pixels and the original
70 // and set the pixels
71 for ($x = 0; $x < $image->getWidth(); $x++) {
72 for ($y = 0; $y < $image->getHeight(); $y++) {
73 $rgbOrig = $image->getRGBAt($x, $y);
74 $rOrig = $rgbOrig["red"];
75 $gOrig = $rgbOrig["green"];
76 $bOrig = $rgbOrig["blue"];
77
78 $rgbBlur = $blurred->getRGBAt($x, $y);
79 $rBlur = $rgbBlur["red"];
80 $gBlur = $rgbBlur["green"];
81 $bBlur = $rgbBlur["blue"];
82
83 // When the masked pixels differ less from the original
84 // than the threshold specifies, they are set to their original value.
85 $rNew = (abs($rOrig - $rBlur) >= $threshold)
86 ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig))
87 : $rOrig;
88 $gNew = (abs($gOrig - $gBlur) >= $threshold)
89 ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig))
90 : $gOrig;
91 $bNew = (abs($bOrig - $bBlur) >= $threshold)
92 ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig))
93 : $bOrig;
94 $rgbNew = array("red" => $rNew, "green" => $gNew, "blue" => $bNew, "alpha" => 0);
95
96 if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) {
97 $image->setRGBAt($x, $y, $rgbNew);
98 }
99 }
100 }
101 }
102 else {
103 $w = $image->getWidth();
104 $h = $image->getHeight();
105 for ($x = 0; $x < $w; $x++) {
106 for ($y = 0; $y < $h; $y++) {
107 $rgbOrig = $image->getRGBAt($x, $y);
108 $rOrig = $rgbOrig["red"];
109 $gOrig = $rgbOrig["green"];
110 $bOrig = $rgbOrig["blue"];
111
112 $rgbBlur = $blurred->getRGBAt($x, $y);
113 $rBlur = $rgbBlur["red"];
114 $gBlur = $rgbBlur["green"];
115 $bBlur = $rgbBlur["blue"];
116
117 $rNew = ($amount * ($rOrig - $rBlur)) + $rOrig;
118 if($rNew>255){$rNew=255;}
119 elseif($rNew<0){$rNew=0;}
120 $gNew = ($amount * ($gOrig - $gBlur)) + $gOrig;
121 if($gNew>255){$gNew=255;}
122 elseif($gNew<0){$gNew=0;}
123 $bNew = ($amount * ($bOrig - $bBlur)) + $bOrig;
124 if($bNew>255){$bNew=255;}
125 elseif($bNew<0){$bNew=0;}
126 $rgbNew = array("red" => $rNew, "green" => $gNew, "blue" => $bNew, "alpha" => 0);
127
128 $image->setRGBAt($x, $y, $rgbNew);
129 }
130 }
131 }
132
133 return $image;
134 }
135 }
136