Textpattern PHP Cross Reference Content Management Systems

Source: /textpattern/lib/class.thumb.php - 684 lines - 21911 bytes - Summary - Text - Print

Description: Tools for creating thumbnails.

   1  <?php
   2  
   3  /**
   4   * Tools for creating thumbnails.
   5   *
   6   * @package Image
   7   * @author  C. Erdmann
   8   * @link    http://www.cerdmann.de/thumb
   9   * @author  Robert Wetzlmayr
  10   *
  11   * Refactored from function.thumb.php by C. Erdmann, which contained
  12   * the following credit and licensing terms:
  13   *
  14   * Smarty plugin "Thumb"
  15   * Purpose: creates cached thumbnails
  16   * Home: http://www.cerdmann.com/thumb/
  17   * Copyright (C) 2005 Christoph Erdmann
  18   *
  19   * This library is free software; you can redistribute it and/or
  20   * modify it under the terms of the GNU Lesser General Public License
  21   * as published by the Free Software Foundation; either version 2.1 of
  22   * the License, or (at your option) any later version.
  23   *
  24   * This library is distributed in the hope that it will be useful, but WITHOUT
  25   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  26   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  27   * details.
  28   *
  29   * You should have received a copy of the GNU Lesser General Public License
  30   * along with this library; if not, write to the Free Software Foundation,
  31   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
  32   *
  33   * @author Christoph Erdmann (CE) <smarty@cerdmann.com>
  34   * @link   http://www.cerdmann.com
  35   *
  36   * @author Benjamin Fleckenstein (BF)
  37   * @link http://www.benjaminfleckenstein.de
  38   *
  39   * @author Marcus Gueldenmeister (MG)
  40   * @link http://www.gueldenmeister.de/marcus/
  41   *
  42   * @author Andreas Bösch (AB)
  43   */
  44  
  45  /**
  46   * Output debug log.
  47   *
  48   * @global bool $verbose
  49   */
  50  
  51  $verbose = false;
  52  
  53  /**
  54   * Creates thumbnails for larger images.
  55   *
  56   * @package Image
  57   */
  58  
  59  class wet_thumb
  60  {
  61      /**
  62       * The width of your thumbnail. The height (if not set) will be
  63       * automatically calculated.
  64       *
  65       * @var int
  66       */
  67  
  68      public $width;
  69  
  70      /**
  71       * The height of your thumbnail. The width (if not set) will be
  72       * automatically calculated.
  73       *
  74       * @var int
  75       */
  76  
  77      public $height;
  78  
  79      /**
  80       * Set the longest side of the image if width, height and shortside is
  81       * not set.
  82       */
  83  
  84      public $longside;
  85  
  86      /**
  87       * Set the shortest side of the image if width, height and longside is
  88       * not set.
  89       */
  90  
  91      public $shortside;
  92  
  93      /**
  94       * Set to 'false' if your source image is smaller than the calculated
  95       * thumb and you do not want the image to get extrapolated.
  96       */
  97  
  98      public $extrapolate;
  99  
 100      /**
 101       * Crops the image.
 102       *
 103       * If set to TRUE, image will be cropped in the center to destination width
 104       * and height params, while keeping aspect ratio. Otherwise the image will
 105       * get resized.
 106       *
 107       * @var bool
 108       */
 109  
 110      public $crop;
 111  
 112      /**
 113       * Applies unsharpen mask.
 114       *
 115       * Set to FALSE if you don't want to use the Unsharp-Mask.
 116       * Thumbnail creation will be faster, but quality is reduced.
 117       *
 118       * @var bool
 119       */
 120  
 121      public $sharpen;
 122  
 123      /**
 124       * If set to FALSE the image will not have a lens icon.
 125       *
 126       * @var bool
 127       */
 128  
 129      public $hint;
 130  
 131      /**
 132       * Set to FALSE to get no lightgrey bottom bar.
 133       *
 134       * @var bool
 135       */
 136  
 137      public $addgreytohint;
 138  
 139      /**
 140       * JPEG image quality (0...100, defaults to 80).
 141       *
 142       * @var int
 143       */
 144  
 145      public $quality;
 146  
 147      /**
 148       * Set to your target URL (a href="linkurl").
 149       *
 150       * @var string
 151       */
 152  
 153      public $linkurl;
 154  
 155      /**
 156       * Will be inserted in the image-tag.
 157       *
 158       * @var string
 159       */
 160  
 161      public $html;
 162  
 163      /**
 164       * An array of accepted image formats.
 165       *
 166       * @var array
 167       */
 168  
 169      public $types = array('', '.gif', '.jpg', '.png');
 170  
 171      /**
 172       * Source.
 173       *
 174       * @var array
 175       */
 176  
 177      public $_SRC;
 178  
 179      /**
 180       * Destination.
 181       *
 182       * @var array
 183       */
 184  
 185      public $_DST;
 186  
 187      /**
 188       * Constructor.
 189       */
 190  
 191      public function __construct()
 192      {
 193          $this->extrapolate = false;
 194          $this->crop = true;
 195          $this->sharpen = true;
 196          $this->hint = true;
 197          $this->addgreytohint = true;
 198          $this->quality = 80;
 199          $this->html = ' alt="" title="" ';
 200          $this->link = true;
 201      }
 202  
 203      /**
 204       * Writes a thumbnail file.
 205       *
 206       * @param  string $infile  Image file name.
 207       * @param  array  $outfile Array of thumb file names (1...n)
 208       * @return bool TRUE on success
 209       */
 210  
 211      public function write($infile, $outfile)
 212      {
 213          global $verbose;
 214  
 215          if ($verbose) {
 216              echo "writing thumb nail...";
 217          }
 218  
 219          // Get source image info.
 220          $temp = getimagesize($infile);
 221  
 222          $this->_SRC['file']       = $infile;
 223          $this->_SRC['width']      = $temp[0];
 224          $this->_SRC['height']     = $temp[1];
 225          $this->_SRC['type']       = $temp[2]; // 1=GIF, 2=JPEG, 3=PNG.
 226          $this->_SRC['string']     = $temp[3];
 227          $this->_SRC['filename']   = basename($infile);
 228          //$this->_SRC['modified'] = filemtime($infile);
 229  
 230          // Check image orientation.
 231          if ($this->_SRC['width'] >= $this->_SRC['height']) {
 232              $this->_SRC['format'] = 'landscape';
 233          } else {
 234              $this->_SRC['format'] = 'portrait';
 235          }
 236  
 237          // Get destination image info.
 238          if (is_numeric($this->width) and empty($this->height)) {
 239              $this->_DST['width']  = $this->width;
 240              $this->_DST['height'] = round($this->width/($this->_SRC['width']/$this->_SRC['height']));
 241          } elseif (is_numeric($this->height) and empty($this->width)) {
 242              $this->_DST['height'] = $this->height;
 243              $this->_DST['width']  = round($this->height/($this->_SRC['height']/$this->_SRC['width']));
 244          } elseif (is_numeric($this->width) and is_numeric($this->height)) {
 245              $this->_DST['width']  = $this->width;
 246              $this->_DST['height'] = $this->height;
 247          } elseif (is_numeric($this->longside) and empty($this->shortside)) {
 248              // Preserve aspect ratio based on provided height.
 249              if ($this->_SRC['format'] == 'portrait') {
 250                  $this->_DST['height'] = $this->longside;
 251                  $this->_DST['width']  = round($this->longside/($this->_SRC['height']/$this->_SRC['width']));
 252              } else {
 253                  $this->_DST['width']  = $this->longside;
 254                  $this->_DST['height'] = round($this->longside/($this->_SRC['width']/$this->_SRC['height']));
 255              }
 256          } elseif (is_numeric($this->shortside)) {
 257              // Preserve aspect ratio based on provided width.
 258              if ($this->_SRC['format'] == 'portrait') {
 259                  $this->_DST['width']  = $this->shortside;
 260                  $this->_DST['height'] = round($this->shortside/($this->_SRC['width']/$this->_SRC['height']));
 261              } else {
 262                  $this->_DST['height'] = $this->shortside;
 263                  $this->_DST['width']  = round($this->shortside/($this->_SRC['height']/$this->_SRC['width']));
 264              }
 265          } else {
 266              // Default dimensions.
 267              $this->width          = 100;
 268              $this->_DST['width']  = $this->width;
 269              $this->_DST['height'] = round($this->width/($this->_SRC['width']/$this->_SRC['height']));
 270          }
 271  
 272          // Don't make the new image larger than the original image.
 273          if (
 274              $this->extrapolate === false &&
 275              $this->_DST['height'] > $this->_SRC['height'] &&
 276              $this->_DST['width'] > $this->_SRC['width']
 277          ) {
 278              $this->_DST['width'] = $this->_SRC['width'];
 279              $this->_DST['height'] = $this->_SRC['height'];
 280          }
 281  
 282          $this->_DST['type'] = $this->_SRC['type'];
 283          $this->_DST['file'] = $outfile;
 284  
 285          // Make sure we have enough memory if the image is large.
 286          if (max($this->_SRC['width'], $this->_SRC['height']) > 1024) {
 287              $shorthand = array('K', 'M', 'G');
 288              $tens = array('000', '000000', '000000000'); // A good enough decimal approximation of K, M, and G.
 289  
 290              // Do not *decrease* memory_limit.
 291              list($ml, $extra) = str_ireplace($shorthand, $tens, array(ini_get('memory_limit'), EXTRA_MEMORY));
 292  
 293              if ($ml < $extra) {
 294                  ini_set('memory_limit', EXTRA_MEMORY);
 295              }
 296          }
 297  
 298          // Read source image.
 299          if ($this->_SRC['type'] == 1) {
 300              $this->_SRC['image'] = imagecreatefromgif($this->_SRC['file']);
 301          } elseif ($this->_SRC['type'] == 2) {
 302              $this->_SRC['image'] = imagecreatefromjpeg($this->_SRC['file']);
 303          } elseif ($this->_SRC['type'] == 3) {
 304              $this->_SRC['image'] = imagecreatefrompng($this->_SRC['file']);
 305          }
 306  
 307          // Crop image.
 308          $off_w = 0;
 309          $off_h = 0;
 310  
 311          if ($this->crop != false) {
 312              if ($this->_SRC['height'] < $this->_SRC['width']) {
 313                  $ratio = (double) ($this->_SRC['height'] / $this->_DST['height']);
 314                  $cpyWidth = round($this->_DST['width'] * $ratio);
 315  
 316                  if ($cpyWidth > $this->_SRC['width']) {
 317                      $ratio = (double) ($this->_SRC['width'] / $this->_DST['width']);
 318                      $cpyWidth = $this->_SRC['width'];
 319                      $cpyHeight = round($this->_DST['height'] * $ratio);
 320                      $off_w = 0;
 321                      $off_h = round(($this->_SRC['height'] - $cpyHeight) / 2);
 322                      $this->_SRC['height'] = $cpyHeight;
 323                  } else {
 324                      $cpyHeight = $this->_SRC['height'];
 325                      $off_w = round(($this->_SRC['width'] - $cpyWidth) / 2);
 326                      $off_h = 0;
 327                      $this->_SRC['width'] = $cpyWidth;
 328                  }
 329              } else {
 330                  $ratio = (double) ($this->_SRC['width'] / $this->_DST['width']);
 331                  $cpyHeight = round($this->_DST['height'] * $ratio);
 332  
 333                  if ($cpyHeight > $this->_SRC['height']) {
 334                      $ratio = (double) ($this->_SRC['height'] / $this->_DST['height']);
 335                      $cpyHeight = $this->_SRC['height'];
 336                      $cpyWidth = round($this->_DST['width'] * $ratio);
 337                      $off_w = round(($this->_SRC['width'] - $cpyWidth) / 2);
 338                      $off_h = 0;
 339                      $this->_SRC['width'] = $cpyWidth;
 340                  } else {
 341                      $cpyWidth = $this->_SRC['width'];
 342                      $off_w = 0;
 343                      $off_h = round(($this->_SRC['height'] - $cpyHeight) / 2);
 344                      $this->_SRC['height'] = $cpyHeight;
 345                  }
 346              }
 347          }
 348  
 349          // Ensure non-zero height/width.
 350          if (!$this->_DST['height']) {
 351              $this->_DST['height'] = 1;
 352          }
 353  
 354          if (!$this->_DST['width']) {
 355              $this->_DST['width'] = 1;
 356          }
 357  
 358          // Create DST.
 359          $this->_DST['image'] = imagecreatetruecolor($this->_DST['width'], $this->_DST['height']);
 360  
 361          // GIF or PNG destination, set the transparency up.
 362          if ($this->_DST['type'] == 1 || $this->_DST['type'] == 3) {
 363              $trans_idx = imagecolortransparent($this->_SRC['image']);
 364              $pallet_size = imagecolorstotal($this->_SRC['image']);
 365  
 366              // Is there a specific transparent colour?
 367              if ($trans_idx >= 0 && ($trans_idx < $pallet_size)) {
 368                  $trans_color = imagecolorsforindex($this->_SRC['image'], $trans_idx);
 369                  $trans_idx = imagecolorallocate(
 370                      $this->_DST['image'],
 371                      $trans_color['red'],
 372                      $trans_color['green'],
 373                      $trans_color['blue']
 374                  );
 375                  imagefill($this->_DST['image'], 0, 0, $trans_idx);
 376                  imagecolortransparent($this->_DST['image'], $trans_idx);
 377              } elseif ($this->_DST['type'] == 3) {
 378                  imagealphablending($this->_DST['image'], false);
 379                  $transparent = imagecolorallocatealpha($this->_DST['image'], 0, 0, 0, 127);
 380                  imagefill($this->_DST['image'], 0, 0, $transparent);
 381                  imagesavealpha($this->_DST['image'], true);
 382              }
 383          }
 384  
 385          imagecopyresampled(
 386              $this->_DST['image'],
 387              $this->_SRC['image'],
 388              0,
 389              0,
 390              $off_w,
 391              $off_h,
 392              $this->_DST['width'],
 393              $this->_DST['height'],
 394              $this->_SRC['width'],
 395              $this->_SRC['height']
 396          );
 397  
 398          if ($this->sharpen === true) {
 399              $this->_DST['image'] = UnsharpMask($this->_DST['image'], 80, .5, 3);
 400          }
 401  
 402          // Finally, the real dimensions.
 403          $this->height = $this->_DST['height'];
 404          $this->width = $this->_DST['width'];
 405  
 406          // Add magnifying glass.
 407          if ($this->hint === true) {
 408              // Should we really add white bars?
 409              if ($this->addgreytohint === true) {
 410                  $trans = imagecolorallocatealpha($this->_DST['image'], 255, 255, 255, 25);
 411                  imagefilledrectangle(
 412                      $this->_DST['image'],
 413                      0,
 414                      $this->_DST['height'] - 9,
 415                      $this->_DST['width'],
 416                      $this->_DST['height'],
 417                      $trans
 418                  );
 419              }
 420  
 421              $magnifier = imagecreatefromstring(gzuncompress(base64_decode("eJzrDPBz5+WS4mJgYOD19HAJAtLcIMzBBiRXrilXA1IsxU6eIRxAUMOR0gHkcxZ4RBYD1QiBMOOlu3V/gIISJa4RJc5FqYklmfl5CiGZuakMBoZ6hkZ6RgYGJs77ex2BalRBaoLz00rKE4tSGXwTk4vyc1NTMhMV3DKLUsvzi7KLFXwjFEAa2svWnGdgYPTydHEMqZhTOsE++1CAyNHzm2NZjgau+dAmXlAwoatQmOld3t/NPxlLMvY7sovPzXHf7re05BPzjpQTMkZTPjm1HlHkv6clYWK43Zt16rcDjdZ/3j2cd7qD4/HHH3GaprFrw0QZDHicORXl2JsPsveVTDz//L3N+WpxJ5Hff+10Tjdd2/Vi17vea79Om5w9zzyne9GLnWGrN8atby/ayXPOsu2w4quvVtxNCVVz5nAf3nDpZckBCedpqSc28WTOWnT7rZNXZSlPvFybie9EFc6y3bIMCn3JAoJ+kyyfn9qWq+LZ9Las26Jv482cDRE6Ci0B6gVbo2oj9KabzD8vyMK4ZMqMs2kSvW4chz88SXNzmeGjtj1QZK9M3HHL8L7HITX3t19//VVY8CYDg9Kvy2vDXu+6mGGxNOiltMPsjn/t9eJr0ja/FOdi5TyQ9Lz3fOqstOr99/dnro2vZ1jy76D/vYivPsBoYPB09XNZ55TQBAAJjs5s</body>")));
 422  
 423              imagealphablending($this->_DST['image'], true);
 424              imagecopy($this->_DST['image'], $magnifier, $this->_DST['width'] - 15, $this->_DST['height'] - 14, 0, 0, 11, 11);
 425              imagedestroy($magnifier);
 426          }
 427  
 428          if ($verbose) {
 429              echo "... saving image ...";
 430          }
 431  
 432          if ($this->_DST['type'] == 1) {
 433              imagetruecolortopalette($this->_DST['image'], false, 256);
 434              if (function_exists('imagegif')) {
 435                  imagegif($this->_DST['image'], $this->_DST['file']);
 436              } else {
 437                  imagedestroy($this->_DST['image']);
 438                  imagedestroy($this->_SRC['image']);
 439  
 440                  return false;
 441              }
 442          } elseif ($this->_DST['type'] == 2) {
 443              imagejpeg($this->_DST['image'], $this->_DST['file'], $this->quality);
 444          } elseif ($this->_DST['type'] == 3) {
 445              imagepng($this->_DST['image'], $this->_DST['file']);
 446          }
 447  
 448          if ($verbose) {
 449              echo "... image successfully saved ...";
 450          }
 451  
 452          imagedestroy($this->_DST['image']);
 453          imagedestroy($this->_SRC['image']);
 454  
 455          return true;
 456      }
 457  
 458      /**
 459       * Return a reference to the the thumbnail image as a HTML a or img tag.
 460       *
 461       * @param  bool $aslink  Return an anchor tag to the source image
 462       * @param  bool $aspopup Open the link in new window
 463       * @return string HTML markup
 464       */
 465  
 466      public function asTag($aslink = true, $aspopup = false)
 467      {
 468          $imgtag = '<img src="'.$this->_DST['file'].'" '.$this->html.' width="'.$this->width.'" height="'.$this->height.'" />';
 469  
 470          if ($aslink === true) {
 471              return '<a href="'.((empty($this->linkurl)) ? $this->_SRC['file'] : $this->linkurl).'" '.
 472                  (($aspopup === true) ? ' rel="noopener" target="_blank"' : '').'>'.$imgtag.'</a>';
 473          }
 474  
 475          return $imgtag;
 476      }
 477  }
 478  
 479  /**
 480   * Wrapper for wet_thumb interfacing Textpattern.
 481   *
 482   * @package Image
 483   */
 484  
 485  class txp_thumb extends wet_thumb
 486  {
 487      /**
 488       * File extension.
 489       *
 490       * @var string
 491       */
 492  
 493      public $m_ext;
 494  
 495      /**
 496       * Image ID.
 497       *
 498       * @var int
 499       */
 500  
 501      public $m_id;
 502  
 503      /**
 504       * Constructor.
 505       *
 506       * @param int $id The Image id.
 507       */
 508  
 509      public function __construct($id)
 510      {
 511          $id = assert_int($id);
 512          $rs = safe_row("*", 'txp_image', "id = $id LIMIT 1");
 513          if ($rs) {
 514              extract($rs);
 515              $this->m_ext = $ext;
 516              $this->m_id = $id;
 517          }
 518          parent::__construct();
 519      }
 520  
 521      /**
 522       * Creates a thumbnail image from a source image.
 523       *
 524       * @param  string $dummy1 Isn't used.
 525       * @param  string $dummy2 Isn't used.
 526       * @return bool TRUE on success
 527       */
 528  
 529      public function write($dummy1 = '', $dummy2 = '')
 530      {
 531          if (!isset($this->m_ext)) {
 532              return false;
 533          }
 534  
 535          if (parent::write(
 536              IMPATH.$this->m_id.$this->m_ext,
 537              IMPATH.$this->m_id.'t'.$this->m_ext
 538          )) {
 539              safe_update(
 540                  'txp_image',
 541                  "thumbnail = 1,
 542                  thumb_w = $this->width,
 543                  thumb_h = $this->height,
 544                  date = NOW()",
 545                  "id = ".$this->m_id
 546              );
 547  
 548              chmod(IMPATH.$this->m_id.'t'.$this->m_ext, 0644);
 549  
 550              return true;
 551          }
 552  
 553          return false;
 554      }
 555  
 556      /**
 557       * Removes a thumbnail.
 558       *
 559       * @return bool TRUE on success
 560       */
 561  
 562      public function delete()
 563      {
 564          if (!isset($this->m_ext)) {
 565              return false;
 566          }
 567  
 568          if (unlink(IMPATH.$this->m_id.'t'.$this->m_ext)) {
 569              safe_update('txp_image', "thumbnail = 0", "id = ".$this->m_id);
 570  
 571              return true;
 572          }
 573  
 574          return false;
 575      }
 576  }
 577  
 578  /**
 579   * Unsharp mask.
 580   *
 581   * Unsharp mask algorithm by Torstein Hønsi 2003 (thoensi_at_netcom_dot_no)
 582   * Christoph Erdmann: changed it a little, because I could not reproduce the
 583   * darker blurred image, now it is up to 15% faster with same results
 584   *
 585   * @author Torstein Hønsi
 586   * @author Christoph Erdmann
 587   * @param  resource $img       Image as a resource
 588   * @param  int      $amount    Filter parameter
 589   * @param  int      $radius    Filter parameter
 590   * @param  int      $threshold Filter parameter
 591   * @return resource Sharpened image as a resource.
 592   *
 593   *
 594   * This library is free software; you can redistribute it and/or modify it
 595   * under the terms of the GNU Lesser General Public License as published by
 596   * the Free Software Foundation; either version 2.1 of the License, or
 597   * (at your option) any later version.
 598   */
 599  
 600      function UnsharpMask($img, $amount, $radius, $threshold)
 601      {
 602          // Attempt to calibrate the parameters to Photoshop:
 603          if ($amount > 500) {
 604              $amount = 500;
 605          }
 606  
 607          $amount = $amount * 0.016;
 608  
 609          if ($radius > 50) {
 610              $radius = 50;
 611          }
 612  
 613          $radius = $radius * 2;
 614  
 615          if ($threshold > 255) {
 616              $threshold = 255;
 617          }
 618  
 619          $radius = abs(round($radius)); // Only integers make sense.
 620  
 621          if ($radius == 0) {
 622              return $img;
 623          }
 624  
 625          $w = imagesx($img);
 626          $h = imagesy($img);
 627          $imgCanvas = $img;
 628          $imgCanvas2 = $img;
 629          $imgBlur = imagecreatetruecolor($w, $h);
 630  
 631          // Gaussian blur matrix:
 632          // 1 2 1
 633          // 2 4 2
 634          // 1 2 1
 635          // Move copies of the image around one pixel at the time and merge them
 636          // with weight according to the matrix. The same matrix is simply
 637          // repeated for higher radii.
 638  
 639          for ($i = 0; $i < $radius; $i++) {
 640              imagecopy($imgBlur, $imgCanvas, 0, 0, 1, 1, $w - 1, $h - 1); // up left
 641              imagecopymerge($imgBlur, $imgCanvas, 1, 1, 0, 0, $w, $h, 50); // down right
 642              imagecopymerge($imgBlur, $imgCanvas, 0, 1, 1, 0, $w - 1, $h, 33.33333); // down left
 643              imagecopymerge($imgBlur, $imgCanvas, 1, 0, 0, 1, $w, $h - 1, 25); // up right
 644              imagecopymerge($imgBlur, $imgCanvas, 0, 0, 1, 0, $w - 1, $h, 33.33333); // left
 645              imagecopymerge($imgBlur, $imgCanvas, 1, 0, 0, 0, $w, $h, 25); // right
 646              imagecopymerge($imgBlur, $imgCanvas, 0, 0, 0, 1, $w, $h - 1, 20); // up
 647              imagecopymerge($imgBlur, $imgCanvas, 0, 1, 0, 0, $w, $h, 16.666667); // down
 648              imagecopymerge($imgBlur, $imgCanvas, 0, 0, 0, 0, $w, $h, 50); // center
 649          }
 650  
 651          $imgCanvas = $imgBlur;
 652  
 653          // Calculate the difference between the blurred pixels and the original
 654          // and set the pixels.
 655  
 656          for ($x = 0; $x < $w; $x++) {
 657              // Each row.
 658              for ($y = 0; $y < $h; $y++) {
 659                  // Each pixel.
 660                  $rgbOrig = ImageColorAt($imgCanvas2, $x, $y);
 661                  $rOrig = (($rgbOrig >> 16) & 0xFF);
 662                  $gOrig = (($rgbOrig >> 8) & 0xFF);
 663                  $bOrig = ($rgbOrig & 0xFF);
 664                  $rgbBlur = ImageColorAt($imgCanvas, $x, $y);
 665                  $rBlur = (($rgbBlur >> 16) & 0xFF);
 666                  $gBlur = (($rgbBlur >> 8) & 0xFF);
 667                  $bBlur = ($rgbBlur & 0xFF);
 668  
 669                  // When the masked pixels differ less from the original than the
 670                  // threshold specifies, they are set to their original value.
 671  
 672                  $rNew = (abs($rOrig - $rBlur) >= $threshold) ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig)) : $rOrig;
 673                  $gNew = (abs($gOrig - $gBlur) >= $threshold) ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig)) : $gOrig;
 674                  $bNew = (abs($bOrig - $bBlur) >= $threshold) ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig)) : $bOrig;
 675  
 676                  if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) {
 677                      $pixCol = ImageColorAllocate($img, $rNew, $gNew, $bNew);
 678                      ImageSetPixel($img, $x, $y, $pixCol);
 679                  }
 680              }
 681          }
 682  
 683          return $img;
 684      }

title

Description

title

Description

title

Description

title

title

Body