Experimental support for liquid image resizing in Horde_Image.
authorMichael J. Rubinsky <mrubinsk@horde.org>
Sun, 26 Sep 2010 19:44:42 +0000 (15:44 -0400)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Sun, 26 Sep 2010 19:44:42 +0000 (15:44 -0400)
I think for Ansel, though, something based on a "center of edginess" technique might be better.

framework/Image/lib/Horde/Image/Effect/Im/LiquidResize.php [new file with mode: 0644]
framework/Image/lib/Horde/Image/Effect/Imagick/LiquidResize.php [new file with mode: 0644]
framework/Image/lib/Horde/Image/Im.php
framework/Image/lib/Horde/Image/Imagick.php
framework/Image/package.xml
framework/Image/tests/im.php
framework/Image/tests/img4.jpg [new file with mode: 0644]
framework/Image/tests/runtest.php

diff --git a/framework/Image/lib/Horde/Image/Effect/Im/LiquidResize.php b/framework/Image/lib/Horde/Image/Effect/Im/LiquidResize.php
new file mode 100644 (file)
index 0000000..0d77fc7
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Image effect for applying content aware image resizing.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author  Michael J. Rubinsky <mrubinsk@horde.org>
+ * @package Horde_Image
+ */
+class Horde_Image_Effect_Im_LiquidResize extends Horde_Image_Effect
+{
+    /**
+     * Valid parameters:
+     *  <pre>
+     *    width       - The target width
+     *    height      - the target height
+     *    ratio       - Keep aspect ratio
+     * </pre>
+     *
+     * @var array
+     */
+    protected $_params = array();
+
+    public function apply()
+    {
+        $this->_params = new Horde_Support_Array($this->_params);
+
+        $resWidth = $this->_params->width * 2;
+        $resHeight = $this->_params->height * 2;
+
+        $this->_image->addOperation("-size {$resWidth}x{$resHeight}");
+        if ($this->_params->get('ratio', true)) {
+            $this->_image->addPostSrcOperation('-liquid-rescale' . " {$this->_params->width}x{$this->_params->height}");
+        } else {
+            $this->_image->addPostSrcOperations('-liquid-rescale' . " {$this->_params->width}x{$this->_params->height}!");
+        }
+        $this->_image->clearGeometry();
+    }
+
+}
\ No newline at end of file
diff --git a/framework/Image/lib/Horde/Image/Effect/Imagick/LiquidResize.php b/framework/Image/lib/Horde/Image/Effect/Imagick/LiquidResize.php
new file mode 100644 (file)
index 0000000..6227c3e
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Image effect for applying content aware image resizing.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author  Michael J. Rubinsky <mrubinsk@horde.org>
+ * @package Horde_Image
+ */
+class Horde_Image_Effect_Imagick_LiquidResize extends Horde_Image_Effect
+{
+    /**
+     *
+     * Valid parameters:
+     *  <pre>
+     *    width       - The target width
+     *    height      - the target height
+     *    delta_x     - How much the seam may move on x axis (A value of 0
+     *                  causes the seam to be straight).
+     *   rigidity     - Introduces a bias for non-straight seams. Typically zero
+     * </pre>
+     *
+     * @var array
+     */
+    protected $_params = array();
+
+    public function apply()
+    {
+        $this->_params = new Horde_Support_Array($this->_params);
+        try {
+            $this->_image->imagick->liquidRescaleImage(
+                $this->_params->width, $this->_params->height, $this->_params->delta_x, $this->_params['rigidity']);
+        } catch (ImagickException $e) {
+            throw new Horde_Image_Exception($e);
+        }
+    }
+
+}
\ No newline at end of file
index 5d3575a..563277b 100644 (file)
@@ -298,7 +298,7 @@ class Horde_Image_Im extends Horde_Image_Base
     public function text($string, $x, $y, $font = '', $color = 'black', $direction = 0, $fontsize = 'small')
     {
         $string = addslashes('"' . $string . '"');
-        $fontsize = self::getFontSize($fontsize);
+        $fontsize = Horde_Image::getFontSize($fontsize);
         $this->_postSrcOperations[] = "-fill $color " . (!empty($font) ? "-font $font" : '') . " -pointsize $fontsize -gravity northwest -draw \"text $x,$y $string\" -fill none";
     }
 
