Remove imagick related code from the Im driver and effects.
authorMichael J. Rubinsky <mrubinsk@horde.org>
Thu, 28 May 2009 14:27:48 +0000 (10:27 -0400)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Fri, 29 May 2009 15:38:19 +0000 (11:38 -0400)
framework/Image/lib/Horde/Image.php
framework/Image/lib/Horde/Image/Effect/Im/Border.php
framework/Image/lib/Horde/Image/Effect/Im/Composite.php
framework/Image/lib/Horde/Image/Effect/Im/DropShadow.php
framework/Image/lib/Horde/Image/Effect/Im/PhotoStack.php
framework/Image/lib/Horde/Image/Effect/Im/PolaroidImage.php
framework/Image/lib/Horde/Image/Effect/Im/RoundCorners.php
framework/Image/lib/Horde/Image/Im.php

index 6caf45a..267102e 100644 (file)
@@ -62,23 +62,19 @@ class Horde_Image
      */
     protected $_logger;
 
-    // @TODO: width/height should be protected since they aren't reliable
-    //        (should use ::getDimensions()) but we need a way to set them
-    //        to zero from Effects... leaving public until a clearGeometry()
-    //        method is implemented.
     /**
      * The current width of the image data.
      *
      * @var integer
      */
-    public $_width = 0;
+    protected $_width = 0;
 
     /**
      * The current height of the image data.
      *
      * @var integer
      */
-    public $_height = 0;
+    protected $_height = 0;
 
     /**
      * A directory for temporary files.
index f2bebe6..edebc51 100755 (executable)
@@ -29,19 +29,11 @@ class Horde_Image_Effect_Im_Border extends Horde_Image_Effect
      */
     public function apply()
     {
-        if (!is_null($this->_image->_imagick)) {
-             $this->_image->_imagick->borderImage(
-                $this->_params['bordercolor'],
-                $this->_params['borderwidth'],
-                $this->_params['borderwidth']);
-        } else {
-            $this->_image->addPostSrcOperation(sprintf(
-                "   -bordercolor \"%s\" %s -border %s",
-                $this->_params['bordercolor'],
-                (!empty($this->_params['preserve']) ? '-compose Copy' : ''),
-                $this->_params['borderwidth']));
-        }
-
+        $this->_image->addPostSrcOperation(sprintf(
+            "   -bordercolor \"%s\" %s -border %s",
+            $this->_params['bordercolor'],
+            (!empty($this->_params['preserve']) ? '-compose Copy' : ''),
+            $this->_params['borderwidth']));
         return true;
     }
 
