1 | <?php |
---|
2 | ////////////////////////////////////////////////////////////// |
---|
3 | //// |
---|
4 | //// Unsharp Mask for PHP - version 2.1.1 |
---|
5 | //// |
---|
6 | //// Unsharp mask algorithm by Torstein Hønsi 2003-07. |
---|
7 | //// thoensi_at_netcom_dot_no. |
---|
8 | //// Please leave this notice. |
---|
9 | //// |
---|
10 | ////////////////////////////////////////////////////////////// |
---|
11 | /// From: http://vikjavev.no/computing/ump.php // |
---|
12 | // // |
---|
13 | // Reformatted by James Heinrich <info@silisoftware.com> // |
---|
14 | // for use in phpThumb() on 3 February 2003. // |
---|
15 | // updated to v2.1.1 on 24 April 2011 // |
---|
16 | // // |
---|
17 | // phpThumb() is found at http://phpthumb.sourceforge.net /// |
---|
18 | ////////////////////////////////////////////////////////////// |
---|
19 | |
---|
20 | /* |
---|
21 | New: |
---|
22 | - In version 2.1 (February 26 2007) Tom Bishop has done some important speed enhancements. |
---|
23 | - From version 2 (July 17 2006) the script uses the imageconvolution function in PHP |
---|
24 | version >= 5.1, which improves the performance considerably. |
---|
25 | |
---|
26 | Unsharp masking is a traditional darkroom technique that has proven very suitable for |
---|
27 | digital imaging. The principle of unsharp masking is to create a blurred copy of the image |
---|
28 | and compare it to the underlying original. The difference in colour values |
---|
29 | between the two images is greatest for the pixels near sharp edges. When this |
---|
30 | difference is subtracted from the original image, the edges will be |
---|
31 | accentuated. |
---|
32 | |
---|
33 | The Amount parameter simply says how much of the effect you want. 100 is 'normal'. |
---|
34 | Radius is the radius of the blurring circle of the mask. 'Threshold' is the least |
---|
35 | difference in colour values that is allowed between the original and the mask. In practice |
---|
36 | this means that low-contrast areas of the picture are left unrendered whereas edges |
---|
37 | are treated normally. This is good for pictures of e.g. skin or blue skies. |
---|
38 | |
---|
39 | Any suggenstions for improvement of the algorithm, expecially regarding the speed |
---|
40 | and the roundoff errors in the Gaussian blur process, are welcome. |
---|
41 | */ |
---|
42 | |
---|
43 | class phpUnsharpMask { |
---|
44 | |
---|
45 | function applyUnsharpMask(&$img, $amount, $radius, $threshold) { |
---|
46 | |
---|
47 | // $img is an image that is already created within php using |
---|
48 | // imgcreatetruecolor. No url! $img must be a truecolor image. |
---|
49 | |
---|
50 | // Attempt to calibrate the parameters to Photoshop: |
---|
51 | $amount = min($amount, 500) * 0.016; |
---|
52 | $radius = abs(round(min(50, $radius) * 2)); // Only integers make sense. |
---|
53 | $threshold = min(255, $threshold); |
---|
54 | if ($radius == 0) { |
---|
55 | return true; |
---|
56 | } |
---|
57 | $w = ImageSX($img); |
---|
58 | $h = ImageSY($img); |
---|
59 | $imgCanvas = ImageCreateTrueColor($w, $h); |
---|
60 | $imgBlur = ImageCreateTrueColor($w, $h); |
---|
61 | |
---|
62 | // Gaussian blur matrix: |
---|
63 | // |
---|
64 | // 1 2 1 |
---|
65 | // 2 4 2 |
---|
66 | // 1 2 1 |
---|
67 | // |
---|
68 | ////////////////////////////////////////////////// |
---|
69 | |
---|
70 | if (function_exists('imageconvolution')) { // PHP >= 5.1 |
---|
71 | $matrix = array( |
---|
72 | array(1, 2, 1), |
---|
73 | array(2, 4, 2), |
---|
74 | array(1, 2, 1) |
---|
75 | ); |
---|
76 | ImageCopy($imgBlur, $img, 0, 0, 0, 0, $w, $h); |
---|
77 | ImageConvolution($imgBlur, $matrix, 16, 0); |
---|
78 | |
---|
79 | } else { |
---|
80 | |
---|
81 | // Move copies of the image around one pixel at the time and merge them with weight |
---|
82 | // according to the matrix. The same matrix is simply repeated for higher radii. |
---|
83 | for ($i = 0; $i < $radius; $i++) { |
---|
84 | ImageCopy( $imgBlur, $img, 0, 0, 1, 0, $w - 1, $h); // left |
---|
85 | ImageCopyMerge($imgBlur, $img, 1, 0, 0, 0, $w , $h, 50); // right |
---|
86 | ImageCopyMerge($imgBlur, $img, 0, 0, 0, 0, $w , $h, 50); // center |
---|
87 | ImageCopy( $imgCanvas, $imgBlur, 0, 0, 0, 0, $w , $h); |
---|
88 | ImageCopyMerge($imgBlur, $imgCanvas, 0, 0, 0, 1, $w , $h - 1, 33.33333); // up |
---|
89 | ImageCopyMerge($imgBlur, $imgCanvas, 0, 1, 0, 0, $w , $h, 25); // down |
---|
90 | } |
---|
91 | } |
---|
92 | |
---|
93 | if ($threshold > 0){ |
---|
94 | // Calculate the difference between the blurred pixels and the original |
---|
95 | // and set the pixels |
---|
96 | for ($x = 0; $x < $w-1; $x++) { // each row |
---|
97 | for ($y = 0; $y < $h; $y++) { // each pixel |
---|
98 | |
---|
99 | $rgbOrig = ImageColorAt($img, $x, $y); |
---|
100 | $rOrig = (($rgbOrig >> 16) & 0xFF); |
---|
101 | $gOrig = (($rgbOrig >> 8) & 0xFF); |
---|
102 | $bOrig = ($rgbOrig & 0xFF); |
---|
103 | |
---|
104 | $rgbBlur = ImageColorAt($imgBlur, $x, $y); |
---|
105 | |
---|
106 | $rBlur = (($rgbBlur >> 16) & 0xFF); |
---|
107 | $gBlur = (($rgbBlur >> 8) & 0xFF); |
---|
108 | $bBlur = ($rgbBlur & 0xFF); |
---|
109 | |
---|
110 | // When the masked pixels differ less from the original |
---|
111 | // than the threshold specifies, they are set to their original value. |
---|
112 | $rNew = ((abs($rOrig - $rBlur) >= $threshold) ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig)) : $rOrig); |
---|
113 | $gNew = ((abs($gOrig - $gBlur) >= $threshold) ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig)) : $gOrig); |
---|
114 | $bNew = ((abs($bOrig - $bBlur) >= $threshold) ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig)) : $bOrig); |
---|
115 | |
---|
116 | if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) { |
---|
117 | $pixCol = ImageColorAllocate($img, $rNew, $gNew, $bNew); |
---|
118 | ImageSetPixel($img, $x, $y, $pixCol); |
---|
119 | } |
---|
120 | } |
---|
121 | } |
---|
122 | } else { |
---|
123 | for ($x = 0; $x < $w; $x++) { // each row |
---|
124 | for ($y = 0; $y < $h; $y++) { // each pixel |
---|
125 | $rgbOrig = ImageColorAt($img, $x, $y); |
---|
126 | $rOrig = (($rgbOrig >> 16) & 0xFF); |
---|
127 | $gOrig = (($rgbOrig >> 8) & 0xFF); |
---|
128 | $bOrig = ($rgbOrig & 0xFF); |
---|
129 | |
---|
130 | $rgbBlur = ImageColorAt($imgBlur, $x, $y); |
---|
131 | |
---|
132 | $rBlur = (($rgbBlur >> 16) & 0xFF); |
---|
133 | $gBlur = (($rgbBlur >> 8) & 0xFF); |
---|
134 | $bBlur = ($rgbBlur & 0xFF); |
---|
135 | |
---|
136 | $rNew = min(255, max(0, ($amount * ($rOrig - $rBlur)) + $rOrig)); |
---|
137 | $gNew = min(255, max(0, ($amount * ($gOrig - $gBlur)) + $gOrig)); |
---|
138 | $bNew = min(255, max(0, ($amount * ($bOrig - $bBlur)) + $bOrig)); |
---|
139 | $rgbNew = ($rNew << 16) + ($gNew <<8) + $bNew; |
---|
140 | ImageSetPixel($img, $x, $y, $rgbNew); |
---|
141 | } |
---|
142 | } |
---|
143 | } |
---|
144 | ImageDestroy($imgCanvas); |
---|
145 | ImageDestroy($imgBlur); |
---|
146 | return true; |
---|
147 | } |
---|
148 | } |
---|
149 | ?> |
---|