index 549bed3..3df072f 100644 (file)
@@ -312,7 +312,7 @@ class Horde_Image_Imagick extends Horde_Image_Base
      */
     public function text($string, $x, $y, $font = '', $color = 'black', $direction = 0, $fontsize = 'small')
     {
-        $fontsize = self::getFontSize($fontsize);
+        $fontsize = Horde_Image::getFontSize($fontsize);
         $pixel = new ImagickPixel($color);
         $draw = new ImagickDraw();
         $draw->setFillColor($pixel);
index 046acfc..c890172 100644 (file)
@@ -58,6 +58,7 @@ Initial Horde 4 package
         <file name="RoundCorners.php" role="php" />
         <file name="TextWatermark.php" role="php" />
         <file name="Unsharpmask.php" role="php" />
+        <file name="LiquidResize.php" role="php" />
        </dir> <!-- /lib/Horde/Image/Effect/Im -->
        <dir name="Imagick">
         <file name="Border.php" role="php" />
@@ -68,6 +69,7 @@ Initial Horde 4 package
         <file name="RoundCorners.php" role="php" />
         <file name="TextWatermark.php" role="php" />
         <file name="Unsharpmask.php" role="php" />
+        <file name="LiquidResize.php" role="php" />
        </dir> <!-- /lib/Horde/Image/Effect/Imagick -->
        <file name="Border.php" role="php" />
       </dir> <!-- /lib/Horde/Image/Effect -->
@@ -162,6 +164,7 @@ Initial Horde 4 package
    <install as="Horde/Image/Effect/Im/RoundCorners.php" name="lib/Horde/Image/Effect/Im/RoundCorners.php" />
    <install as="Horde/Image/Effect/Im/TextWatermark.php" name="lib/Horde/Image/Effect/Im/TextWatermark.php" />
    <install as="Horde/Image/Effect/Im/Unsharpmask.php" name="lib/Horde/Image/Effect/Im/Unsharpmask.php" />
+   <install as="Horde/Image/Effect/Im/LiquidResize.php" name="lib/Horde/Image/Effect/Im/LiquidResize.php" />
    <install as="Horde/Image/Effect/Imagick/Border.php" name="lib/Horde/Image/Effect/Imagick/Border.php" />
    <install as="Horde/Image/Effect/Imagick/Composite.php" name="lib/Horde/Image/Effect/Imagick/Composite.php" />
    <install as="Horde/Image/Effect/Imagick/DropShadow.php" name="lib/Horde/Image/Effect/Imagick/DropShadow.php" />
@@ -170,6 +173,7 @@ Initial Horde 4 package
    <install as="Horde/Image/Effect/Imagick/RoundCorners.php" name="lib/Horde/Image/Effect/Imagick/RoundCorners.php" />
    <install as="Horde/Image/Effect/Imagick/TextWatermark.php" name="lib/Horde/Image/Effect/Imagick/TextWatermark.php" />
    <install as="Horde/Image/Effect/Imagick/Unsharpmask.php" name="lib/Horde/Image/Effect/Imagick/Unsharpmask.php" />
+   <install as="Horde/Image/Effect/Imagick/LiquidResize.php" name="lib/Horde/Image/Effect/Imagick/LiquidResize.php" />
    <install as="Horde/Image/Exif/Base.php" name="lib/Horde/Image/Exif/Base.php" />
    <install as="Horde/Image/Exif/Bundled.php" name="lib/Horde/Image/Exif/Bundled.php" />
    <install as="Horde/Image/Exif/Exiftool.php" name="lib/Horde/Image/Exif/Exiftool.php" />
index ab10125..20a3dd3 100644 (file)
@@ -8,7 +8,7 @@
  * @package Horde_Image
  */
 
-require_once dirname(__FILE__) . '/../../../horde/lib/Application.php';
+require_once dirname(__FILE__) . '/../lib/Application.php';
 Horde_Registry::appInit('horde', array('authentication' => 'none'));
 
 // Putting these here so they don't interfere with timing/memory data when
@@ -21,6 +21,12 @@ $handler = new Horde_Log_Handler_Stream(fopen('/tmp/imagetest.log','a+'));
 $logger = new Horde_Log_Logger($handler);
 
 switch ($test) {
+case 'liquid':
+    $time = xdebug_time_index();
+    $image = getImageObject(array('filename' => 'img4.jpg'));
+    $image->addEffect('LiquidResize', array('ratio' => true, 'width' => 612, 'height' => 340, 'delta_x' => 3, 'rigidity' => 0));
+    $image->display();
+    break;
 
 case 'multipage':
     $time = xdebug_time_index();
diff --git a/framework/Image/tests/img4.jpg b/framework/Image/tests/img4.jpg
new file mode 100644 (file)
index 0000000..683358a
Binary files /dev/null and b/framework/Image/tests/img4.jpg differ
index e9cb656..169b8de 100644 (file)
@@ -3,7 +3,7 @@
  * Test harness for generating the test images for Horde_Image tests
  */
 
-require_once dirname(__FILE__) . '/../../../horde/lib/Application.php';
+require_once dirname(__FILE__) . '/../lib/Application.php';
 Horde_Registry::appInit('horde', array('authentication' => 'none'));
 
 $allTests = array(
@@ -31,9 +31,10 @@ $allTests = array(
     'testRoundstackBlueBG' => 'Thumbnail stack, rounded corners on a blue background',
     'testPolaroidstackTransparentBG' => 'Polaroid stack on a transparent background.',
     'testPolaroidstackBlueBG' => 'Polaroid stack on a blue background',
-    //'testInitialStateAfterLoad' => 'Initial state after loading an existing image.',
+    'testInitialStateAfterLoad' => 'Initial state after loading an existing image.',
     'testResize' => 'Test resize method.',
     'multipage' => 'Test Multipage tiffs',
+    'liquid' => 'Test Seam Carving',
 );
 ?>
 <html>
@@ -44,9 +45,10 @@ $allTests = array(
 <table width="50%">
  <thead><td>Effect</td><td>Im</td><td>Imagick</td></thead>
 <?php
+$url = new Horde_Url('im.php');
 foreach ($allTests as $name => $description) {
-    echo '<tr><td text-align="top">' . $description . '</td><td>' . Horde::img('im.php?test=' . $name, '', '', '') . '</td>' .
-    '<td text-align="top">' . Horde::img('im.php?test=' . $name . '&driver=Imagick', '', '', '') . '</td></tr>';
+    echo '<tr><td text-align="top">' . $description . '</td><td><img src="' . $url->copy()->add('test', $name) . '" /></td>' .
+    '<td text-align="top"><img src="' . $url->copy()->add(array('test' => $name, 'driver' => 'Imagick')) . '" /></td></tr>';
 }
 echo '</table>';
 ?></body></html>