root/afridex/plugins/Flutter/phpthumb.unsharp.php

Revision 21, 6.9 kB (checked in by admin, 18 years ago)
Line 
1<?php
2//////////////////////////////////////////////////////////////
3////                                                      ////
4////              p h p U n s h a r p M a s k             ////
5////                                                      ////
6////    Unsharp mask algorithm by Torstein Hønsi 2003.    ////
7////               thoensi_at_netcom_dot_no               ////
8////               Please leave this notice.              ////
9////                                                      ////
10//////////////////////////////////////////////////////////////
11/// From: http://vikjavev.no/hovudsida/umtestside.php       //
12//                                                          //
13//  Reformatted by James Heinrich <info@silisoftware.com>   //
14//  for use in phpThumb() on 3 February 2003.               //
15//                                                          //
16//  phpThumb() is found at http://phpthumb.sourceforge.net ///
17//////////////////////////////////////////////////////////////
18
19/*
20WARNING! Due to a known bug in PHP 4.3.2 this script is not working well in this version.
21The sharpened images get too dark. The bug is fixed in version 4.3.3.
22
23Unsharp masking is a traditional darkroom technique that has proven very suitable for
24digital imaging. The principle of unsharp masking is to create a blurred copy of the image
25and compare it to the underlying original. The difference in colour values
26between the two images is greatest for the pixels near sharp edges. When this
27difference is subtracted from the original image, the edges will be
28accentuated.
29
30The Amount parameter simply says how much of the effect you want. 100 is 'normal'.
31Radius is the radius of the blurring circle of the mask. 'Threshold' is the least
32difference in colour values that is allowed between the original and the mask. In practice
33this means that low-contrast areas of the picture are left unrendered whereas edges
34are treated normally. This is good for pictures of e.g. skin or blue skies.
35
36Any suggenstions for improvement of the algorithm, expecially regarding the speed
37and the roundoff errors in the Gaussian blur process, are welcome.
38*/
39
40class phpUnsharpMask {
41
42        function applyUnsharpMask(&$img, $amount, $radius, $threshold) {
43
44                // $img is an image that is already created within php using
45                // imgcreatetruecolor. No url! $img must be a truecolor image.
46
47                // Attempt to calibrate the parameters to Photoshop:
48                $amount = min($amount, 500);
49                $amount = $amount * 0.016;
50                if ($amount == 0) {
51                        return true;
52                }
53
54                $radius = min($radius, 50);
55                $radius = $radius * 2;
56
57                $threshold = min($threshold, 255);
58
59                $radius = abs(round($radius));  // Only integers make sense.
60                if ($radius == 0) {
61                        return true;
62                }
63
64                $w = ImageSX($img);
65                $h = ImageSY($img);
66                $imgCanvas  = ImageCreateTrueColor($w, $h);
67                $imgCanvas2 = ImageCreateTrueColor($w, $h);
68                ImageCopy($imgCanvas,  $img, 0, 0, 0, 0, $w, $h);
69                ImageCopy($imgCanvas2, $img, 0, 0, 0, 0, $w, $h);
70
71
72                $builtinFilterSucceeded = false;
73                if ($radius == 1) {
74                        if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
75                                if (ImageFilter($imgCanvas, IMG_FILTER_GAUSSIAN_BLUR) && ImageFilter($imgCanvas2, IMG_FILTER_GAUSSIAN_BLUR)) {
76                                        $builtinFilterSucceeded = true;
77                                }
78                        }
79                }
80
81                if (!$builtinFilterSucceeded) {
82                        $imgBlur  = ImageCreateTrueColor($w, $h);
83                        $imgBlur2 = ImageCreateTrueColor($w, $h);
84
85                        ///////////////////////////
86                        //
87                        // Gaussian blur matrix:
88                        //      1  2  1
89                        //      2  4  2
90                        //      1  2  1
91                        //
92                        ///////////////////////////
93
94                        // Move copies of the image around one pixel at the time and merge them with weight
95                        // according to the matrix. The same matrix is simply repeated for higher radii.
96                        for ($i = 0; $i < $radius; $i++)        {
97                                ImageCopy     ($imgBlur, $imgCanvas, 0, 0, 1, 1, $w - 1, $h - 1);            // up left
98                                ImageCopyMerge($imgBlur, $imgCanvas, 1, 1, 0, 0, $w,     $h,     50);        // down right
99                                ImageCopyMerge($imgBlur, $imgCanvas, 0, 1, 1, 0, $w - 1, $h,     33.33333);  // down left
100                                ImageCopyMerge($imgBlur, $imgCanvas, 1, 0, 0, 1, $w,     $h - 1, 25);        // up right
101                                ImageCopyMerge($imgBlur, $imgCanvas, 0, 0, 1, 0, $w - 1, $h,     33.33333);  // left
102                                ImageCopyMerge($imgBlur, $imgCanvas, 1, 0, 0, 0, $w,     $h,     25);        // right
103                                ImageCopyMerge($imgBlur, $imgCanvas, 0, 0, 0, 1, $w,     $h - 1, 20 );       // up
104                                ImageCopyMerge($imgBlur, $imgCanvas, 0, 1, 0, 0, $w,     $h,     16.666667); // down
105                                ImageCopyMerge($imgBlur, $imgCanvas, 0, 0, 0, 0, $w,     $h,     50);        // center
106                                ImageCopy     ($imgCanvas, $imgBlur, 0, 0, 0, 0, $w,     $h);
107
108                                // During the loop above the blurred copy darkens, possibly due to a roundoff
109                                // error. Therefore the sharp picture has to go through the same loop to
110                                // produce a similar image for comparison. This is not a good thing, as processing
111                                // time increases heavily.
112                                ImageCopy     ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h);
113                                ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 50);
114                                ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 33.33333);
115                                ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 25);
116                                ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 33.33333);
117                                ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 25);
118                                ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 20 );
119                                ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 16.666667);
120                                ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 50);
121                                ImageCopy     ($imgCanvas2, $imgBlur2, 0, 0, 0, 0, $w, $h);
122                        }
123                        ImageDestroy($imgBlur);
124                        ImageDestroy($imgBlur2);
125                }
126
127                // Calculate the difference between the blurred pixels and the original
128                // and set the pixels
129                for ($x = 0; $x < $w; $x++)     { // each row
130                        for ($y = 0; $y < $h; $y++)     { // each pixel
131
132                                $rgbOrig = ImageColorAt($imgCanvas2, $x, $y);
133                                $rOrig = (($rgbOrig >> 16) & 0xFF);
134                                $gOrig = (($rgbOrig >>  8) & 0xFF);
135                                $bOrig =  ($rgbOrig        & 0xFF);
136
137                                $rgbBlur = ImageColorAt($imgCanvas, $x, $y);
138                                $rBlur = (($rgbBlur >> 16) & 0xFF);
139                                $gBlur = (($rgbBlur >>  8) & 0xFF);
140                                $bBlur =  ($rgbBlur        & 0xFF);
141
142                                // When the masked pixels differ less from the original
143                                // than the threshold specifies, they are set to their original value.
144                                $rNew = (abs($rOrig - $rBlur) >= $threshold) ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig)) : $rOrig;
145                                $gNew = (abs($gOrig - $gBlur) >= $threshold) ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig)) : $gOrig;
146                                $bNew = (abs($bOrig - $bBlur) >= $threshold) ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig)) : $bOrig;
147
148                                if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) {
149                                        $pixCol = ImageColorAllocate($img, $rNew, $gNew, $bNew);
150                                        ImageSetPixel($img, $x, $y, $pixCol);
151                                }
152                        }
153                }
154                ImageDestroy($imgCanvas);
155                ImageDestroy($imgCanvas2);
156
157                return true;
158        }
159
160}
161
162?>
Note: See TracBrowser for help on using the browser.