Ticket #28474: 28474.2.diff
File 28474.2.diff, 7.0 KB (added by , 9 years ago) |
---|
-
src/wp-includes/class-wp-image-editor-gd.php
486 486 487 487 return parent::make_image( $filename, $function, $arguments ); 488 488 } 489 490 public function is_animated() { 491 if ( null === $this->animated ) { 492 if ( 'image/jpg' === $this->mime_type ) { 493 $this->animated = false; 494 } 495 else if ( ! ( $fh = @fopen( $this->file, 'rb' ) ) ) { 496 $this->animated = false; 497 } 498 else { 499 $count = 0; 500 //an animated gif contains multiple "frames", with each frame having a 501 //header made up of: 502 // * a static 4-byte sequence (\x00\x21\xF9\x04) 503 // * 4 variable bytes 504 // * a static 2-byte sequence (\x00\x2C) 505 506 // We read through the file til we reach the end of the file, or we've found 507 // at least 2 frame headers 508 while( ! feof($fh) && $count < 2 ) { 509 $chunk = fread( $fh, 1024 * 100 ); //read 100kb at a time 510 $count += preg_match_all( '#\x00\x21\xF9\x04.{4}\x00[\x2C\x21]#s', $chunk, $matches ); 511 } 512 513 fclose($fh); 514 515 $this->animated = $count > 1; 516 } 517 } 518 519 return $this->animated; 520 } 521 489 522 } -
src/wp-includes/class-wp-image-editor-imagick.php
139 139 if ( ! $this->image->valid() ) 140 140 return new WP_Error( 'invalid_image', __('File is not an image.'), $this->file); 141 141 142 // We need to check to see if image is animated before we set the index, or else it returns false. 143 // For animation to be supported, also getImageBlob, writeImages, coalesceImages and optimizeImageLayers are required. 144 // While coalesceImages seems to be supported far back, optimizeImageLayers is not. 145 if ( method_exists( $this->image, 'coalesceImages' ) ) { 146 $this->animated = (bool) ( count( $this->image->coalesceImages() ) - 1); 147 } 148 else { 149 $this->animated = false; 150 } 151 142 152 // Select the first frame to handle animated images properly 143 153 if ( is_callable( array( $this->image, 'setIteratorIndex' ) ) ) 144 154 $this->image->setIteratorIndex(0); … … 250 260 } 251 261 252 262 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 ); 263 if ( $this->animated ) { 264 $this->image = $this->image->coalesceImages(); 265 } 266 267 foreach ($this->image as $frame) { 268 /** 269 * @TODO: Thumbnail is more efficient, given a newer version of Imagemagick. 270 * $this->image->thumbnailImage( $dst_w, $dst_h ); 271 */ 272 $frame->scaleImage( $dst_w, $dst_h ); 273 } 274 275 # $this->deconstructImages(); or $this->optimizeImageLayers(); 276 if ( $this->animated ) { 277 $this->image = $this->image->optimizeImageLayers(); 278 } 258 279 } 259 280 catch ( Exception $e ) { 260 281 return new WP_Error( 'image_resize_error', $e->getMessage() ); … … 356 377 } 357 378 358 379 try { 359 $this->image->cropImage( $src_w, $src_h, $src_x, $src_y ); 360 $this->image->setImagePage( $src_w, $src_h, 0, 0); 380 if ( $this->animated ) { 381 $this->image = $this->image->coalesceImages(); 382 } 361 383 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 ) 384 foreach ($this->image as $frame) { 385 $frame->cropImage( $src_w, $src_h, $src_x, $src_y ); 386 $frame->setImagePage( $src_w, $src_h, 0, 0); 387 388 if ( $dst_w || $dst_h ) { 389 // If destination width/height isn't specified, use same as 390 // width/height from source. 391 if ( ! $dst_w ) 366 392 $dst_w = $src_w; 367 if ( ! $dst_h )368 $dst_h = $src_h;393 if ( ! $dst_h ) 394 $dst_h = $src_h; 369 395 370 $this->image->scaleImage( $dst_w, $dst_h );371 return $this->update_size();396 $frame->scaleImage( $dst_w, $dst_h ); 397 } 372 398 } 399 400 if ( $this->animated ) { 401 $this->image = $this->image->optimizeImageLayers(); 402 } 373 403 } 374 404 catch ( Exception $e ) { 375 405 return new WP_Error( 'image_crop_error', $e->getMessage() ); … … 392 422 * (GD rotates counter-clockwise) 393 423 */ 394 424 try { 395 $this->image->rotateImage( new ImagickPixel('none'), 360-$angle ); 425 if ( $this->animated ) { 426 $this->image = $this->image->coalesceImages(); 427 } 396 428 429 foreach ($this->image as $frame) { 430 $frame->rotateImage( new ImagickPixel('none'), 360-$angle ); 431 } 432 433 if ( $this->animated ) { 434 $this->image = $this->image->optimizeImageLayers(); 435 } 436 397 437 // Since this changes the dimensions of the image, update the size. 398 438 $result = $this->update_size(); 399 439 if ( is_wp_error( $result ) ) … … 419 459 */ 420 460 public function flip( $horz, $vert ) { 421 461 try { 422 if ( $horz ) 423 $this->image->flipImage(); 462 if ( $this->animated ) { 463 $this->image = $this->image->coalesceImages(); 464 } 424 465 425 if ( $vert ) 426 $this->image->flopImage(); 466 foreach ($this->image as $frame) { 467 if ( $horz ) 468 $frame->flipImage(); 469 470 if ( $vert ) 471 $frame->flopImage(); 472 } 473 474 if ( $this->animated ) { 475 $this->image = $this->image->optimizeImageLayers(); 476 } 427 477 } 428 478 catch ( Exception $e ) { 429 479 return new WP_Error( 'image_flip_error', $e->getMessage() ); … … 477 527 $orig_format = $this->image->getImageFormat(); 478 528 479 529 $this->image->setImageFormat( strtoupper( $this->get_extension( $mime_type ) ) ); 480 $this->make_image( $filename, array( $image, 'writeImage' ), array( $filename ) );481 530 531 if ( $this->animated ) { 532 $this->make_image( $filename, array( $image, 'writeImages' ), array( $filename, true ) ); 533 } else { 534 $this->make_image( $filename, array( $image, 'writeImage' ), array( $filename ) ); 535 } 536 482 537 // Reset original Format 483 538 $this->image->setImageFormat( $orig_format ); 484 539 } … … 519 574 520 575 // Output stream of image content 521 576 header( "Content-Type: $mime_type" ); 522 print $this->image->getImageBlob();523 577 578 if ( $this->animated ) { 579 print $this->image->getImagesBlob(); 580 } else { 581 print $this->image->getImageBlob(); 582 } 583 524 584 // Reset Image to original Format 525 585 $this->image->setImageFormat( $this->get_extension( $this->mime_type ) ); 526 586 } -
src/wp-includes/class-wp-image-editor.php
20 20 protected $default_quality = 90; 21 21 22 22 /** 23 * Whether this is an animated image. 24 * 25 * @access protected 26 * @var bool 27 */ 28 protected $animated = null; 29 30 /** 23 31 * Each instance handles a single file. 24 32 * 25 33 * @param string $file Path to the file to load. … … 491 499 492 500 return $extensions[0]; 493 501 } 502 503 public function is_animated() { 504 return $this->animated; 505 } 506 494 507 } 495 508