WordPress.org

Make WordPress Core

Ticket #6821: 6821.patch

File 6821.patch, 21.0 KB (added by markoheijnen, 7 years ago)

First try to implement my class on github

  • wp-includes/class-wp-image.php

     
     1<?php
     2
     3class WP_Image {
     4        private $editor;
     5
     6        private $file;
     7        private $url;
     8        private $meta;
     9        private $backup_sizes;
     10
     11        function __construct( $post_id ) {
     12                if ( ! wp_attachment_is_image( $post_id ) )
     13                        return false;
     14
     15                $this->file         = get_attached_file( $post_id );
     16                $this->url          = wp_get_attachment_url( $post_id );
     17                $this->meta         = wp_get_attachment_metadata( $post_id );
     18                $this->backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true );
     19        }
     20
     21        function get_metadata() {
     22                return $this->meta;
     23        }
     24
     25        function load() {
     26                return $this->editor->load( $this->file );
     27        }
     28
     29        private function editor() {
     30                if( $this->editor )
     31                        return $this->editor;
     32
     33                $this->editor = new WP_Image_Editor( $this->url );
     34
     35                return $this->editor;
     36        }
     37}
     38 No newline at end of file
  • wp-includes/media.php

     
    180180 *
    181181 * @since 2.9.0
    182182 */
    183 function add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
     183function add_image_size( $name, $width = 0, $height = 0, $crop = false, $autogenerate = true ) {
    184184        global $_wp_additional_image_sizes;
    185         $_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => (bool) $crop );
     185        $_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => (bool) $crop, 'autogenerate' => (bool) $autogenerate );
    186186}
    187187
    188188/**
     
    191191 * @since 2.9.0
    192192 */
    193193function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) {
    194         add_image_size( 'post-thumbnail', $width, $height, $crop );
     194        add_image_size( 'post-thumbnail', $width, $height, $crop, false );
    195195}
    196196
    197197/**
     
    236236}
    237237
    238238/**
    239  * Load an image from a string, if PHP supports it.
    240  *
    241  * @since 2.1.0
    242  *
    243  * @param string $file Filename of the image to load.
    244  * @return resource The resulting image resource on success, Error string on failure.
    245  */
    246 function wp_load_image( $file ) {
    247         if ( is_numeric( $file ) )
    248                 $file = get_attached_file( $file );
    249 
    250         if ( ! file_exists( $file ) )
    251                 return sprintf(__('File &#8220;%s&#8221; doesn&#8217;t exist?'), $file);
    252 
    253         if ( ! function_exists('imagecreatefromstring') )
    254                 return __('The GD image library is not installed.');
    255 
    256         // Set artificially high because GD uses uncompressed images in memory
    257         @ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) );
    258         $image = imagecreatefromstring( file_get_contents( $file ) );
    259 
    260         if ( !is_resource( $image ) )
    261                 return sprintf(__('File &#8220;%s&#8221; is not an image.'), $file);
    262 
    263         return $image;
    264 }
    265 
    266 /**
    267239 * Calculates the new dimensions for a downsampled image.
    268240 *
    269241 * If either width or height are empty, no constraint is applied on
     
    393365}
    394366
    395367/**
    396  * Scale down an image to fit a particular size and save a new copy of the image.
    397  *
    398  * The PNG transparency will be preserved using the function, as well as the
    399  * image type. If the file going in is PNG, then the resized image is going to
    400  * be PNG. The only supported image types are PNG, GIF, and JPEG.
    401  *
    402  * Some functionality requires API to exist, so some PHP version may lose out
    403  * support. This is not the fault of WordPress (where functionality is
    404  * downgraded, not actual defects), but of your PHP version.
    405  *
    406  * @since 2.5.0
    407  *
    408  * @param string $file Image file path.
    409  * @param int $max_w Maximum width to resize to.
    410  * @param int $max_h Maximum height to resize to.
    411  * @param bool $crop Optional. Whether to crop image or resize.
    412  * @param string $suffix Optional. File suffix.
    413  * @param string $dest_path Optional. New image file path.
    414  * @param int $jpeg_quality Optional, default is 90. Image quality percentage.
    415  * @return mixed WP_Error on failure. String with new destination path.
    416  */
    417 function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
    418 
    419         $image = wp_load_image( $file );
    420         if ( !is_resource( $image ) )
    421                 return new WP_Error( 'error_loading_image', $image, $file );
    422 
    423         $size = @getimagesize( $file );
    424         if ( !$size )
    425                 return new WP_Error('invalid_image', __('Could not read image size'), $file);
    426         list($orig_w, $orig_h, $orig_type) = $size;
    427 
    428         $dims = image_resize_dimensions($orig_w, $orig_h, $max_w, $max_h, $crop);
    429         if ( !$dims )
    430                 return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') );
    431         list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims;
    432 
    433         $newimage = wp_imagecreatetruecolor( $dst_w, $dst_h );
    434 
    435         imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
    436 
    437         // convert from full colors to index colors, like original PNG.
    438         if ( IMAGETYPE_PNG == $orig_type && function_exists('imageistruecolor') && !imageistruecolor( $image ) )
    439                 imagetruecolortopalette( $newimage, false, imagecolorstotal( $image ) );
    440 
    441         // we don't need the original in memory anymore
    442         imagedestroy( $image );
    443 
    444         // $suffix will be appended to the destination filename, just before the extension
    445         if ( !$suffix )
    446                 $suffix = "{$dst_w}x{$dst_h}";
    447 
    448         $info = pathinfo($file);
    449         $dir = $info['dirname'];
    450         $ext = $info['extension'];
    451         $name = wp_basename($file, ".$ext");
    452 
    453         if ( !is_null($dest_path) and $_dest_path = realpath($dest_path) )
    454                 $dir = $_dest_path;
    455         $destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
    456 
    457         if ( IMAGETYPE_GIF == $orig_type ) {
    458                 if ( !imagegif( $newimage, $destfilename ) )
    459                         return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
    460         } elseif ( IMAGETYPE_PNG == $orig_type ) {
    461                 if ( !imagepng( $newimage, $destfilename ) )
    462                         return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
    463         } else {
    464                 // all other formats are converted to jpg
    465                 if ( 'jpg' != $ext && 'jpeg' != $ext )
    466                         $destfilename = "{$dir}/{$name}-{$suffix}.jpg";
    467                 if ( !imagejpeg( $newimage, $destfilename, apply_filters( 'jpeg_quality', $jpeg_quality, 'image_resize' ) ) )
    468                         return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
    469         }
    470 
    471         imagedestroy( $newimage );
    472 
    473         // Set correct file permissions
    474         $stat = stat( dirname( $destfilename ));
    475         $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
    476         @ chmod( $destfilename, $perms );
    477 
    478         return $destfilename;
    479 }
    480 
    481 /**
    482368 * Resize an image to make a thumbnail or intermediate size.
    483369 *
    484370 * The returned array has the file size, the image width, and image height. The
     
    493379 * @param bool $crop Optional, default is false. Whether to crop image to specified height and width or resize.
    494380 * @return bool|array False, if no image was created. Metadata array on success.
    495381 */
    496 function image_make_intermediate_size($file, $width, $height, $crop=false) {
     382function image_make_intermediate_size( $file, $width, $height, $crop = sfalse ) {
    497383        if ( $width || $height ) {
    498                 $resized_file = image_resize($file, $width, $height, $crop);
    499                 if ( !is_wp_error($resized_file) && $resized_file && $info = getimagesize($resized_file) ) {
    500                         $resized_file = apply_filters('image_make_intermediate_size', $resized_file);
    501                         return array(
    502                                 'file' => wp_basename( $resized_file ),
    503                                 'width' => $info[0],
    504                                 'height' => $info[1],
    505                         );
     384                $editor = new WP_Image_Editor( $file );
     385                $resized_file = $editor->resize( $width, $height, $crop );
     386                unset( $editor );
     387
     388                if ( ! is_wp_error( $resized_file ) && $resized_file ) {
     389                        return $resized_file;
    506390                }
    507391        }
     392
    508393        return false;
    509394}
    510395
  • wp-includes/editors/class-wp-image-editor-imagick.php

     
     1<?php
     2
     3class WP_Image_Editor_Imagick {
     4        function __construct() {
     5
     6        }
     7
     8        public static function test( $function ) {
     9                if ( ! extension_loaded('imagick') )
     10                        return false;
     11
     12                return true;
     13        }
     14
     15        public function load( $file ) {
     16                if ( ! file_exists( $file ) )
     17                        return sprintf( __('File &#8220;%s&#8221; doesn&#8217;t exist?'), $file );
     18
     19                try {
     20                        $image = new Imagick( $file );
     21                }
     22                catch ( Exception $e ) {
     23                        return sprintf(__('File &#8220;%s&#8221; is not an image.'), $file);
     24                }
     25
     26                if( ! $image->valid() ) {
     27                        return sprintf(__('File &#8220;%s&#8221; is not an image.'), $file);
     28                }
     29
     30                return $image;
     31        }
     32
     33        public function resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
     34                $image = $this->load( $file );
     35                if ( ! is_object( $image ) )
     36                        return new WP_Error( 'error_loading_image', $image, $file );
     37
     38                $imageprops = $image->getImageGeometry();
     39                $orig_type  = $image->getImageFormat();
     40                if ( ! $imageprops )
     41                        return new WP_Error( 'invalid_image', __('Could not read image size'), $file );
     42
     43                $dims = image_resize_dimensions( $imageprops['width'], $imageprops['height'], $max_w, $max_h, $crop );
     44                if ( ! $dims )
     45                        return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') );
     46                list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims;
     47
     48                if( 'JPEG' == $orig_type ) {
     49                        $image->setImageCompression( imagick::COMPRESSION_JPEG );
     50                        $image->setImageCompressionQuality( $jpeg_quality );
     51                }
     52
     53                if ( $crop ) {
     54                        $image->cropImage( $src_w, $src_h, $src_x, $src_y );
     55
     56                        $image->scaleImage( $dst_w, $dst_h, true );
     57                        //$image->resizeImage( $dst_w, $dst_h, imagick::FILTER_LANCZOS, 1 );
     58                }
     59                else {
     60                        //$image->thumbnailImage( $dst_w, $dst_h );
     61                        $image->scaleImage( $dst_w, $dst_h, true );
     62                }
     63
     64                // $suffix will be appended to the destination filename, just before the extension
     65                if ( ! $suffix )
     66                        $suffix = "{$dst_w}x{$dst_h}";
     67
     68                $info = pathinfo( $file );
     69                $dir  = $info['dirname'];
     70                $ext  = $info['extension'];
     71                $name = wp_basename( $file, ".$ext" );
     72
     73                if ( ! is_null( $dest_path ) && $_dest_path = realpath( $dest_path ) )
     74                        $dir = $_dest_path;
     75                $destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
     76
     77                if( apply_filters( 'wp_editors_stripimage', true ) ) {
     78                        $image->stripImage();
     79                }
     80
     81                $image->writeImage( $destfilename );
     82
     83                // Set correct file permissions
     84                $stat = stat( dirname( $destfilename ) );
     85                $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
     86                @ chmod( $destfilename, $perms );
     87
     88                return array(
     89                        'path' => $destfilename,
     90                        'file' => wp_basename(  apply_filters( 'image_make_intermediate_size', $destfilename ) ),
     91                        'width' => $dst_w,
     92                        'height' => $dst_h
     93                );
     94        }
     95}
     96 No newline at end of file
  • wp-includes/editors/class-wp-image-editor-gd.php

     
     1<?php
     2
     3class WP_Image_Editor_GD {
     4        private $image = false;
     5
     6        function __construct() {
     7
     8        }
     9
     10        function __destruct() {
     11                if ( $this->image ) {
     12                        // we don't need the original in memory anymore
     13                        imagedestroy( $this->image );
     14                }
     15        }
     16
     17        public static function test( $function ) {
     18                if ( ! extension_loaded('gd') || ! function_exists('gd_info') )
     19                        return false;
     20
     21                return true;
     22        }
     23
     24        public function load( $file ) {
     25                if( $this->image )
     26                        $this->image;
     27
     28                if ( ! file_exists( $file ) )
     29                        return sprintf( __('File &#8220;%s&#8221; doesn&#8217;t exist?'), $file );
     30
     31                if ( ! function_exists('imagecreatefromstring') )
     32                        return __('The GD image library is not installed.');
     33
     34                // Set artificially high because GD uses uncompressed images in memory
     35                @ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) );
     36                $image = imagecreatefromstring( file_get_contents( $file ) );
     37
     38                if ( ! is_resource( $image ) )
     39                        return sprintf( __('File &#8220;%s&#8221; is not an image.'), $file );
     40
     41                $this->image = $image;
     42                return $image;
     43        }
     44
     45        public function resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
     46                $image = $this->load( $file );
     47                if ( ! is_resource( $image ) )
     48                        return new WP_Error( 'error_loading_image', $image, $file );
     49
     50                $size = @getimagesize( $file );
     51                if ( ! $size )
     52                        return new WP_Error( 'invalid_image', __('Could not read image size'), $file );
     53                list( $orig_w, $orig_h, $orig_type ) = $size;
     54
     55                $dims = image_resize_dimensions( $orig_w, $orig_h, $max_w, $max_h, $crop );
     56                if ( ! $dims )
     57                        return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') );
     58                list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims;
     59
     60
     61                $newimage = wp_imagecreatetruecolor( $dst_w, $dst_h );
     62
     63                imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h );
     64
     65                // convert from full colors to index colors, like original PNG.
     66                if ( IMAGETYPE_PNG == $orig_type && function_exists('imageistruecolor') && !imageistruecolor( $image ) )
     67                        imagetruecolortopalette( $newimage, false, imagecolorstotal( $image ) );
     68
     69                // $suffix will be appended to the destination filename, just before the extension
     70                if ( ! $suffix )
     71                        $suffix = "{$dst_w}x{$dst_h}";
     72
     73                $info = pathinfo( $file );
     74                $dir  = $info['dirname'];
     75                $ext  = $info['extension'];
     76                $name = wp_basename( $file, ".$ext" );
     77
     78                if ( ! is_null( $dest_path ) && $_dest_path = realpath( $dest_path ) )
     79                        $dir = $_dest_path;
     80                $destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
     81
     82                if ( IMAGETYPE_GIF == $orig_type ) {
     83                        if ( ! imagegif( $newimage, $destfilename ) )
     84                                return new WP_Error( 'resize_path_invalid', __( 'Resize path invalid' ) );
     85                }
     86                elseif ( IMAGETYPE_PNG == $orig_type ) {
     87                        if ( !imagepng( $newimage, $destfilename ) )
     88                                return new WP_Error( 'resize_path_invalid', __( 'Resize path invalid' ) );
     89                }
     90                else {
     91                        // all other formats are converted to jpg
     92                        if ( 'jpg' != $ext && 'jpeg' != $ext )
     93                                $destfilename = "{$dir}/{$name}-{$suffix}.jpg";
     94
     95                        if ( ! imagejpeg( $newimage, $destfilename, apply_filters( 'jpeg_quality', $jpeg_quality, 'image_resize' ) ) )
     96                                return new WP_Error( 'resize_path_invalid', __( 'Resize path invalid' ) );
     97                }
     98
     99                imagedestroy( $newimage );
     100
     101                // Set correct file permissions
     102                $stat = stat( dirname( $destfilename ) );
     103                $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
     104                @ chmod( $destfilename, $perms );
     105
     106                return array(
     107                        'path' => $destfilename,
     108                        'file' => wp_basename(  apply_filters( 'image_make_intermediate_size', $destfilename ) ),
     109                        'width' => $dst_w,
     110                        'height' => $dst_h
     111                );
     112        }
     113}
     114 No newline at end of file
  • wp-includes/class-wp-image-editor.php

     
     1<?php
     2
     3class WP_Image_Editor {
     4        private $file;
     5        private $editors;
     6
     7        function __construct( $file ) {
     8                $this->file = $file;
     9        }
     10
     11        /**
     12         * Tests which editors are capable of supporting the request.
     13         *
     14         * @since 3.5.0
     15         * @access private
     16         *
     17         * @return string|bool Class name for the first editor that claims to support the request. False if no editor claims to support the request.
     18         */
     19        private function get_first_available( $function ) {
     20                $request_order = apply_filters( 'wp_editors', array( 'imagick', 'gd' ) );
     21
     22                // Loop over each editor on each request looking for one which will serve this request's needs
     23                foreach ( $request_order as $editor ) {
     24                        $class = 'WP_Image_Editor_' . $editor;
     25
     26                        // Check to see if this editor is a possibility, calls the editor statically
     27                        if ( ! call_user_func( array( $class, 'test' ), $function  ) )
     28                                continue;
     29
     30                        if( ! apply_filters( 'wp_editor_use_' . $editor, true, $function ) )
     31                                continue;
     32
     33                        if( ! $this->editors[ $class ] )
     34                                $this->editors[ $class ] = new $class;
     35
     36                        return $this->editors[ $class ];
     37                }
     38
     39                return false;
     40        }
     41
     42
     43        function load( $file ) {
     44                $editor = $this->get_first_available( 'load' );
     45
     46                if( $editor ) {
     47                        return $editor->load( $file );
     48                }
     49
     50                return false;
     51        }
     52
     53        function resize( $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
     54                $editor = $this->get_first_available( 'resize' );
     55
     56                if( $editor ) {
     57                        return $editor->resize( $this->file, $max_w, $max_h, $crop, $suffix, $dest_path, $jpeg_quality );
     58                }
     59        }
     60
     61        function rotate() {
     62
     63        }
     64
     65        function save() {
     66
     67        }
     68}
     69 No newline at end of file
  • wp-includes/deprecated.php

     
    31903190        if ( is_sticky( $post_id ) )
    31913191                echo ' sticky';
    31923192}
     3193
     3194
     3195
     3196
     3197
     3198/**
     3199 * Load an image from a string, if PHP supports it.
     3200 *
     3201 * @since 2.1.0
     3202 * @deprecated 3.5.0
     3203 * @deprecated wp_get_image_for_editing()
     3204 *
     3205 * @param string $file Filename of the image to load.
     3206 * @return resource The resulting image resource on success, Error string on failure.
     3207 */
     3208function wp_load_image( $file ) {
     3209        _deprecated_function( __FUNCTION__, '3.5', 'wp_get_image_for_editing()' );
     3210
     3211        if ( is_numeric( $file ) )
     3212                $file = get_attached_file( $file );
     3213
     3214        $editor = new WP_Image_Editor_GD;
     3215        $editor->load( $file );
     3216}
     3217
     3218/**
     3219 * Scale down an image to fit a particular size and save a new copy of the image.
     3220 *
     3221 * The PNG transparency will be preserved using the function, as well as the
     3222 * image type. If the file going in is PNG, then the resized image is going to
     3223 * be PNG. The only supported image types are PNG, GIF, and JPEG.
     3224 *
     3225 * Some functionality requires API to exist, so some PHP version may lose out
     3226 * support. This is not the fault of WordPress (where functionality is
     3227 * downgraded, not actual defects), but of your PHP version.
     3228 *
     3229 * @since 2.5.0
     3230 * @deprecated 3.5.0
     3231 * @deprecated wp_get_image_for_editing()
     3232 *
     3233 * @param string $file Image file path.
     3234 * @param int $max_w Maximum width to resize to.
     3235 * @param int $max_h Maximum height to resize to.
     3236 * @param bool $crop Optional. Whether to crop image or resize.
     3237 * @param string $suffix Optional. File suffix.
     3238 * @param string $dest_path Optional. New image file path.
     3239 * @param int $jpeg_quality Optional, default is 90. Image quality percentage.
     3240 * @return mixed WP_Error on failure. String with new destination path.
     3241 */
     3242function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
     3243        _deprecated_function( __FUNCTION__, '3.5', 'wp_get_image_for_editing()' );
     3244
     3245        $editor = new WP_Image_Editor_GD;
     3246        $editor->resize( $file, $max_w, $max_h, $crop, $suffix, $dest_path, $jpeg_quality );
     3247}
  • wp-settings.php

     
    143143require( ABSPATH . WPINC . '/nav-menu-template.php' );
    144144require( ABSPATH . WPINC . '/admin-bar.php' );
    145145
     146require( ABSPATH . WPINC . '/admin-wp-image.php' );
     147require( ABSPATH . WPINC . '/admin-wp-image-editor.php' );
     148require( ABSPATH . WPINC . '/editors/class-wp-image-editor-gd.php' );
     149require( ABSPATH . WPINC . '/editors/class-wp-image-editor-imagick.php' );
     150
    146151// Load multisite-specific files.
    147152if ( is_multisite() ) {
    148153        require( ABSPATH . WPINC . '/ms-functions.php' );
  • wp-admin/includes/image.php

     
    127127                global $_wp_additional_image_sizes;
    128128
    129129                foreach ( get_intermediate_image_sizes() as $s ) {
     130                        if ( isset( $_wp_additional_image_sizes[$s] ) && ! $_wp_additional_image_sizes[$s]['autogenerate'] )
     131                                continue;
     132
    130133                        $sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => false );
    131134                        if ( isset( $_wp_additional_image_sizes[$s]['width'] ) )
    132135                                $sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] ); // For theme-added sizes
     
    144147
    145148                $sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes );
    146149
     150                $editor = new WP_Image_Editor( $file );
     151
    147152                foreach ($sizes as $size => $size_data ) {
    148                         $resized = image_make_intermediate_size( $file, $size_data['width'], $size_data['height'], $size_data['crop'] );
    149                         if ( $resized )
     153                        $resized = $editor->resize( $size_data['width'], $size_data['height'], $size_data['crop'] );
     154                        if ( ! is_wp_error( $resized ) && $resized )
    150155                                $metadata['sizes'][$size] = $resized;
    151156                }
    152157
     158                unset( $editor );
     159
    153160                // fetch additional metadata from exif/iptc
    154161                $image_meta = wp_read_image_metadata( $file );
    155162                if ( $image_meta )