OSDN Git Service

original file
[nucleus-jp/nucleus-plugins.git] / trunk / NP_TinyMCE2j / tinymce2j / plugins / ibrowser / scripts / phpThumb / phpthumb.unsharp.php
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 /*
20 WARNING! Due to a known bug in PHP 4.3.2 this script is not working well in this version.
21 The sharpened images get too dark. The bug is fixed in version 4.3.3.
22
23 Unsharp masking is a traditional darkroom technique that has proven very suitable for
24 digital imaging. The principle of unsharp masking is to create a blurred copy of the image
25 and compare it to the underlying original. The difference in colour values
26 between the two images is greatest for the pixels near sharp edges. When this
27 difference is subtracted from the original image, the edges will be
28 accentuated.
29
30 The Amount parameter simply says how much of the effect you want. 100 is 'normal'.
31 Radius is the radius of the blurring circle of the mask. 'Threshold' is the least
32 difference in colour values that is allowed between the original and the mask. In practice
33 this means that low-contrast areas of the picture are left unrendered whereas edges
34 are treated normally. This is good for pictures of e.g. skin or blue skies.
35
36 Any suggenstions for improvement of the algorithm, expecially regarding the speed
37 and the roundoff errors in the Gaussian blur process, are welcome.
38 */
39
40 class 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                 $imgBlur    = ImageCreateTrueColor($w, $h);
69                 $imgBlur2   = ImageCreateTrueColor($w, $h);
70                 ImageCopy($imgCanvas,  $img, 0, 0, 0, 0, $w, $h);
71                 ImageCopy($imgCanvas2, $img, 0, 0, 0, 0, $w, $h);
72
73
74                 // Gaussian blur matrix:
75                 //
76                 //      1       2       1
77                 //      2       4       2
78                 //      1       2       1
79                 //
80                 //////////////////////////////////////////////////
81
82                 // Move copies of the image around one pixel at the time and merge them with weight
83                 // according to the matrix. The same matrix is simply repeated for higher radii.
84                 for ($i = 0; $i < $radius; $i++)        {
85                         ImageCopy     ($imgBlur, $imgCanvas, 0, 0, 1, 1, $w - 1, $h - 1);            // up left
86                         ImageCopyMerge($imgBlur, $imgCanvas, 1, 1, 0, 0, $w,     $h,     50);        // down right
87                         ImageCopyMerge($imgBlur, $imgCanvas, 0, 1, 1, 0, $w - 1, $h,     33.33333);  // down left
88                         ImageCopyMerge($imgBlur, $imgCanvas, 1, 0, 0, 1, $w,     $h - 1, 25);        // up right
89                         ImageCopyMerge($imgBlur, $imgCanvas, 0, 0, 1, 0, $w - 1, $h,     33.33333);  // left
90                         ImageCopyMerge($imgBlur, $imgCanvas, 1, 0, 0, 0, $w,     $h,     25);        // right
91                         ImageCopyMerge($imgBlur, $imgCanvas, 0, 0, 0, 1, $w,     $h - 1, 20 );       // up
92                         ImageCopyMerge($imgBlur, $imgCanvas, 0, 1, 0, 0, $w,     $h,     16.666667); // down
93                         ImageCopyMerge($imgBlur, $imgCanvas, 0, 0, 0, 0, $w,     $h,     50);        // center
94                         ImageCopy     ($imgCanvas, $imgBlur, 0, 0, 0, 0, $w,     $h);
95
96                         // During the loop above the blurred copy darkens, possibly due to a roundoff
97                         // error. Therefore the sharp picture has to go through the same loop to
98                         // produce a similar image for comparison. This is not a good thing, as processing
99                         // time increases heavily.
100                         ImageCopy     ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h);
101                         ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 50);
102                         ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 33.33333);
103                         ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 25);
104                         ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 33.33333);
105                         ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 25);
106                         ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 20 );
107                         ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 16.666667);
108                         ImageCopyMerge($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 50);
109                         ImageCopy     ($imgCanvas2, $imgBlur2, 0, 0, 0, 0, $w, $h);
110                 }
111
112                 // Calculate the difference between the blurred pixels and the original
113                 // and set the pixels
114                 for ($x = 0; $x < $w; $x++)     { // each row
115                         for ($y = 0; $y < $h; $y++)     { // each pixel
116
117                                 $rgbOrig = ImageColorAt($imgCanvas2, $x, $y);
118                                 $rOrig = (($rgbOrig >> 16) & 0xFF);
119                                 $gOrig = (($rgbOrig >>  8) & 0xFF);
120                                 $bOrig =  ($rgbOrig        & 0xFF);
121
122                                 $rgbBlur = ImageColorAt($imgCanvas, $x, $y);
123                                 $rBlur = (($rgbBlur >> 16) & 0xFF);
124                                 $gBlur = (($rgbBlur >>  8) & 0xFF);
125                                 $bBlur =  ($rgbBlur        & 0xFF);
126
127                                 // When the masked pixels differ less from the original
128                                 // than the threshold specifies, they are set to their original value.
129                                 $rNew = (abs($rOrig - $rBlur) >= $threshold) ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig)) : $rOrig;
130                                 $gNew = (abs($gOrig - $gBlur) >= $threshold) ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig)) : $gOrig;
131                                 $bNew = (abs($bOrig - $bBlur) >= $threshold) ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig)) : $bOrig;
132
133                                 if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) {
134                                         $pixCol = ImageColorAllocate($img, $rNew, $gNew, $bNew);
135                                         ImageSetPixel($img, $x, $y, $pixCol);
136                                 }
137                         }
138                 }
139                 ImageDestroy($imgCanvas);
140                 ImageDestroy($imgCanvas2);
141                 ImageDestroy($imgBlur);
142                 ImageDestroy($imgBlur2);
143
144                 return true;
145         }
146
147 }
148
149 ?>