WordPress.org

Make WordPress Core

Ticket #28474: 28474.diff

File 28474.diff, 5.9 KB (added by mikeschroder, 6 years ago)

Rough First Pass. Partially works. This does not check for all necessary functions existing, and doesn't seem to always thumbnail correctly.

  • src/wp-includes/class-wp-image-editor-imagick.php

    diff --git src/wp-includes/class-wp-image-editor-imagick.php src/wp-includes/class-wp-image-editor-imagick.php
    index a14fa40..fb49ef7 100644
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    2323         */
    2424        protected $image;
    2525
     26        /**
     27         * Whether this is an animated image.
     28         *
     29         * @access protected
     30         * @var bool
     31         */
     32        protected $animated = false;
     33
    2634        public function __destruct() {
    2735                if ( $this->image instanceof Imagick ) {
    2836                        // we don't need the original in memory anymore
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    6371                        'getimageblob',
    6472                        'getimagegeometry',
    6573                        'getimageformat',
     74                        'getimageiterations',
    6675                        'setimageformat',
    6776                        'setimagecompression',
    6877                        'setimagecompressionquality',
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    139148                        if ( ! $this->image->valid() )
    140149                                return new WP_Error( 'invalid_image', __('File is not an image.'), $this->file);
    141150
     151                        // We need to check to see if image is animated before we set the index, or else it returns false.
     152                        // For animation to be supported, also getImageBlob, writeImages, coalesceImages and optimizeImageLayers are required.
     153                        // While coalesceImages seems to be supported far back, optimizeImageLayers is not.
     154                        $this->animated = $this->image->getImageIterations();
     155
    142156                        // Select the first frame to handle animated images properly
    143157                        if ( is_callable( array( $this->image, 'setIteratorIndex' ) ) )
    144158                                $this->image->setIteratorIndex(0);
    145159
    146160                        $this->mime_type = $this->get_mime_type( $this->image->getImageFormat() );
     161
    147162                }
    148163                catch ( Exception $e ) {
    149164                        return new WP_Error( 'invalid_image', $e->getMessage(), $this->file );
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    250265                }
    251266
    252267                try {
    253                         /**
    254                          * @TODO: Thumbnail is more efficient, given a newer version of Imagemagick.
    255                          * $this->image->thumbnailImage( $dst_w, $dst_h );
    256                          */
    257                         $this->image->scaleImage( $dst_w, $dst_h );
     268                        if ( $this->animated ) {
     269                                $this->image->coalesceImages();
     270                        }
     271
     272                        foreach ($this->image as $frame) {
     273                                /**
     274                                 * @TODO: Thumbnail is more efficient, given a newer version of Imagemagick.
     275                                 * $this->image->thumbnailImage( $dst_w, $dst_h );
     276                                 */
     277                                $frame->scaleImage( $dst_w, $dst_h );
     278                        }
     279
     280                        # $this->deconstructImages(); or $this->optimizeImageLayers();
     281                        if ( $this->animated ) {
     282                                $this->image->optimizeImageLayers();
     283                        }
    258284                }
    259285                catch ( Exception $e ) {
    260286                        return new WP_Error( 'image_resize_error', $e->getMessage() );
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    356382                }
    357383
    358384                try {
    359                         $this->image->cropImage( $src_w, $src_h, $src_x, $src_y );
    360                         $this->image->setImagePage( $src_w, $src_h, 0, 0);
     385                        if ( $this->animated ) {
     386                                $this->image->coalesceImages();
     387                        }
     388
     389                        foreach ($this->image as $frame) {
     390                                $frame->cropImage( $src_w, $src_h, $src_x, $src_y );
     391                                $frame->setImagePage( $src_w, $src_h, 0, 0);
    361392
    362                         if ( $dst_w || $dst_h ) {
    363                                 // If destination width/height isn't specified, use same as
    364                                 // width/height from source.
    365                                 if ( ! $dst_w )
     393                                if ( $dst_w || $dst_h ) {
     394                                        // If destination width/height isn't specified, use same as
     395                                        // width/height from source.
     396                                        if ( ! $dst_w )
    366397                                        $dst_w = $src_w;
    367                                 if ( ! $dst_h )
    368                                         $dst_h = $src_h;
     398                                        if ( ! $dst_h )
     399                                                $dst_h = $src_h;
    369400
    370                                 $this->image->scaleImage( $dst_w, $dst_h );
    371                                 return $this->update_size();
     401                                        $frame->scaleImage( $dst_w, $dst_h );
     402                                }
     403                        }
     404
     405                        if ( $this->animated ) {
     406                                $this->image->optimizeImageLayers();
    372407                        }
    373408                }
    374409                catch ( Exception $e ) {
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    392427                 * (GD rotates counter-clockwise)
    393428                 */
    394429                try {
    395                         $this->image->rotateImage( new ImagickPixel('none'), 360-$angle );
     430                        if ( $this->animated ) {
     431                                $this->image->coalesceImages();
     432                        }
     433
     434                        foreach ($this->image as $frame) {
     435                                $frame->rotateImage( new ImagickPixel('none'), 360-$angle );
     436                        }
     437
     438                        if ( $this->animated ) {
     439                                $this->image->optimizeImageLayers();
     440                        }
    396441
    397442                        // Since this changes the dimensions of the image, update the size.
    398443                        $result = $this->update_size();
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    419464         */
    420465        public function flip( $horz, $vert ) {
    421466                try {
    422                         if ( $horz )
    423                                 $this->image->flipImage();
     467                        if ( $this->animated ) {
     468                                $this->image->coalesceImages();
     469                        }
     470
     471                        foreach ($this->image as $frame) {
     472                                if ( $horz )
     473                                        $frame->flipImage();
    424474
    425                         if ( $vert )
    426                                 $this->image->flopImage();
     475                                if ( $vert )
     476                                        $frame->flopImage();
     477                        }
     478
     479                        if ( $this->animated ) {
     480                                $this->image->optimizeImageLayers();
     481                        }
    427482                }
    428483                catch ( Exception $e ) {
    429484                        return new WP_Error( 'image_flip_error', $e->getMessage() );
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    477532                        $orig_format = $this->image->getImageFormat();
    478533
    479534                        $this->image->setImageFormat( strtoupper( $this->get_extension( $mime_type ) ) );
    480                         $this->make_image( $filename, array( $image, 'writeImage' ), array( $filename ) );
     535
     536                        if ( $this->animated ) {
     537                                $this->make_image( $filename, array( $image, 'writeImages' ), array( $filename, true ) );
     538                        } else {
     539                                $this->make_image( $filename, array( $image, 'writeImage' ), array( $filename ) );
     540                        }
    481541
    482542                        // Reset original Format
    483543                        $this->image->setImageFormat( $orig_format );
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    519579
    520580                        // Output stream of image content
    521581                        header( "Content-Type: $mime_type" );
    522                         print $this->image->getImageBlob();
     582
     583                        if ( $this->animated ) {
     584                                print $this->image->getImagesBlob();
     585                        } else {
     586                                print $this->image->getImageBlob();
     587                        }
    523588
    524589                        // Reset Image to original Format
    525590                        $this->image->setImageFormat( $this->get_extension( $this->mime_type ) );