[ Index ]

PHP Cross Reference of phpwcms V1.4.3 _r380 (23.11.09)

title

Body

[close]

/include/inc_ext/ss_image/ -> ss_image.unsharp.php (source)

   1  <?php
   2  
   3  /* 
   4  
   5  WARNING! Due to a known bug in PHP 4.3.2 this script is not working well in this version. The sharpened images get too dark. The bug is fixed in version 4.3.3.
   6  
   7  
   8  Unsharp masking is a traditional darkroom technique that has proven very suitable for 
   9  digital imaging. The principle of unsharp masking is to create a blurred copy of the image
  10  and compare it to the underlying original. The difference in colour values
  11  between the two images is greatest for the pixels near sharp edges. When this 
  12  difference is subtracted from the original image, the edges will be
  13  accentuated. 
  14  
  15  The Amount parameter simply says how much of the effect you want. 100 is 'normal'.
  16  Radius is the radius of the blurring circle of the mask. 'Threshold' is the least
  17  difference in colour values that is allowed between the original and the mask. In practice
  18  this means that low-contrast areas of the picture are left unrendered whereas edges
  19  are treated normally. This is good for pictures of e.g. skin or blue skies.
  20  
  21  Any suggenstions for improvement of the algorithm, expecially regarding the speed
  22  and the roundoff errors in the Gaussian blur process, are welcome.
  23  
  24  f.e. amount = 100, radius = 1, treshold = 3
  25  
  26  */
  27  
  28  function UnsharpMask($img, $amount, $radius, $threshold)    {
  29  ////////////////////////////////////////////////////////////////////////////////////////////////
  30  ////
  31  ////                  p h p U n s h a r p M a s k
  32  ////
  33  ////    Unsharp mask algorithm by Torstein Hønsi 2003.
  34  ////             thoensi_at_netcom_dot_no.
  35  ////               Please leave this notice.
  36  ////
  37  ///////////////////////////////////////////////////////////////////////////////////////////////
  38  
  39  ///////////////////////////////////////////////////////////////////////////////////////////////
  40  ////    The original script was changed a little bit by Yuriy Horobey
  41  ////    to be included into ImageProcessor script.
  42  ////    keep in mind that this script is freeware and you were not charged for it.
  43  ////    I have included it into the package just for your convenience
  44  ////    all credit goes to the author as it is noticed above.
  45  ///////////////////////////////////////////////////////////////////////////////////////////////
  46  
  47  
  48  
  49      // Attempt to calibrate the parameters to Photoshop:
  50      if ($amount > 500)    $amount = 500;
  51      $amount = $amount * 0.016;
  52      if ($radius > 50)    $radius = 50;
  53      $radius = $radius * 2;
  54      if ($threshold > 255)    $threshold = 255;
  55      
  56      $w = imagesx($img); $h = imagesy($img);
  57      $img_result = imagecreatetruecolor($w, $h);
  58      imagecopy ($img_result, $img, 0, 0, 0, 0, $w, $h);
  59  
  60      $radius = abs(round($radius));     // Only integers make sense.
  61      if ($radius == 0) {
  62          return $img_result;
  63      }
  64      $imgCanvas = imagecreatetruecolor($w, $h);
  65      $imgCanvas2 = imagecreatetruecolor($w, $h);
  66      $imgBlur = imagecreatetruecolor($w, $h);
  67      $imgBlur2 = 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  
  73      // Gaussian blur matrix:
  74      //                        
  75      //    1    2    1        
  76      //    2    4    2        
  77      //    1    2    1        
  78      //                        
  79      //////////////////////////////////////////////////
  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, $imgCanvas, 0, 0, 1, 1, $w - 1, $h - 1); // up left
  85          imagecopymerge ($imgBlur, $imgCanvas, 1, 1, 0, 0, $w, $h, 50); // down right
  86          imagecopymerge ($imgBlur, $imgCanvas, 0, 1, 1, 0, $w - 1, $h, 33.33333); // down left
  87          imagecopymerge ($imgBlur, $imgCanvas, 1, 0, 0, 1, $w, $h - 1, 25); // up right
  88          imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 1, 0, $w - 1, $h, 33.33333); // left
  89          imagecopymerge ($imgBlur, $imgCanvas, 1, 0, 0, 0, $w, $h, 25); // right
  90          imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 0, 1, $w, $h - 1, 20 ); // up
  91          imagecopymerge ($imgBlur, $imgCanvas, 0, 1, 0, 0, $w, $h, 16.666667); // down
  92          imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 0, 0, $w, $h, 50); // center
  93          imagecopy ($imgCanvas, $imgBlur, 0, 0, 0, 0, $w, $h);
  94  
  95          // During the loop above the blurred copy darkens, possibly due to a roundoff
  96          // error. Therefore the sharp picture has to go through the same loop to 
  97          // produce a similar image for comparison. This is not a good thing, as processing
  98          // time increases heavily.
  99          imagecopy ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h);
 100          imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 50);
 101          imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 33.33333);
 102          imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 25);
 103          imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 33.33333);
 104          imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 25);
 105          imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 20 );
 106          imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 16.666667);
 107          imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 50);
 108          imagecopy ($imgCanvas2, $imgBlur2, 0, 0, 0, 0, $w, $h);
 109          
 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              
 124              $rBlur = (($rgbBlur >> 16) & 0xFF);
 125              $gBlur = (($rgbBlur >> 8) & 0xFF);
 126              $bBlur = ($rgbBlur & 0xFF);
 127              
 128              // When the masked pixels differ less from the original
 129              // than the threshold specifies, they are set to their original value.
 130              $rNew = (abs($rOrig - $rBlur) >= $threshold) 
 131                  ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig)) 
 132                  : $rOrig;
 133              $gNew = (abs($gOrig - $gBlur) >= $threshold) 
 134                  ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig)) 
 135                  : $gOrig;
 136              $bNew = (abs($bOrig - $bBlur) >= $threshold) 
 137                  ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig)) 
 138                  : $bOrig;
 139              
 140              
 141                          
 142              if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) {
 143                      $pixCol = ImageColorAllocate($img_result, $rNew, $gNew, $bNew);
 144                      ImageSetPixel($img_result, $x, $y, $pixCol);
 145                  }
 146  }
 147          }
 148  
 149      imagedestroy($imgCanvas);
 150      imagedestroy($imgCanvas2);
 151      imagedestroy($imgBlur);
 152      imagedestroy($imgBlur2);
 153      
 154      return $img_result;
 155  
 156      }
 157  
 158  ?>


Generated: Wed Dec 30 05:55:15 2009 Cross-referenced by PHPXref 0.7