Make WordPress Core

Changeset 38949


Ignore:
Timestamp:
10/26/2016 07:27:51 AM (10 years ago)
Author:
mikeschroder
Message:

Media: Add support for rendering PDF thumbnails.

When support for PDFs is available, on upload,
render 'Thumbnail', 'Medium', 'Large', and 'Full' sizes of
the first page, and save them in attachment meta.

Use these renders within Add Media, Media Gallery and List views,
Attachment Details, Post/Attachment Edit screens, and Attachment pages.

Support available by default via Imagick -> ImageMagick -> Ghostscript,
but can be provided by any WP_Image_Editor that supports PDFs.

Props adamsilverstein, azaozz, celloexpressions, desrosj, dglingren, ericlewis, ipstenu, joemcgill, joyously, markoheijnen, melchoyce, mikeschroder, tomauger.
Fixes #31050.

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/image.php

    r38333 r38949  
    7777        $metadata = array();
    7878        $support = false;
    79         if ( preg_match('!^image/!', get_post_mime_type( $attachment )) && file_is_displayable_image($file) ) {
     79        $mime_type = get_post_mime_type( $attachment );
     80
     81        if ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image( $file ) ) {
    8082                $imagesize = getimagesize( $file );
    8183                $metadata['width'] = $imagesize[0];
     
    202204                }
    203205        }
     206        // Try to create image thumbnails for PDFs
     207        else if ( 'application/pdf' === $mime_type ) {
     208                $editor = wp_get_image_editor( $file );
     209
     210                $fallback_sizes = array(
     211                        'thumbnail',
     212                        'medium',
     213                        'large',
     214                );
     215
     216                $sizes = array();
     217
     218                foreach ( $fallback_sizes as $s ) {
     219                        $sizes[$s]['width']  = get_option( "{$s}_size_w" );
     220                        $sizes[$s]['height'] = get_option( "{$s}_size_h" );
     221
     222                        // Force thumbnails to be soft crops.
     223                        if ( ! 'thumbnail' === $s ) {
     224                                $sizes[$s]['crop'] = get_option( "{$s}_crop" );
     225                        }
     226                }
     227
     228                if ( ! is_wp_error( $editor ) ) { // No support for this type of file
     229                        $uploaded = $editor->save( $file, 'image/jpeg' );
     230                        unset( $editor );
     231
     232                        // Resize based on the full size image, rather than the source.
     233                        if ( ! is_wp_error( $uploaded ) ) {
     234                                $editor = wp_get_image_editor( $uploaded['path'] );
     235                                unset( $uploaded['path'] );
     236
     237                                if ( ! is_wp_error( $editor ) ) {
     238                                        $metadata['sizes'] = $editor->multi_resize( $sizes );
     239                                        $metadata['sizes']['full'] = $uploaded;
     240                                }
     241                        }
     242                }
     243        }
    204244
    205245        // Remove the blob of binary data from the array.
  • trunk/src/wp-admin/includes/media.php

    r38734 r38949  
    27672767                echo wp_video_shortcode( $attr );
    27682768
    2769         else :
     2769        elseif ( isset( $thumb_url[0] ) ):
     2770
     2771                ?>
     2772                <div class="wp_attachment_image wp-clearfix" id="media-head-<?php echo $attachment_id; ?>">
     2773                        <p id="thumbnail-head-<?php echo $attachment_id; ?>">
     2774                                <img class="thumbnail" src="<?php echo set_url_scheme( $thumb_url[0] ); ?>" style="max-width:100%" alt="" />
     2775                        </p>
     2776                </div>
     2777                <?php
     2778
     2779        else:
    27702780
    27712781                /**
  • trunk/src/wp-includes/class-wp-image-editor-imagick.php

    r38015 r38949  
    7474                        'flipimage',
    7575                        'flopimage',
     76                        'readimage',
    7677                );
    7778
     
    145146
    146147                try {
    147                         $this->image = new Imagick( $this->file );
     148                        $this->image = new Imagick();
     149                        $file_parts = pathinfo( $this->file );
     150
     151                        // By default, PDFs are rendered in a very low resolution.
     152                        // We want the thumbnail to be readable, so increase the rendering dpi.
     153                        if ( 'pdf' == strtolower( $file_parts['extension'] ) ) {
     154                                $this->image->setResolution( 128, 128 );
     155                        }
     156
     157                        // Reading image after Imagick instantiation because `setResolution`
     158                        // only applies correctly before the image is read.
     159                        $this->image->readImage( $this->file );
    148160
    149161                        if ( ! $this->image->valid() )
  • trunk/src/wp-includes/media-template.php

    r38468 r38949  
    291291                                <# if ( data.uploading ) { #>
    292292                                        <div class="media-progress-bar"><div></div></div>
    293                                 <# } else if ( 'image' === data.type && data.sizes && data.sizes.large ) { #>
     293                                <# } else if ( data.sizes && data.sizes.large ) { #>
    294294                                        <img class="details-image" src="{{ data.sizes.large.url }}" draggable="false" alt="" />
    295                                 <# } else if ( 'image' === data.type && data.sizes && data.sizes.full ) { #>
     295                                <# } else if ( data.sizes && data.sizes.full ) { #>
    296296                                        <img class="details-image" src="{{ data.sizes.full.url }}" draggable="false" alt="" />
    297297                                <# } else if ( -1 === jQuery.inArray( data.type, [ 'audio', 'video' ] ) ) { #>
     
    455455                                                <# if ( data.image && data.image.src && data.image.src !== data.icon ) { #>
    456456                                                        <img src="{{ data.image.src }}" class="thumbnail" draggable="false" alt="" />
     457                                                <# } else if ( data.sizes && data.sizes.medium ) { #>
     458                                                        <img src="{{ data.sizes.medium.url }}" class="thumbnail" draggable="false" alt="" />
    457459                                                <# } else { #>
    458460                                                        <img src="{{ data.icon }}" class="icon" draggable="false" alt="" />
  • trunk/src/wp-includes/media.php

    r38812 r38949  
    184184 */
    185185function image_downsize( $id, $size = 'medium' ) {
    186 
    187         if ( !wp_attachment_is_image($id) )
    188                 return false;
     186        $is_image = wp_attachment_is_image( $id );
    189187
    190188        /**
     
    210208        $is_intermediate = false;
    211209        $img_url_basename = wp_basename($img_url);
     210
     211        // If the file isn't an image, attempt to replace its URL with a rendered image from its meta.
     212        // Otherwise, a non-image type could be returned.
     213        if ( ! $is_image ) {
     214                if ( ! empty( $meta['sizes'] ) ) {
     215                        $img_url = str_replace( $img_url_basename, $meta['sizes']['full']['file'], $img_url );
     216                        $img_url_basename = $meta['sizes']['full']['file'];
     217                        $width = $meta['sizes']['full']['width'];
     218                        $height = $meta['sizes']['full']['height'];
     219                } else {
     220                        return false;
     221                }
     222        }
    212223
    213224        // try for a new style intermediate size
     
    685696        if ( is_array( $size ) ) {
    686697                $candidates = array();
     698
     699                if ( ! isset( $imagedata['file'] ) && isset( $imagedata['sizes']['full'] ) ) {
     700                        $imagedata['height'] = $imagedata['sizes']['full']['height'];
     701                        $imagedata['width']  = $imagedata['sizes']['full']['width'];
     702                }
    687703
    688704                foreach ( $imagedata['sizes'] as $_size => $data ) {
     
    739755
    740756        // include the full filesystem path of the intermediate file
    741         if ( empty($data['path']) && !empty($data['file']) ) {
     757        if ( empty( $data['path'] ) && ! empty( $data['file'] ) && ! empty( $imagedata['file'] ) ) {
    742758                $file_url = wp_get_attachment_url($post_id);
    743759                $data['path'] = path_join( dirname($imagedata['file']), $data['file'] );
     
    31243140                $response['nonces']['delete'] = wp_create_nonce( 'delete-post_' . $attachment->ID );
    31253141
    3126         if ( $meta && 'image' === $type ) {
     3142        if ( $meta && ! empty( $meta['sizes'] ) ) {
    31273143                $sizes = array();
    31283144
     
    31723188                }
    31733189
    3174                 $sizes['full'] = array( 'url' => $attachment_url );
    3175 
    3176                 if ( isset( $meta['height'], $meta['width'] ) ) {
    3177                         $sizes['full']['height'] = $meta['height'];
    3178                         $sizes['full']['width'] = $meta['width'];
    3179                         $sizes['full']['orientation'] = $meta['height'] > $meta['width'] ? 'portrait' : 'landscape';
    3180                 }
    3181 
    3182                 $response = array_merge( $response, array( 'sizes' => $sizes ), $sizes['full'] );
    3183         } elseif ( $meta && 'video' === $type ) {
     3190                if ( 'image' === $type ) {
     3191                        $sizes['full'] = array( 'url' => $attachment_url );
     3192
     3193                        if ( isset( $meta['height'], $meta['width'] ) ) {
     3194                                $sizes['full']['height'] = $meta['height'];
     3195                                $sizes['full']['width'] = $meta['width'];
     3196                                $sizes['full']['orientation'] = $meta['height'] > $meta['width'] ? 'portrait' : 'landscape';
     3197                        }
     3198
     3199                        $response = array_merge( $response, $sizes['full'] );
     3200                } elseif ( $meta['sizes']['full']['file'] ) {
     3201                        $sizes['full'] = array(
     3202                                'url'         => $base_url . $meta['sizes']['full']['file'],
     3203                                'height'      => $meta['sizes']['full']['height'],
     3204                                'width'       => $meta['sizes']['full']['width'],
     3205                                'orientation' => $meta['sizes']['full']['height'] > $meta['sizes']['full']['width'] ? 'portrait' : 'landscape'
     3206                        );
     3207                }
     3208
     3209                $response = array_merge( $response, array( 'sizes' => $sizes ) );
     3210        }
     3211
     3212        if ( $meta && 'video' === $type ) {
    31843213                if ( isset( $meta['width'] ) )
    31853214                        $response['width'] = (int) $meta['width'];
  • trunk/tests/phpunit/tests/image/functions.php

    r38762 r38949  
    352352                WP_Image_Editor_Mock::$save_return = array();
    353353        }
     354
     355        /**
     356         * @ticket 31050
     357         */
     358        public function test_wp_generate_attachment_metadata_pdf() {
     359                if ( ! wp_image_editor_supports( array( 'mime_type' => 'application/pdf' ) ) ) {
     360                        $this->markTestSkipped( 'Rendering PDFs is not supported on this system.' );
     361                }
     362
     363                $orig_file = DIR_TESTDATA . '/images/wordpress-gsoc-flyer.pdf';
     364                $test_file = '/tmp/wordpress-gsoc-flyer.pdf';
     365                copy( $orig_file, $test_file );
     366
     367                $attachment_id = $this->factory->attachment->create_object( $test_file, 0, array(
     368                        'post_mime_type' => 'application/pdf',
     369                ) );
     370
     371                $this->assertNotEmpty( $attachment_id );
     372
     373                $expected = array(
     374                        'sizes' => array(
     375                                'thumbnail' => array(
     376                                        'file'      => "wordpress-gsoc-flyer-116x150.jpg",
     377                                        'width'     => 116,
     378                                        'height'    => 150,
     379                                        'mime-type' => "image/jpeg",
     380                                ),
     381                                'medium'    => array(
     382                                        'file'      => "wordpress-gsoc-flyer-232x300.jpg",
     383                                        'width'     => 232,
     384                                        'height'    => 300,
     385                                        'mime-type' => "image/jpeg",
     386                                ),
     387                                'large'     => array(
     388                                        'file'      => "wordpress-gsoc-flyer-791x1024.jpg",
     389                                        'width'     => 791,
     390                                        'height'    => 1024,
     391                                        'mime-type' => "image/jpeg",
     392                                ),
     393                                'full'      => array(
     394                                        'file'      => "wordpress-gsoc-flyer.jpg",
     395                                        'width'     => 1088,
     396                                        'height'    => 1408,
     397                                        'mime-type' => "image/jpeg",
     398                                ),
     399                        ),
     400                );
     401
     402                $metadata = wp_generate_attachment_metadata( $attachment_id, $test_file );
     403                $this->assertSame( $expected, $metadata );
     404
     405                unlink( $test_file );
     406        }
    354407}
Note: See TracChangeset for help on using the changeset viewer.