index 15bf207..3b5bf13 100755 (executable)
@@ -36,47 +36,28 @@ class Horde_Image_Effect_Im_Composite extends Horde_Image_Effect
      */
     public function apply()
     {
-        $this->_image->_imagick = null;
-        if (!is_null($this->_image->_imagick)) {
-            foreach ($this->_params['images'] as $image) {
-                $topimg = new Horde_Image_ImagickProxy();
-                $topimg->clear();
-                $topimg->readImageBlob($image->raw());
-
-                /* Calculate center for composite (gravity center)*/
-                $geometry = $this->_image->_imagick->getImageGeometry();
-                $x = $geometry['width'] / 2;
-                $y = $geometry['height'] / 2;
-
-                if (isset($this->_params['x']) && isset($this->_params['y'])) {
-                    $x = $this->_params['x'];
-                    $y = $this->_params['y'];
-                }
-                $this->_image->_imagick->compositeImage($topimg, constant('Imagick::COMPOSITE_OVER'), $x, $y);
-            }
-        } else {
-            $ops = $geometry = $gravity = '';
-            if (isset($this->_params['gravity'])) {
-                $gravity = ' -gravity ' . $this->_params['gravity'];
-            }
+        $ops = $geometry = $gravity = '';
+        if (isset($this->_params['gravity'])) {
+            $gravity = ' -gravity ' . $this->_params['gravity'];
+        }
 
-            if (isset($this->_params['x']) && isset($this->_params['y'])) {
-                $geometry = ' -geometry +' . $this->_params['x'] . '+' . $this->_params['y'] . ' ';
-            }
-            if (isset($this->_params['compose'])) {
-                // The -matte ensures that the destination (background) image
-                // has an alpha channel - to avoid black holes in the image.
-                $compose = ' -compose ' . $this->_params['compose'] . ' -matte';
-            }
+        if (isset($this->_params['x']) && isset($this->_params['y'])) {
+            $geometry = ' -geometry +' . $this->_params['x'] . '+' . $this->_params['y'] . ' ';
+        }
+        if (isset($this->_params['compose'])) {
+            // The -matte ensures that the destination (background) image
+            // has an alpha channel - to avoid black holes in the image.
+            $compose = ' -compose ' . $this->_params['compose'] . ' -matte';
+        }
 
-            foreach($this->_params['images'] as $image) {
-                $temp = $image->toFile();
-                $this->_image->addFileToClean($temp);
-                $ops .= ' ' . $temp . $gravity . $compose . ' -composite';
-            }
-            $this->_image->addOperation($geometry);
-            $this->_image->addPostSrcOperation($ops);
+        foreach($this->_params['images'] as $image) {
+            $temp = $image->toFile();
+            $this->_image->addFileToClean($temp);
+            $ops .= ' ' . $temp . $gravity . $compose . ' -composite';
         }
+        $this->_image->addOperation($geometry);
+        $this->_image->addPostSrcOperation($ops);
+
         return true;
     }
 
index 83a504a..f95de76 100644 (file)
@@ -32,51 +32,9 @@ class Horde_Image_Effect_Im_DropShadow extends Horde_Image_Effect
      */
     public function apply()
     {
-        if (!is_null($this->_image->_imagick)) {
-            // $shadow is_a ImagickProxy object
-            $shadow = $this->_image->_imagick->cloneIM();
-            $shadow->setImageBackgroundColor('black');
-            $shadow->shadowImage(80, $this->_params['fade'],
-                                 $this->_params['distance'],
-                                 $this->_params['distance']);
-
-
-            // If we have an actual background color, we need to explicitly
-            // create a new background image with that color to be sure there
-            // *is* a background color.
-            if ($this->_params['background'] != 'none') {
-                $size = $shadow->getImageGeometry();
-                $new = new Horde_Image_ImagickProxy($size['width'],
-                                                    $size['height'],
-                                                    $this->_params['background'],
-                                                    $this->_image->getType());
-
-                $new->compositeImage($shadow,
-                                     constant('Imagick::COMPOSITE_OVER'), 0, 0);
-                $shadow->clear();
-                $shadow->addImage($new);
-                $new->destroy();
-            }
-
-            if ($this->_params['padding']) {
-                $shadow->borderImage($this->_params['background'],
-                                     $this->_params['padding'],
-                                     $this->_params['padding']);
-            }
-            $shadow->compositeImage($this->_image->_imagick,
-                                    constant('Imagick::COMPOSITE_OVER'),
-                                    0, 0);
-            $this->_image->_imagick->clear();
-            $this->_image->_imagick->addImage($shadow);
-            $shadow->destroy();
-        } else {
-            $size = $this->_image->getDimensions();
-//            $this->_image->addPostSrcOperation("-size {$size['width']}x{$size['height']} xc:{$this->_params['background']} "
-//                . "-fill {$this->_params['background']} -draw \"matte 0,0 reset\"");
-            $this->_image->addPostSrcOperation('\( +clone -background black -shadow 80x' . $this->_params['fade'] . '+' . $this->_params['distance'] . '+' . $this->_params['distance'] . ' \) +swap -background none -flatten +repage -bordercolor ' . $this->_params['background'] . ' -border ' . $this->_params['padding']);
-        }
-        $this->_image->_width = 0;
-        $this->_image->_height = 0;
+        $size = $this->_image->getDimensions();
+        $this->_image->addPostSrcOperation('\( +clone -background black -shadow 80x' . $this->_params['fade'] . '+' . $this->_params['distance'] . '+' . $this->_params['distance'] . ' \) +swap -background none -flatten +repage -bordercolor ' . $this->_params['background'] . ' -border ' . $this->_params['padding']);
+        $this->_image->clearGeometry();
 
         return true;
     }
index 1ccf6e8..1f2b8f8 100644 (file)
@@ -61,81 +61,60 @@ class Horde_Image_Effect_Im_PhotoStack extends Horde_Image_Effect
         $i = 1;
         $cnt = count($this->_params['images']);
         if ($cnt <=0) {
-            return PEAR::raiseError('No images provided');
+            throw new Horde_Image_Exception('No Images provided.');
         }
-        if (!is_null($this->_image->_imagick) &&
-            $this->_image->_imagick->methodExists('polaroidImage') &&
-            $this->_image->_imagick->methodExists('trimImage')) {
 
-            $imgs = array();
-            $length = 0;
+        // Start out fresh.
+        $this->_image->raw();
+
+        switch ($this->_params['type']) {
+        case 'plain':
+        case 'rounded':
+            // Get top image dimensions, then force each bottom image to the
+            // same dimensions.
+            $this->_params['images'][$cnt - 1]->resize($this->_params['resize_height'],
+                                                       $this->_params['resize_height'],
+                                                       true);
+            $size = $this->_params['images'][$cnt - 1]->getDimensions();
+            //$this->_image->resize(2 * $this->_params['resize_height'], 2 * $this->_params['resize_height']);
+            for ($i = 0; $i < $cnt; $i++) {
+                $this->_params['images'][$i]->resize($size['height'], $size['width'], false);
+            }
+            $xo = $yo = (count($this->_params['images']) + 1) * $this->_params['offset'];
+            $ops = '';
+            $haveBottom = false;
+            foreach ($this->_params['images'] as $image) {
+                $xo -= $this->_params['offset'];
+                $yo -= $this->_params['offset'];
 
-            switch ($this->_params['type']) {
-            case 'plain':
-            case 'rounded':
-                $haveBottom = false;
-                // First, we need to resize the top image to get the dimensions
-                // for the rest of the stack.
-                $topimg = new Horde_Image_ImagickProxy();
-                $topimg->clear();
-                $topimg->readImageBlob($this->_params['images'][$cnt - 1]->raw());
-                $topimg->thumbnailImage(
-                    $this->_params['resize_height'],
-                    $this->_params['resize_height'],
-                    true);
                 if ($this->_params['type'] == 'rounded') {
-                    $topimg = $this->_roundBorder($topimg);
+                    $temp = $this->_roundBorder($image);
+                } else {
+                    $temp = $image->toFile();
                 }
+                $this->_image->addFileToClean($temp);
+                $ops .= ' \( ' . $temp . ' -background none -thumbnail ' . $size['width'] . 'x' . $size['height'] . '! -repage +' . $xo . '+' . $yo . ($this->_params['type'] == 'plain' ? ' -bordercolor "#333" -border 1 ' : ' ' ) . ((!$haveBottom) ? '\( +clone -shadow 80x4+0+0 \) +swap -mosaic' : '') . ' \) ';
+                $haveBottom = true;
+            }
 
-                $size = $topimg->getImageGeometry();
-                foreach ($this->_params['images'] as $image) {
-                    $imgk= new Horde_Image_ImagickProxy();
-                    $imgk->clear();
-                    $imgk->readImageBlob($image->raw());
-                    if ($i++ <= $cnt) {
-                        $imgk->thumbnailImage($size['width'], $size['height'],
-                                              false);
-                    } else {
-                        $imgk->destroy();
-                        $imgk = $topimg->cloneIM();
-                    }
+            // The first -background none option below is only honored in
+            // convert versions before 6.4 it seems. Without it specified as
+            // none here, all stacks come out with a white background.
+            $this->_image->addPostSrcOperation($ops . ' -background ' . $this->_params['background'] . ' -mosaic -bordercolor ' . $this->_params['background'] . ' -border ' . $this->_params['padding']);
 
-                    if ($this->_params['type'] == 'rounded') {
-                        $imgk = $this->_roundBorder($imgk);
-                    } else {
-                        $imgk->borderImage($this->_params['bordercolor'], 1, 1);
-                    }
-                    // Only shadow the bottom image for 'plain' stacks
-                    if (!$haveBottom) {
-                        $shad = $imgk->cloneIM();
-                        $shad->setImageBackgroundColor('black');
-                        $shad->shadowImage(80, 4, 0, 0);
-                        $shad->compositeImage($imgk,
-                                              constant('Imagick::COMPOSITE_OVER'),
-                                              0, 0);
-                        $imgk->clear();
-                        $imgk->addImage($shad);
-                        $shad->destroy();
-                        $haveBottom = true;
-                    }
-                    // Get the geometry of the image and remember the largest.
-                    $geo = $imgk->getImageGeometry();
-                    $length = max(
-                        $length,
-                        sqrt(pow($geo['height'], 2) + pow($geo['width'], 2)));
+            break;
 
-                    $imgs[] = $imgk;
-                }
-                break;
-            case 'polaroid':
+        case 'polaroid':
+            // Check for im version > 6.3.2
+            $ver = $this->_image->getIMVersion();
+            if (is_array($ver) && version_compare($ver[0], '6.3.2') >= 0) {
+                $ops = '';
                 foreach ($this->_params['images'] as $image) {
-                    $imgk= new Horde_Image_ImagickProxy();
-                    $imgk->clear();
-                    $imgk->readImageBlob($image->raw());
-                    $imgk->thumbnailImage($this->_params['resize_height'],
-                                          $this->_params['resize_height'],
-                                          true);
-                    $imgk->setImageBackgroundColor('black');
+                    $temp = $image->toFile();
+                    // Remember the temp files so we can nuke them later.
+                    $this->_image->addFileToClean($temp);
+
+                    // Don't rotate the top image.
                     if ($i++ == $cnt) {
                         $angle = 0;
                     } else {
@@ -144,155 +123,30 @@ class Horde_Image_Effect_Im_PhotoStack extends Horde_Image_Effect
                             $angle = $angle * -1;
                         }
                     }
-                    $result = $imgk->polaroidImage($angle);
-                    if (is_a($result, 'PEAR_Error')) {
-                        return $result;
-                    }
-                     // Get the geometry of the image and remember the largest.
-                    $geo = $imgk->getImageGeometry();
-                    $length = max(
-                        $length,
-                        sqrt(pow($geo['height'], 2) + pow($geo['width'], 2)));
-
-                    $imgs[] = $imgk;
-                }
-                break;
-            }
-
-            // Make sure the background canvas is large enough to hold it all.
-            $this->_image->_imagick->thumbnailImage($length * 1.5 + 20,
-                                                    $length * 1.5 + 20);
-
-            // x and y offsets.
-            $xo = $yo = (count($imgs) + 1) * $this->_params['offset'];
-            foreach ($imgs as $image) {
-                if ($this->_params['type'] == 'polaroid') {
-                    $xo = mt_rand(1, $this->_params['resize_height'] / 2);
-                    $yo = mt_rand(1, $this->_params['resize_height'] / 2);
-                } elseif ($this->_params['type'] == 'plain' ||
-                          $this->_params['type'] == 'rounded') {
-                    $xo -= $this->_params['offset'];
-                    $yo -= $this->_params['offset'];
+                    $ops .= ' \( ' . $temp . ' -geometry +' . mt_rand(1, $this->_params['resize_height']) . '+' . mt_rand(1, $this->_params['resize_height']) . ' -thumbnail \'' . $this->_params['resize_height'] . 'x' . $this->_params['resize_height'] . '>\' -bordercolor Snow -border 1 -polaroid ' . $angle . ' \) ';
                 }
-
-                $this->_image->_imagick->compositeImage(
-                    $image, constant('Imagick::COMPOSITE_OVER'), $xo, $yo);
-                $image->removeImage();
-                $image->destroy();
-            }
-            // If we have a background other than 'none' we need to
-            // compose two images together to make sure we *have* a background.
-            if ($this->_params['background'] != 'none') {
-                $size = $this->_image->getDimensions();
-                $new = new Horde_Image_ImagickProxy($length * 1.5 + 20,
-                                                    $length * 1.5 + 20,
-                                                    $this->_params['background'],
-                                                    $this->_image->getType());
-
-
-
-                $new->compositeImage($this->_image->_imagick,
-                                     constant('Imagick::COMPOSITE_OVER'), 0, 0);
-                $this->_image->_imagick->clear();
-                $this->_image->_imagick->addImage($new);
-                $new->destroy();
-            }
-            // Trim the canvas before resizing to keep the thumbnails as large
-            // as possible.
-            $this->_image->_imagick->trimImage(0);
-            if ($this->_params['padding']) {
-                $this->_image->_imagick->borderImage($this->_params['background'],
-                                                     $this->_params['padding'],
-                                                     $this->_params['padding']);
-            }
-
-        } else {
-            // No Imagick installed - use im, but make sure we don't mix imagick
-            // and convert.
-            $this->_image->_imagick = null;
-            $this->_image->raw();
-
-            switch ($this->_params['type']) {
-            case 'plain':
-            case 'rounded':
-                // Get top image dimensions, then force each bottom image to the
-                // same dimensions.
-                $this->_params['images'][$cnt - 1]->resize($this->_params['resize_height'],
-                                                           $this->_params['resize_height'],
-                                                           true);
-                $size = $this->_params['images'][$cnt - 1]->getDimensions();
-                //$this->_image->resize(2 * $this->_params['resize_height'], 2 * $this->_params['resize_height']);
-                for ($i = 0; $i < $cnt; $i++) {
-                    $this->_params['images'][$i]->resize($size['height'], $size['width'], false);
-                }
-                $xo = $yo = (count($this->_params['images']) + 1) * $this->_params['offset'];
+                $this->_image->addPostSrcOperation('-background none' . $ops . '-mosaic -bordercolor ' . $this->_params['background'] . ' -border ' . $this->_params['padding']);
+            } else {
+                // An attempt at a -polaroid command free version of this
+                // effect based on various examples and ideas at
+                // http://imagemagick.org
                 $ops = '';
-                $haveBottom = false;
                 foreach ($this->_params['images'] as $image) {
-                    $xo -= $this->_params['offset'];
-                    $yo -= $this->_params['offset'];
-
-                    if ($this->_params['type'] == 'rounded') {
-                        $temp = $this->_roundBorder($image);
-                    } else {
-                        $temp = $image->toFile();
-                    }
+                    $temp = $image->toFile();
                     $this->_image->addFileToClean($temp);
-                    $ops .= ' \( ' . $temp . ' -background none -thumbnail ' . $size['width'] . 'x' . $size['height'] . '! -repage +' . $xo . '+' . $yo . ($this->_params['type'] == 'plain' ? ' -bordercolor "#333" -border 1 ' : ' ' ) . ((!$haveBottom) ? '\( +clone -shadow 80x4+0+0 \) +swap -mosaic' : '') . ' \) ';
-                    $haveBottom = true;
-                }
-
-                // The first -background none option below is only honored in
-                // convert versions before 6.4 it seems. Without it specified as
-                // none here, all stacks come out with a white background.
-                $this->_image->addPostSrcOperation($ops . ' -background ' . $this->_params['background'] . ' -mosaic -bordercolor ' . $this->_params['background'] . ' -border ' . $this->_params['padding']);
-
-                break;
-
-            case 'polaroid':
-                // Check for im version > 6.3.2
-                $ver = $this->_image->getIMVersion();
-                if (is_array($ver) && version_compare($ver[0], '6.3.2') >= 0) {
-                    $ops = '';
-                    foreach ($this->_params['images'] as $image) {
-                        $temp = $image->toFile();
-                        // Remember the temp files so we can nuke them later.
-                        $this->_image->addFileToClean($temp);
-
-                        // Don't rotate the top image.
-                        if ($i++ == $cnt) {
-                            $angle = 0;
-                        } else {
-                            $angle = mt_rand(1, 45);
-                            if (mt_rand(1, 2) % 2 === 0) {
-                                $angle = $angle * -1;
-                            }
-                        }
-                        $ops .= ' \( ' . $temp . ' -geometry +' . mt_rand(1, $this->_params['resize_height']) . '+' . mt_rand(1, $this->_params['resize_height']) . ' -thumbnail \'' . $this->_params['resize_height'] . 'x' . $this->_params['resize_height'] . '>\' -bordercolor Snow -border 1 -polaroid ' . $angle . ' \) ';
-                    }
-                    $this->_image->addPostSrcOperation('-background none' . $ops . '-mosaic -bordercolor ' . $this->_params['background'] . ' -border ' . $this->_params['padding']);
-                } else {
-                    // An attempt at a -polaroid command free version of this
-                    // effect based on various examples and ideas at
-                    // http://imagemagick.org
-                    $ops = '';
-                    foreach ($this->_params['images'] as $image) {
-                        $temp = $image->toFile();
-                        $this->_image->addFileToClean($temp);
-                        if ($i++ == $cnt) {
-                            $angle = 0;
-                        } else {
-                            $angle = mt_rand(1, 45);
-                            if (mt_rand(1, 2) % 2 === 0) {
-                                $angle = $angle * -1;
-                            }
+                    if ($i++ == $cnt) {
+                        $angle = 0;
+                    } else {
+                        $angle = mt_rand(1, 45);
+                        if (mt_rand(1, 2) % 2 === 0) {
+                            $angle = $angle * -1;
                         }
-                        $ops .= '\( ' . $temp . ' -thumbnail \'' . $this->_params['resize_height'] . 'x' . $this->_params['resize_height']. '>\' -bordercolor "#eee" -border 4 -bordercolor grey90 -border 1 -bordercolor none -background none -rotate ' . $angle . ' -background none \( +clone -shadow 60x4+4+4 \) +swap -background none -flatten \) ';
                     }
-                    $this->_image->addPostSrcOperation('-background none ' . $ops . '-mosaic -trim +repage -bordercolor ' . $this->_params['background'] . ' -border ' . $this->_params['padding']);
+                    $ops .= '\( ' . $temp . ' -thumbnail \'' . $this->_params['resize_height'] . 'x' . $this->_params['resize_height']. '>\' -bordercolor "#eee" -border 4 -bordercolor grey90 -border 1 -bordercolor none -background none -rotate ' . $angle . ' -background none \( +clone -shadow 60x4+4+4 \) +swap -background none -flatten \) ';
                 }
-                break;
+                $this->_image->addPostSrcOperation('-background none ' . $ops . '-mosaic -trim +repage -bordercolor ' . $this->_params['background'] . ' -border ' . $this->_params['padding']);
             }
+            break;
         }
 
         return true;
@@ -302,27 +156,13 @@ class Horde_Image_Effect_Im_PhotoStack extends Horde_Image_Effect
     {
         $context = array('tmpdir' => $this->_image->getTmpDir(),
                          'convert' => $this->_image->getConvertPath());
-        if (!is_null($this->_image->_imagick)) {
-            $size = $image->getImageGeometry();
-            $new = Horde_Image::factory('im', array('context' => $context));
-            $new->loadString('somestring', $image->getImageBlob());
-            $image->destroy();
-            $new->addEffect('RoundCorners', array('border' => 2, 'bordercolor' => '#111'));
-            $new->applyEffects();
-            $return  = new Horde_Image_ImagickProxy($size['width'] + $this->_params['borderwidth'],
-                                                $size['height'] + $this->_params['borderwidth'],
-                                                $this->_params['bordercolor'],
-                                                $this->_image->getType());
-            $return->clear();
-            $return->readImageBlob($new->raw());
-            return $return;
-        } else {
-            $size = $image->getDimensions();
-            $new = Horde_Image::factory('im', array('data' => $image->raw(), 'context' => $context));
-            $new->addEffect('RoundCorners', array('border' => 2, 'bordercolor' => '#111', 'background' => 'none'));
-            $new->applyEffects();
-            return $new->toFile();
-        }
+
+        $size = $image->getDimensions();
+        $new = Horde_Image::factory('im', array('data' => $image->raw(), 'context' => $context));
+        $new->addEffect('RoundCorners', array('border' => 2, 'bordercolor' => '#111', 'background' => 'none'));
+        $new->applyEffects();
+
+        return $new->toFile();
     }
 
 }
\ No newline at end of file
index cd93d89..3845019 100755 (executable)
@@ -35,52 +35,19 @@ class Horde_Image_Effect_Im_PolaroidImage extends Horde_Image_Effect
      */
     public function apply()
     {
-        if (!is_null($this->_image->_imagick) &&
-            $this->_image->_imagick->methodExists('polaroidImage') &&
-            $this->_image->_imagick->methodExists('trimImage')) {
-
-           // This determines the color of the underlying shadow.
-           $this->_image->_imagick->setImageBackgroundColor($this->_params['shadowcolor']);
-
-            $result = $this->_image->_imagick->polaroidImage($this->_params['angle']);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-
-            // We need to create a new image to composite the polaroid over.
-            // (yes, even if it's a transparent background evidently)
-            $size = $this->_image->getDimensions();
-            $imk = new Horde_Image_ImagickProxy($size['width'],
-                                                $size['height'],
-                                                $this->_params['background'],
-                                                $this->_image->getType());
-
-            $result = $imk->compositeImage($this->_image->_imagick,
-                                       constant('Imagick::COMPOSITE_OVER'),
-                                       0, 0);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-            $this->_image->_imagick->clear();
-            $this->_image->_imagick->addImage($imk);
-            $imk->destroy();
-
+        // Check for im version > 6.3.2
+        $this->_image->_imagick = null;
+        $ver = $this->_image->getIMVersion();
+        if (is_array($ver) && version_compare($ver[0], '6.3.2') >= 0) {
+            $this->_image->addPostSrcOperation(sprintf("-bordercolor \"#eee\" -background none -polaroid %s \( +clone -fill %s -draw 'color 0,0 reset' \) +swap +flatten",
+                                                          $this->_params['angle'], $this->_params['background']));
         } else {
-
-            // Check for im version > 6.3.2
-            $this->_image->_imagick = null;
-            $ver = $this->_image->getIMVersion();
-            if (is_array($ver) && version_compare($ver[0], '6.3.2') >= 0) {
-                $this->_image->addPostSrcOperation(sprintf("-bordercolor \"#eee\" -background none -polaroid %s \( +clone -fill %s -draw 'color 0,0 reset' \) +swap +flatten",
-                                                              $this->_params['angle'], $this->_params['background']));
-            } else {
-                $size = $this->_image->getDimensions();
-                $this->_image->addPostSrcOperation(sprintf("-bordercolor \"#eee\" -border 8 bordercolor grey90 -border 1 -bordercolor none -background none -rotate %s \( +clone -shadow 60x1.5+1+1 -rotate 90 -wave 1x%s -rotate 90 \) +swap -rotate 90 -wave 1x%s -rotate -90 -flatten \( +clone -fill %s -draw 'color 0,0 reset ' \) +swap -flatten",
-                                                               $this->_params['angle'], $size['height'] * 2, $size['height'] * 2, $this->_params['background']));
-            }
-
-            return true;
+            $size = $this->_image->getDimensions();
+            $this->_image->addPostSrcOperation(sprintf("-bordercolor \"#eee\" -border 8 bordercolor grey90 -border 1 -bordercolor none -background none -rotate %s \( +clone -shadow 60x1.5+1+1 -rotate 90 -wave 1x%s -rotate 90 \) +swap -rotate 90 -wave 1x%s -rotate -90 -flatten \( +clone -fill %s -draw 'color 0,0 reset ' \) +swap -flatten",
+                                                           $this->_params['angle'], $size['height'] * 2, $size['height'] * 2, $this->_params['background']));
         }
+
+        return true;
     }
 
 }
\ No newline at end of file
index c56e7f4..c1b4de0 100644 (file)
@@ -25,79 +25,25 @@ class Horde_Image_Effect_Im_RoundCorners extends Horde_Image_Effect
     {
         /* Use imagick extension if available */
         $round = $this->_params['radius'];
-        // Apparently roundCorners() requires imagick to be compiled against
-        // IM > 6.2.8.
-        if (!is_null($this->_image->_imagick) &&
-            $this->_image->_imagick->methodExists('roundCorners')) {
-            $result = $this->_image->_imagick->roundCorners($round, $round);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
 
-            // Using a border?
-            if ($this->_params['bordercolor'] != 'none' &&
-                $this->_params['border'] > 0) {
+        // Get image dimensions
+        $dimensions = $this->_image->getDimensions();
+        $height = $dimensions['height'];
+        $width = $dimensions['width'];
 
-                $size = $this->_image->getDimensions();
+        $this->_image->addOperation("-size {$width}x{$height} xc:{$this->_params['background']} "
+            . "-fill {$this->_params['background']} -draw \"matte 0,0 reset\" -tile");
 
-                $new = new Horde_Image_ImagickProxy($size['width'] + $this->_params['border'],
-                                                    $size['height'] + $this->_params['border'],
-                                                    $this->_params['bordercolor'],
-                                                    $this->_image->getType());
-
-                $result = $new->roundCorners($round, $round);
-                if (is_a($result, 'PEAR_Error')) {
-                    return $result;
-                }
-                $new->compositeImage($this->_image->_imagick,
-                                     constant('Imagick::COMPOSITE_OVER'), 1, 1);
-                $this->_image->_imagick->clear();
-                $this->_image->_imagick->addImage($new);
-                $new->destroy();
-            }
-
-            // If we have a background other than 'none' we need to
-            // compose two images together to make sure we *have* a background.
-            if ($this->_params['background'] != 'none') {
-                $size = $this->_image->getDimensions();
-                $new = new Horde_Image_ImagickProxy($size['width'],
-                                                    $size['height'],
-                                                    $this->_params['background'],
-                                                    $this->_image->getType());
-
-
-
-                $new->compositeImage($this->_image->_imagick,
-                                     constant('Imagick::COMPOSITE_OVER'), 0, 0);
-                $this->_image->_imagick->clear();
-                $this->_image->_imagick->addImage($new);
-                $new->destroy();
-            }
-        } else {
-            // Get image dimensions
-            $dimensions = $this->_image->getDimensions();
-            $height = $dimensions['height'];
-            $width = $dimensions['width'];
-
-            // Make sure we don't attempt to use Imagick for any other effects
-            // to make sure we do them in the proper order.
-            $this->_image->_imagick = null;
-
-            $this->_image->addOperation("-size {$width}x{$height} xc:{$this->_params['background']} "
-                . "-fill {$this->_params['background']} -draw \"matte 0,0 reset\" -tile");
-
-            $this->_image->roundedRectangle(round($round / 2),
-                                    round($round / 2),
-                                    $width - round($round / 2) - 2,
-                                    $height - round($round / 2) - 2,
-                                    $round + 2,
-                                    'none',
-                                    'white');
-        }
+        $this->_image->roundedRectangle(round($round / 2),
+                                round($round / 2),
+                                $width - round($round / 2) - 2,
+                                $height - round($round / 2) - 2,
+                                $round + 2,
+                                'none',
+                                'white');
 
         // Reset width/height since these might have changed
-        $this->_image->_width = 0;
-        $this->_image->_height = 0;
+        $this->_image->clearGeometry();
 
         return true;
     }
index 7055a6a..b07e9cc 100644 (file)
@@ -45,17 +45,6 @@ class Horde_Image_Im extends Horde_Image
     protected $_postSrcOperations = array();
 
     /**
-     * Reference to an Horde_Image_ImagickProxy object.
-     *
-     * @TODO: This needs to be public since some of the Effects need to
-     *        access this and possibly null it out. This will be resolved
-     *        when Imagick is pulled out into it's own driver.
-     *
-     * @var Imagick
-     */
-    public $_imagick = null;
-
-    /**
      * An array of temporary filenames that need to be unlinked at the end of
      * processing. Use addFileToClean() from client code (Effects) to add files
      * to this array.
@@ -82,86 +71,13 @@ class Horde_Image_Im extends Horde_Image
             throw new InvalidArgumentException('A path to the convert binary is required.');
         }
         $this->_convert = $context['convert'];
-
-        // TODO: Will be breaking out Imagick into it's own driver.
-
-        // Imagick library doesn't play nice with outputting data for 0x0
-        // images, so use 1x1 for our default if needed.
-        if (Util::loadExtension('imagick')) {
-            ini_set('imagick.locale_fix', 1);
-            $this->_width = max(array($this->_width, 1));
-            $this->_height = max(array($this->_height, 1));
-            // Use a proxy for the Imagick calls to keep exception catching
-            // code out of PHP4 compliant code.
-            $this->_imagick = new Horde_Image_ImagickProxy($this->_width,
-                                                           $this->_height,
-                                                           $this->_background,
-                                                           $this->_type);
-            // Yea, it's wasteful to create the proxy (which creates a blank
-            // image) then overwrite it if we're passing in an image, but this
-            // will be fixed in Horde 4 when imagick is broken out into it's own
-            // proper driver.
-            if (!empty($params['filename'])) {
-                $this->loadFile($params['filename']);
-            } elseif(!empty($params['data'])) {
-                $this->loadString(md5($params['data']), $params['data']);
-            } else {
-                $this->_data = $this->_imagick->getImageBlob();
-            }
-
-            $this->_imagick->setImageFormat($this->_type);
+        if (!empty($params['filename'])) {
+            $this->loadFile($params['filename']);
+        } elseif (!empty($params['data'])) {
+            $this->loadString(md5($params['data']), $params['data']);
         } else {
-            if (!empty($params['filename'])) {
-                $this->loadFile($params['filename']);
-            } elseif (!empty($params['data'])) {
-                $this->loadString(md5($params['data']), $params['data']);
-            } else {
-                $cmd = "-size {$this->_width}x{$this->_height} xc:{$this->_background} +profile \"*\" {$this->_type}:__FILEOUT__";
-                $this->executeConvertCmd($cmd);
-            }
-        }
-    }
-
-    /**
-     * Load the image data from a string. Need to override this method
-     * in order to load the imagick object if we need to.
-     *
-     * @TODO: This can be nuked when imagick is broken out.
-     *
-     * @param string $id          An arbitrary id for the image.
-     * @param string $image_data  The data to use for the image.
-     */
-    public function loadString($id, $image_data)
-    {
-        parent::loadString($id, $image_data);
-        if (!is_null($this->_imagick)) {
-            $this->_imagick->clear();
-            $this->_imagick->readImageBlob($image_data);
-            $this->_imagick->setFormat($this->_type);
-            $this->_imagick->setIteratorIndex(0);
-        }
-    }
-
-    /**
-     * Load the image data from a file. Need to override this method
-     * in order to load the imagick object if we need to.
-     *
-     * @TODO: Nuke when imagick is broken out.
-     *
-     * @param string $filename  The full path and filename to the file to load
-     *                          the image data from. The filename will also be
-     *                          used for the image id.
-     *
-     * @return mixed  PEAR Error if file does not exist or could not be loaded
-     *                otherwise NULL if successful or already loaded.
-     */
-    public function loadFile($filename)
-    {
-        parent::loadFile($filename);
-        if (!is_null($this->_imagick)) {
-            $this->_imagick->clear();
-            $this->_imagick->readImageBlob($this->_data);
-            $this->_imagick->setIteratorIndex(0);
+            $cmd = "-size {$this->_width}x{$this->_height} xc:{$this->_background} +profile \"*\" {$this->_type}:__FILEOUT__";
+            $this->executeConvertCmd($cmd);
         }
     }
 
@@ -178,11 +94,6 @@ class Horde_Image_Im extends Horde_Image
      */
     public function raw($convert = false)
     {
-        // Make sure _data is sync'd with imagick object
-        if (!is_null($this->_imagick)) {
-            $this->_data = $this->_imagick->getImageBlob();
-        }
-
         if (!empty($this->_data)) {
             // If there are no operations, and we already have data, don't
             // bother writing out files, just return the current data.
@@ -214,16 +125,7 @@ class Horde_Image_Im extends Horde_Image
 
             /* Load the result */
             $this->_data = file_get_contents($tmpout);
-
-            // Keep imagick object in sync if we need to.
-            // @TODO: Might be able to stop doing this once all operations
-            // are doable through imagick api.
-            if (!is_null($this->_imagick)) {
-                $this->_imagick->clear();
-                $this->_imagick->readImageBlob($this->_data);
-            }
         }
-
         @unlink($tmpin);
         @unlink($tmpout);
 
@@ -238,11 +140,7 @@ class Horde_Image_Im extends Horde_Image
         parent::reset();
         $this->_operations = array();
         $this->_postSrcOperations = array();
-        if (is_object($this->_imagick)) {
-            $this->_imagick->clear();
-        }
-        $this->_width = 0;
-        $this->_height = 0;
+        $this->clearGeometry();
     }
 
     /**
@@ -255,50 +153,20 @@ class Horde_Image_Im extends Horde_Image
      */
     public function resize($width, $height, $ratio = true, $keepProfile = false)
     {
-        if (!is_null($this->_imagick)) {
-            $this->_imagick->thumbnailImage($width, $height, $ratio);
+        $resWidth = $width * 2;
+        $resHeight = $height * 2;
+        $this->_operations[] = "-size {$resWidth}x{$resHeight}";
+        if ($ratio) {
+            $this->_postSrcOperations[] = (($keepProfile) ? "-resize" : "-thumbnail") . " {$width}x{$height}";
         } else {
-            $resWidth = $width * 2;
-            $resHeight = $height * 2;
-            $this->_operations[] = "-size {$resWidth}x{$resHeight}";
-            if ($ratio) {
-                $this->_postSrcOperations[] = (($keepProfile) ? "-resize" : "-thumbnail") . " {$width}x{$height}";
-            } else {
-                $this->_postSrcOperations[] = (($keepProfile) ? "-resize" : "-thumbnail") . " {$width}x{$height}!";
-            }
+            $this->_postSrcOperations[] = (($keepProfile) ? "-resize" : "-thumbnail") . " {$width}x{$height}!";
         }
         // Reset the width and height instance variables since after resize
         // we don't know the *exact* dimensions yet (especially if we maintained
         // aspect ratio.
         // Refresh the data
         $this->raw();
-        $this->_width = 0;
-        $this->_height = 0;
-    }
-
-    /**
-     * More efficient way of getting size if using imagick library.
-     * *ALWAYS* use getDimensions() to get image geometry...instance
-     * variables only cache geometry until it changes, then they go
-     * to zero.
-     *
-     */
-    public function getDimensions()
-    {
-        if (!is_null($this->_imagick)) {
-            if ($this->_height == 0 && $this->_width == 0) {
-                $size = $this->_imagick->getImageGeometry();
-                if (is_a($size, 'PEAR_Error')) {
-                    return $size;
-                }
-                $this->_height = $size['height'];
-                $this->_width = $size['width'];
-            }
-            return array('width' => $this->_width,
-                         'height' => $this->_height);
-        } else {
-            return parent::getDimensions();
-        }
+        $this->clearGeometry();
     }
 
     /**
@@ -311,24 +179,16 @@ class Horde_Image_Im extends Horde_Image
      */
     public function crop($x1, $y1, $x2, $y2)
     {
-        if (!is_null($this->_imagick)) {
-            $result = $this->_imagick->cropImage($x2 - $x1, $y2 - $y1, $x1, $y1);
-            $this->_imagick->setImagePage(0, 0, 0, 0);
-        } else {
-            $line = ($x2 - $x1) . 'x' . ($y2 - $y1) . '+' . $x1 . '+' . $y1;
-            $this->_operations[] = '-crop ' . $line . ' +repage';
-            $result = true;
-        }
+        $line = ($x2 - $x1) . 'x' . ($y2 - $y1) . '+' . $x1 . '+' . $y1;
+        $this->_operations[] = '-crop ' . $line . ' +repage';
+
         // Reset width/height since these might change
         $this->raw();
-        $this->_width = 0;
-        $this->_height = 0;
-
-        return $result;
+        $this->clearGeometry();
     }
 
     /**
-     * Rotate the current image.
+     * Rotate the current image. This is an atomic operation.
      *
      * @param integer $angle       The angle to rotate the image by,
      *                             in the clockwise direction.
@@ -336,16 +196,12 @@ class Horde_Image_Im extends Horde_Image
      */
     public function rotate($angle, $background = 'white')
     {
-        if (!is_null($this->_imagick)) {
-            return $this->_imagick->rotateImage($background, $angle);
-        } else {
-            $this->raw();
-            $this->_operations[] = "-background $background -rotate {$angle}";
-            $this->raw();
-        }
+        $this->raw();
+        $this->_operations[] = "-background $background -rotate {$angle}";
+        $this->raw();
+
         // Reset width/height since these might have changed
-        $this->_width = 0;
-        $this->_height = 0;
+        $this->clearGeometry();
     }
 
     /**
@@ -353,11 +209,7 @@ class Horde_Image_Im extends Horde_Image
      */
     public function flip()
     {
-        if (!is_null($this->_imagick)) {
-            $this->_imagick->flipImage();
-        } else {
-            $this->_operations[] = '-flip';
-        }
+        $this->_operations[] = '-flip';
     }
 
     /**
@@ -365,11 +217,7 @@ class Horde_Image_Im extends Horde_Image
      */
     public function mirror()
     {
-        if (!is_null($this->_imagick)) {
-            $this->_imagick->flopImage();
-        } else {
-            $this->_operations[] = '-flop';
-        }
+        $this->_operations[] = '-flop';
     }
 
     /**
@@ -377,11 +225,7 @@ class Horde_Image_Im extends Horde_Image
      */
     public function grayscale()
     {
-        if (!is_null($this->_imagick)) {
-            $this->_imagick->setImageColorSpace(constant('Imagick::COLORSPACE_GRAY'));
-        } else {
-            $this->_postSrcOperations[] = '-colorspace GRAY';
-        }
+        $this->_postSrcOperations[] = '-colorspace GRAY';
     }
 
     /**
@@ -391,14 +235,10 @@ class Horde_Image_Im extends Horde_Image
      */
     public function sepia($threshold =  85)
     {
-        if (!is_null($this->_imagick)) {
-            $this->_imagick->sepiaToneImage($threshold);
-        } else {
-            $this->_operations[] = '-sepia-tone ' . $threshold . '%';
-        }
+        $this->_operations[] = '-sepia-tone ' . $threshold . '%';
     }
 
-     /**
+    /**
      * Draws a text string on the image in a specified location, with
      * the specified style information.
      *
@@ -415,15 +255,9 @@ class Horde_Image_Im extends Horde_Image
      */
     public function text($string, $x, $y, $font = '', $color = 'black', $direction = 0, $fontsize = 'small')
     {
-        if (!is_null($this->_imagick)) {
-            $fontsize = self::getFontSize($fontsize);
-
-            return $this->_imagick->text($string, $x, $y, $font, $color, $direction, $fontsize);
-        } else {
-            $string = addslashes('"' . $string . '"');
-            $fontsize = self::getFontSize($fontsize);
-            $this->_postSrcOperations[] = "-fill $color " . (!empty($font) ? "-font $font" : '') . " -pointsize $fontsize -gravity northwest -draw \"text $x,$y $string\" -fill none";
-        }
+        $string = addslashes('"' . $string . '"');
+        $fontsize = self::getFontSize($fontsize);
+        $this->_postSrcOperations[] = "-fill $color " . (!empty($font) ? "-font $font" : '') . " -pointsize $fontsize -gravity northwest -draw \"text $x,$y $string\" -fill none";
     }
 
     /**
@@ -437,12 +271,8 @@ class Horde_Image_Im extends Horde_Image
      */
     public function circle($x, $y, $r, $color, $fill = 'none')
     {
-        if (!is_null($this->_imagick)) {
-            return $this->_imagick->circle($x, $y, $r, $color, $fill);
-        } else {
-            $xMax = $x + $r;
-            $this->_postSrcOperations[] = "-stroke $color -fill $fill -draw \"circle $x,$y $xMax,$y\" -stroke none -fill none";
-        }
+        $xMax = $x + $r;
+        $this->_postSrcOperations[] = "-stroke $color -fill $fill -draw \"circle $x,$y $xMax,$y\" -stroke none -fill none";
     }
 
     /**
@@ -455,17 +285,11 @@ class Horde_Image_Im extends Horde_Image
      */
     public function polygon($verts, $color, $fill = 'none')
     {
-        // TODO: For now, use only convert since ::polygon is called from other
-        // methods that are convert-only for now.
-        //if (!is_null($this->_imagick)) {
-            //return $this->_imagick->polygon($verts, $color, $fill);
-        //} else {
-            $command = '';
-            foreach ($verts as $vert) {
-                $command .= sprintf(' %d,%d', $vert['x'], $vert['y']);
-            }
-            $this->_postSrcOperations[] = "-stroke $color -fill $fill -draw \"polygon $command\" -stroke none -fill none";
-        //}
+        $command = '';
+        foreach ($verts as $vert) {
+            $command .= sprintf(' %d,%d', $vert['x'], $vert['y']);
+        }
+        $this->_postSrcOperations[] = "-stroke $color -fill $fill -draw \"polygon $command\" -stroke none -fill none";
     }
 
     /**
@@ -480,13 +304,9 @@ class Horde_Image_Im extends Horde_Image
      */
     public function rectangle($x, $y, $width, $height, $color, $fill = 'none')
     {
-        if (!is_null($this->_imagick)) {
-            $this->_imagick->rectangle($x, $y, $width, $height, $color, $fill);
-        } else {
-            $xMax = $x + $width;
-            $yMax = $y + $height;
-            $this->_postSrcOperations[] = "-stroke $color -fill $fill -draw \"rectangle $x,$y $xMax,$yMax\" -stroke none -fill none";
-        }
+        $xMax = $x + $width;
+        $yMax = $y + $height;
+        $this->_postSrcOperations[] = "-stroke $color -fill $fill -draw \"rectangle $x,$y $xMax,$yMax\" -stroke none -fill none";
     }
 
     /**
@@ -502,14 +322,9 @@ class Horde_Image_Im extends Horde_Image
      */
     public function roundedRectangle($x, $y, $width, $height, $round, $color, $fill)
     {
-        if (!is_null($this->_imagick)) {
-            $this->_imagick->roundedRectangle($x, $y, $width, $height, $round, $color, $fill);
-        } else {
-            $x1 = $x + $width;
-            $y1 = $y + $height;
-            $this->_postSrcOperations[] = "-stroke $color -fill $fill -draw \"roundRectangle $x,$y $x1,$y1 $round,$round\" -stroke none -fill none";
-
-        }
+        $x1 = $x + $width;
+        $y1 = $y + $height;
+        $this->_postSrcOperations[] = "-stroke $color -fill $fill -draw \"roundRectangle $x,$y $x1,$y1 $round,$round\" -stroke none -fill none";
     }
 
     /**
@@ -524,11 +339,7 @@ class Horde_Image_Im extends Horde_Image
      */
     public function line($x0, $y0, $x1, $y1, $color = 'black', $width = 1)
     {
-        if (!is_null($this->_imagick)) {
-            return $this->_imagick->line($x0, $y0, $x1, $y1, $color, $width);
-        } else {
-            $this->_operations[] = "-stroke $color -strokewidth $width -draw \"line $x0,$y0 $x1,$y1\"";
-        }
+        $this->_operations[] = "-stroke $color -strokewidth $width -draw \"line $x0,$y0 $x1,$y1\"";
     }
 
     /**
@@ -545,13 +356,7 @@ class Horde_Image_Im extends Horde_Image
      */
     public function dashedLine($x0, $y0, $x1, $y1, $color = 'black', $width = 1, $dash_length = 2, $dash_space = 2)
     {
-        if (!is_null($this->_imagick)) {
-            return $this->_imagick->dashedLine($x0, $y0, $x1, $y1, $color,
-                                               $width, $dash_length,
-                                               $dash_space);
-        } else {
-            $this->_operations[] = "-stroke $color -strokewidth $width -draw \"line $x0,$y0 $x1,$y1\"";
-        }
+       $this->_operations[] = "-stroke $color -strokewidth $width -draw \"line $x0,$y0 $x1,$y1\"";
     }
 
     /**
@@ -565,15 +370,11 @@ class Horde_Image_Im extends Horde_Image
      */
     public function polyline($verts, $color, $width = 1)
     {
-        if (!is_null($this->_imagick)) {
-            return $this->_imagick->polyline($verts, $color, $width);
-        } else {
-            $command = '';
-            foreach ($verts as $vert) {
-                $command .= sprintf(' %d,%d', $vert['x'], $vert['y']);
-            }
-            $this->_operations[] = "-stroke $color -strokewidth $width -fill none -draw \"polyline $command\" -strokewidth 1 -stroke none -fill none";
+        $command = '';
+        foreach ($verts as $vert) {
+            $command .= sprintf(' %d,%d', $vert['x'], $vert['y']);
         }
+        $this->_operations[] = "-stroke $color -strokewidth $width -fill none -draw \"polyline $command\" -strokewidth 1 -stroke none -fill none";
     }
 
     /**
@@ -703,13 +504,8 @@ class Horde_Image_Im extends Horde_Image
     {
         static $version = null;
         if (!is_array($version)) {
-            if (!is_null($this->_imagick)) {
-                $output = $this->_imagick->getVersion();
-                $output[0] = $output['versionString'];
-            } else {
-                $commandline = $this->_convert . ' --version';
-                exec($commandline, $output, $retval);
-            }
+            $commandline = $this->_convert . ' --version';
+            exec($commandline, $output, $retval);
             if (preg_match('/([0-9])\.([0-9])\.([0-9])/', $output[0], $matches)) {
                 $version = $matches;
                 return $matches;
@@ -717,6 +513,7 @@ class Horde_Image_Im extends Horde_Image
                return false;
             }
         }
+
         return $version;
     }