http://www.mediawiki.org/wiki/Special:Code/MediaWiki/83778

Revision: 83778
Author:   btongminh
Date:     2011-03-12 19:32:39 +0000 (Sat, 12 Mar 2011)
Log Message:
-----------
(bug 14706) Added support for the Imagick PHP extension. Based on patch by 
Leslie Hoare. 
Scaler type is "imext". Rotation is supported.
Logic mostly copied from transformImagemagick() and ported to Imagick calls.
Resizing animated gifs is broken; it only shows the first frame and I can't 
find out why it does not work, but otherwise it is fully working.

Modified Paths:
--------------
    trunk/phase3/CREDITS
    trunk/phase3/RELEASE-NOTES
    trunk/phase3/includes/media/Bitmap.php

Modified: trunk/phase3/CREDITS
===================================================================
--- trunk/phase3/CREDITS        2011-03-12 18:51:51 UTC (rev 83777)
+++ trunk/phase3/CREDITS        2011-03-12 19:32:39 UTC (rev 83778)
@@ -34,6 +34,7 @@
 * Jon Harald Søby
 * Juliano F. Ravasi
 * Leon Weber
+* Leslie Hoare
 * Marco Schuster
 * Matěj Grabovský
 * Matt Johnston

Modified: trunk/phase3/RELEASE-NOTES
===================================================================
--- trunk/phase3/RELEASE-NOTES  2011-03-12 18:51:51 UTC (rev 83777)
+++ trunk/phase3/RELEASE-NOTES  2011-03-12 19:32:39 UTC (rev 83778)
@@ -102,6 +102,7 @@
   several wikis.
 * When $wgAllowMicrodataAttributes is true, all itemtypes are allowed, not just
   the three that were defined in the original specification.
+* (bug 14706) Added support for the Imagick PHP extension.
 
 === Bug fixes in 1.18 ===
 * (bug 23119) WikiError class and subclasses are now marked as deprecated

Modified: trunk/phase3/includes/media/Bitmap.php
===================================================================
--- trunk/phase3/includes/media/Bitmap.php      2011-03-12 18:51:51 UTC (rev 
83777)
+++ trunk/phase3/includes/media/Bitmap.php      2011-03-12 19:32:39 UTC (rev 
83778)
@@ -143,6 +143,8 @@
                        case 'custom':
                                $err = $this->transformCustom( $image, 
$scalerParams );
                                break;
+                       case 'imext':
+                               $err = $this->transformImageMagickExt( $image, 
$scalerParams );
                        case 'gd':
                        default:
                                $err = $this->transformGd( $image, 
$scalerParams );
@@ -184,6 +186,8 @@
                        $scaler = 'custom';
                } elseif ( function_exists( 'imagecreatetruecolor' ) ) {
                        $scaler = 'gd';
+               } elseif ( class_exists( 'Imagick' ) ) {
+                       $scaler = 'imext';
                } else {
                        $scaler = 'client';
                }
@@ -209,7 +213,7 @@
                return new ThumbnailImage( $image, $image->getURL(),
                                $params['clientWidth'], 
$params['clientHeight'], $params['srcPath'] );
        }
-
+       
        /**
         * Transform an image using ImageMagick
         *
@@ -301,7 +305,92 @@
 
                return false; # No error
        }
+       
+       /**
+        * Transform an image using the Imagick PHP extension
+        * 
+        * @param $image File File associated with this thumbnail
+        * @param $params array Array with scaler params
+        *
+        * @return MediaTransformError Error object if error occured, false 
(=no error) otherwise
+        */
+       protected function transformImageMagickExt( $image, $params ) {
+               global $wgSharpenReductionThreshold, $wgSharpenParameter, 
$wgMaxAnimatedGifArea;
+               
+               try {
+                       $im = new Imagick();
+                       $im->readImage( $params['srcPath'] );
+       
+                       if ( $params['mimeType'] == 'image/jpeg' ) {
+                               // Sharpening, see bug 6193
+                               if ( ( $params['physicalWidth'] + 
$params['physicalHeight'] )
+                                               / ( $params['srcWidth'] + 
$params['srcHeight'] )
+                                               < $wgSharpenReductionThreshold 
) {
+                                       // Hack, since $wgSharpenParamater is 
written specifically for the command line convert
+                                       list( $radius, $sigma ) = explode( 'x', 
$wgSharpenParameter );
+                                       $im->sharpenImage( $radius, $sigma );
+                               }
+                               $im->setCompressionQuality( 80 );
+                       } elseif( $params['mimeType'] == 'image/png' ) {
+                               $im->setCompressionQuality( 95 );
+                       } elseif ( $params['mimeType'] == 'image/gif' ) {
+                               if ( $this->getImageArea( $image, 
$params['srcWidth'],
+                                               $params['srcHeight'] ) > 
$wgMaxAnimatedGifArea ) {
+                                       // Extract initial frame only; we're so 
big it'll
+                                       // be a total drag. :P
+                                       $im->setImageScene( 0 );
+                               } elseif ( $this->isAnimatedImage( $image ) ) {
+                                       // Coalesce is needed to scale animated 
GIFs properly (bug 1017).
+                                       $im = $im->coalesceImages();
+                               }
+                       }
+                       
+                       $rotation = $this->getRotation( $image );
+                       if ( $rotation == 90 || $rotation == 270 ) {
+                               // We'll resize before rotation, so swap the 
dimensions again
+                               $width = $params['physicalHeight'];
+                               $height = $params['physicalWidth'];
+                       } else {
+                               $width = $params['physicalWidth'];
+                               $height = $params['physicalHeight'];            
        
+                       }
+                       
+                       $im->setImageBackgroundColor( new ImagickPixel( 'white' 
) );
+                       
+                       // Call Imagick::thumbnailImage on each frame
+                       foreach ( $im as $i => $frame ) {
+                               if ( !$frame->thumbnailImage( $width, $height, 
/* fit */ false ) ) {
+                                       return $this->getMediaTransformError( 
$params, "Error scaling frame $i" );
+                               }
+                       }
+                       $im->setImageDepth( 8 );
+                       
+                       if ( $rotation ) {
+                               if ( !$im->rotateImage( new ImagickPixel( 
'white' ), $rotation ) ) {
+                                       return $this->getMediaTransformError( 
$params, "Error rotating $rotation degrees" );
+                               }
+                       }
+       
+                       if ( $this->isAnimatedImage( $image ) ) {
+                               wfDebug( __METHOD__ . ": Writing animated 
thumbnail\n" );
+                               // This is broken somehow... can't find out how 
to fix it
+                               $result = $im->writeImages( $params['dstPath'], 
true );
+                       } else {
+                               $result = $im->writeImage( $params['dstPath'] );
+                       }
+                       if ( !$result ) {
+                               return $this->getMediaTransformError( $params, 
+                                       "Unable to write thumbnail to 
{$params['dstPath']}" );
+                       }
 
+               } catch ( ImagickException $e ) {
+                       return $this->getMediaTransformError( $params, 
$e->getMessage() ); 
+               }
+               
+               return false;
+               
+       }
+
        /**
         * Transform an image using a custom command
         *
@@ -703,6 +792,9 @@
                        case 'im':
                                # ImageMagick supports autorotation
                                return true;
+                       case 'imext':
+                               # Imagick::rotateImage
+                               return true;
                        case 'gd':
                                # GD's imagerotate function is used to rotate 
images, but not
                                # all precompiled PHP versions have that 
function


_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to