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