Author: stunami
Date: 2010-04-04 12:45:24 +0200 (Sun, 04 Apr 2010)
New Revision: 28970
Added:
plugins/sfImageTransformPlugin/trunk/lib/transforms/GD/sfImageUnsharpMaskGD.class.php
plugins/sfImageTransformPlugin/trunk/lib/transforms/ImageMagick/sfImageUnsharpMaskImageMagick.class.php
Log:
Adding unsharp mask transform
Added:
plugins/sfImageTransformPlugin/trunk/lib/transforms/GD/sfImageUnsharpMaskGD.class.php
===================================================================
---
plugins/sfImageTransformPlugin/trunk/lib/transforms/GD/sfImageUnsharpMaskGD.class.php
(rev 0)
+++
plugins/sfImageTransformPlugin/trunk/lib/transforms/GD/sfImageUnsharpMaskGD.class.php
2010-04-04 10:45:24 UTC (rev 28970)
@@ -0,0 +1,301 @@
+<?php
+/*
+ * This file is part of the sfImageTransform package.
+ * (c) 2007 Stuart Lowes <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ *
+ * sfImageUnsharpMaskGD class.
+ *
+ * Applies an unsharp mask to the image.
+ *
+ * Based on http://vikjavev.no/computing/ump.php
+ *
+ * @package sfImageTransform
+ * @subpackage transforms
+ * @author Stuart Lowes <[email protected]>
+ * @version SVN: $Id$
+ */
+class sfImageUnsharpMaskGD extends sfImageTransformAbstract
+{
+ /**
+ *
+ * @var integer
+ */
+ protected $amount = 500;
+
+ /**
+ *
+ * @var integer
+ */
+ protected $radius = 50;
+
+ /**
+ *
+ * @var float
+ */
+ protected $threshold = 255;
+
+ public function __construct($radius, $threshold, $amount)
+ {
+ $this->setRadius($radius);
+ $this->setThreshold($threshold);
+ $this->setAmount($amount);
+ }
+
+ /**
+ * The radius of the blurring circle of the mask
+ *
+ * @param integer
+ */
+ public function setRadius($radius)
+ {
+ if(is_numeric($radius) && $radius > 0 && $radius <= 50)
+ {
+
+ $this->radius = (float)$radius;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the radius of the blurring circle of the mask
+ *
+ * @return integer
+ */
+ public function getRadius()
+ {
+ return $this->radius;
+ }
+
+ /**
+ * Threshold the least
+ * difference in colour values that is allowed between the original and the
mask. In practice
+ * this means that low-contrast areas of the picture are left unrendered
whereas edges
+ * are treated normally. This is good for pictures of e.g. skin or blue
skies.
+ *
+ * @param float
+ */
+ public function setThreshold($threshold)
+ {
+ if(is_numeric($threshold) && $threshold > 0 && $threshold <= 500)
+ {
+ $this->threshold = (float)$threshold;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ *
+ *
+ * @return integer
+ */
+ public function getThreshold()
+ {
+ return $this->threshold;
+ }
+
+ /**
+ * Amount of unsharp to be applied. 100 is normal
+ *
+ * @param integer
+ */
+ public function setAmount($amount)
+ {
+ if(is_numeric($amount) && $amount > 0 && $amount <= 500)
+ {
+ $this->amount = (int)$amount;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the amount of unsharp mask to be applied
+ *
+ * @return integer
+ */
+ public function getAmount()
+ {
+ return $this->amount;
+ }
+
+ protected function transform(sfImage $image)
+ {
+ $resource = $image->getAdapter()->getHolder();
+
+ // Attempt to calibrate the parameters to Photoshop:
+ $amount = $this->getAmount() * 0.016;
+ $radius = abs(round($this->getRadius() * 2));
+
+ $threshold = $this->getThreshold();
+
+ $w = $image->getWidth();
+ $h = $image->getHeight();
+
+ if ($radius > 0)
+ {
+ $imgCanvas = imagecreatetruecolor($w, $h);
+ $imgBlur = imagecreatetruecolor($w, $h);
+
+ if (function_exists('imageconvolution'))
+ {
+ $matrix = array(
+ array( 1, 2, 1 ),
+ array( 2, 4, 2 ),
+ array( 1, 2, 1 )
+ );
+
+ imagecopy ($imgBlur, $resource, 0, 0, 0, 0, $w, $h);
+ imageconvolution($imgBlur, $matrix, 16, 0);
+ }
+
+ else
+ {
+
+ // Move copies of the image around one pixel at the time and merge
them with weight
+ // according to the matrix. The same matrix is simply repeated for
higher radii.
+ for ($i = 0; $i < $radius; $i++)
+ {
+ imagecopy ($imgBlur, $resource, 0, 0, 1, 0, $w - 1, $h); // left
+ imagecopymerge ($imgBlur, $resource, 1, 0, 0, 0, $w, $h, 50); //
right
+ imagecopymerge ($imgBlur, $resource, 0, 0, 0, 0, $w, $h, 50); //
center
+ imagecopy ($imgCanvas, $imgBlur, 0, 0, 0, 0, $w, $h);
+
+ imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 0, 1, $w, $h - 1,
33.33333 ); // up
+ imagecopymerge ($imgBlur, $imgCanvas, 0, 1, 0, 0, $w, $h, 25); //
down
+ }
+ }
+
+ if ($threshold > 0)
+ {
+ // Calculate the difference between the blurred pixels and the
original
+ // and set the pixels
+
+ // Each row
+ for ($x = 0; $x < $w - 1; $x++)
+ {
+ // Each pixel
+ for ($y = 0; $y < $h; $y++)
+ {
+
+ $rgbOrig = ImageColorAt($resource, $x, $y);
+ $rOrig = (($rgbOrig >> 16) & 0xFF);
+ $gOrig = (($rgbOrig >> 8) & 0xFF);
+ $bOrig = ($rgbOrig & 0xFF);
+
+ $rgbBlur = ImageColorAt($imgBlur, $x, $y);
+
+ $rBlur = (($rgbBlur >> 16) & 0xFF);
+ $gBlur = (($rgbBlur >> 8) & 0xFF);
+ $bBlur = ($rgbBlur & 0xFF);
+
+ // When the masked pixels differ less from the original
+ // than the threshold specifies, they are set to their original
value.
+ $rNew = $rOrig;
+ if (abs($rOrig - $rBlur) >= $threshold)
+ {
+ $rNew = max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig));
+ }
+
+ $gNew = $gOrig;
+ if (abs($gOrig - $gBlur) >= $threshold)
+ {
+ $gNew = max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig));
+ }
+
+
+ $bNew = $bOrig;
+ if (abs($bOrig - $bBlur) >= $threshold)
+ {
+ $bNew = max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig));
+ }
+
+ if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew))
+ {
+ $pixCol = ImageColorAllocate($resource, $rNew, $gNew, $bNew);
+ ImageSetPixel($resource, $x, $y, $pixCol);
+ }
+ }
+ }
+ }
+
+ else
+ {
+ // each row
+ for ($x = 0; $x < $w; $x++)
+ {
+ // each pixel
+ for ($y = 0; $y < $h; $y++)
+ {
+ $rgbOrig = ImageColorAt($resource, $x, $y);
+ $rOrig = (($rgbOrig >> 16) & 0xFF);
+ $gOrig = (($rgbOrig >> 8) & 0xFF);
+ $bOrig = ($rgbOrig & 0xFF);
+
+ $rgbBlur = ImageColorAt($imgBlur, $x, $y);
+
+ $rBlur = (($rgbBlur >> 16) & 0xFF);
+ $gBlur = (($rgbBlur >> 8) & 0xFF);
+ $bBlur = ($rgbBlur & 0xFF);
+
+ $rNew = ($amount * ($rOrig - $rBlur)) + $rOrig;
+
+ if($rNew > 255)
+ {
+ $rNew = 255;
+ }
+ elseif ($rNew < 0)
+ {
+ $rNew = 0;
+ }
+
+ $gNew = ($amount * ($gOrig - $gBlur)) + $gOrig;
+
+ if($gNew > 255)
+ {
+ $gNew = 255;
+ }
+ elseif ($gNew < 0)
+ {
+ $gNew = 0;
+ }
+
+ $bNew = ($amount * ($bOrig - $bBlur)) + $bOrig;
+
+ if ($bNew > 255)
+ {
+ $bNew = 255;
+ }
+ elseif ($bNew < 0)
+ {
+ $bNew = 0;
+ }
+
+ $rgbNew = ($rNew << 16) + ($gNew <<8) + $bNew;
+ ImageSetPixel($resource, $x, $y, $rgbNew);
+ }
+ }
+ }
+
+ imagedestroy($imgCanvas);
+ imagedestroy($imgBlur);
+
+ }
+
+ return $image;
+ }
+
+}
Added:
plugins/sfImageTransformPlugin/trunk/lib/transforms/ImageMagick/sfImageUnsharpMaskImageMagick.class.php
===================================================================
---
plugins/sfImageTransformPlugin/trunk/lib/transforms/ImageMagick/sfImageUnsharpMaskImageMagick.class.php
(rev 0)
+++
plugins/sfImageTransformPlugin/trunk/lib/transforms/ImageMagick/sfImageUnsharpMaskImageMagick.class.php
2010-04-04 10:45:24 UTC (rev 28970)
@@ -0,0 +1,208 @@
+<?php
+/*
+ * This file is part of the sfImageTransform package.
+ * (c) 2007 Stuart Lowes <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ *
+ * sfImageUnsharpMaskGD class.
+ *
+ * Applies an unsharp mask to the image.
+ *
+ * Based on http://vikjavev.no/computing/ump.php
+ *
+ * @package sfImageTransform
+ * @subpackage transforms
+ * @author Stuart Lowes <[email protected]>
+ * @version SVN: $Id$
+ */
+class sfImageUnsharpMaskImageMagick extends sfImageTransformAbstract
+{
+ /**
+ *
+ * @var float
+ */
+ protected $amount = null;
+
+ /**
+ *
+ * @var float
+ */
+ protected $radius = null;
+
+ /**
+ *
+ * @var float
+ */
+ protected $threshold = null;
+
+ /**
+ *
+ * @var float
+ */
+ protected $sigma = null;
+
+ /**
+ *
+ * Channel
+ *
+ * @var integer
+ */
+ protected $channel = Imagick::CHANNEL_ALL;
+
+
+ public function __construct($radius, $threshold, $amount, $sigma, $channel =
Imagick::CHANNEL_ALL)
+ {
+ $this->setRadius($radius);
+ $this->setThreshold($threshold);
+ $this->setAmount($amount);
+ $this->setSigma($sigma);
+ }
+
+ /**
+ * The radius of the blurring circle of the mask
+ *
+ * @param integer
+ */
+ public function setRadius($radius)
+ {
+ if(is_numeric($radius))
+ {
+
+ $this->radius = (float)$radius;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the radius of the blurring circle of the mask
+ *
+ * @return integer
+ */
+ public function getRadius()
+ {
+ return $this->radius;
+ }
+
+ /**
+ * Threshold the least
+ * difference in colour values that is allowed between the original and the
mask. In practice
+ * this means that low-contrast areas of the picture are left unrendered
whereas edges
+ * are treated normally. This is good for pictures of e.g. skin or blue
skies.
+ *
+ * @param float
+ */
+ public function setThreshold($threshold)
+ {
+ if(is_numeric($threshold))
+ {
+ $this->threshold = $threshold;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ *
+ *
+ * @return integer
+ */
+ public function getThreshold()
+ {
+ return $this->threshold;
+ }
+
+ /**
+ * Amount of unsharp to be applied. 100 is normal
+ *
+ * @param integer
+ */
+ public function setAmount($amount)
+ {
+ if(is_numeric($amount))
+ {
+ $this->amount = (float)$amount;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the amount of unsharp mask to be applied
+ *
+ * @return integer
+ */
+ public function getAmount()
+ {
+ return $this->amount;
+ }
+
+ /**
+ *
+ *
+ * @param float
+ */
+ public function setSigma($sigma)
+ {
+ if(is_numeric($sigma))
+ {
+ $this->sigma = (float)$sigma;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ *
+ *
+ * @return float
+ */
+ public function getSigma()
+ {
+ return $this->sigma;
+ }
+
+ /**
+ *
+ *
+ * @param integer
+ */
+ public function setChannel($channel)
+ {
+ $this->channel = $channel;
+ }
+
+ /**
+ *
+ *
+ * @return integer
+ */
+ public function getChannel()
+ {
+ return $this->channel;
+ }
+
+ protected function transform(sfImage $image)
+ {
+ $resource = $image->getAdapter()->getHolder();
+
+ $resource->normalizeImage();
+
+ $resource->unsharpMaskImage($this->getRadius(), $this->getSigma(),
$this->getAmount(), $this->getThreshold());
+
+ return $image;
+ }
+}
--
You received this message because you are subscribed to the Google Groups
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/symfony-svn?hl=en.