WordPress.org

Make WordPress Core

Ticket #6005: image-resize-r7030.patch

File image-resize-r7030.patch, 6.3 KB (added by tellyworth, 10 years ago)
  • wordpress/wp-admin/includes/image.php

     
    227227        return wp_constrain_dimensions( $width, $height, $wmax, $hmax );
    228228}
    229229
    230 // same as wp_shrink_dimensions, except the max parameters are optional.
    231 // if either width or height are empty, no constraint is applied on that dimension.
    232 function wp_constrain_dimensions( $current_width, $current_height, $max_width=0, $max_height=0 ) {
    233         if ( !$max_width and !$max_height )
    234                 return array( $current_width, $current_height );
    235        
    236         $width_ratio = $height_ratio = 1.0;
    237        
    238         if ( $max_width > 0 && $current_width > $max_width )
    239                 $width_ratio = $max_width / $current_width;
    240        
    241         if ( $max_height > 0 && $current_height > $max_height )
    242                 $height_ratio = $max_height / $current_height;
    243        
    244         // the smaller ratio is the one we need to fit it to the constraining box
    245         $ratio = min( $width_ratio, $height_ratio );
    246        
    247         return array( intval($current_width * $ratio), intval($current_height * $ratio) );
    248 }
    249 
    250230// convert a fraction string to a decimal
    251231function wp_exif_frac2dec($str) {
    252232        @list( $n, $d ) = explode( '/', $str );
  • wordpress/wp-includes/media.php

     
    9292        return $html;
    9393}
    9494
     95// same as wp_shrink_dimensions, except the max parameters are optional.
     96// if either width or height are empty, no constraint is applied on that dimension.
     97function wp_constrain_dimensions( $current_width, $current_height, $max_width=0, $max_height=0 ) {
     98        if ( !$max_width and !$max_height )
     99                return array( $current_width, $current_height );
     100       
     101        $width_ratio = $height_ratio = 1.0;
     102       
     103        if ( $max_width > 0 && $current_width > $max_width )
     104                $width_ratio = $max_width / $current_width;
     105       
     106        if ( $max_height > 0 && $current_height > $max_height )
     107                $height_ratio = $max_height / $current_height;
     108       
     109        // the smaller ratio is the one we need to fit it to the constraining box
     110        $ratio = min( $width_ratio, $height_ratio );
     111       
     112        return array( intval($current_width * $ratio), intval($current_height * $ratio) );
     113}
     114
     115// calculate dimensions and coordinates for a resized image that fits within a specified width and height
     116// if $crop is true, the largest matching central portion of the image will be cropped out and resized to the required size
     117function image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop=false) {
     118       
     119        if ($orig_w <= 0 || $orig_h <= 0)
     120                return false;
     121        // at least one of dest_w or dest_h must be specific
     122        if ($dest_w <= 0 && $dest_h <= 0)
     123                return false;
     124       
     125        if ( $crop ) {
     126                // crop the largest possible portion of the original image that we can size to $dest_w x $dest_h
     127                $aspect_ratio = $orig_w / $orig_h;
     128                $new_w = min($dest_w, $orig_w);
     129                $new_h = min($dest_h, $orig_h);
     130                if (!$new_w) {
     131                        $new_w = intval($new_h * $aspect_ratio);
     132                }
     133                if (!$new_h) {
     134                        $new_h = intval($new_w / $aspect_ratio);
     135                }
     136
     137                $size_ratio = max($new_w / $orig_w, $new_h / $orig_h);
     138               
     139                $crop_w = ceil($new_w / $size_ratio);
     140                $crop_h = ceil($new_h / $size_ratio);
     141
     142                $s_x = floor(($orig_w - $crop_w)/2);
     143                $s_y = floor(($orig_h - $crop_h)/2);
     144        }
     145        else {
     146                // don't crop, just resize using $dest_w x $dest_h as a maximum bounding box
     147                $crop_w = $orig_w;
     148                $crop_h = $orig_h;
     149               
     150                $s_x = 0;
     151                $s_y = 0;
     152               
     153                list( $new_w, $new_h ) = wp_constrain_dimensions( $orig_w, $orig_h, $dest_w, $dest_h );
     154        }
     155       
     156        // if the resulting image would be the same size or larger we don't want to resize it
     157        if ($new_w >= $orig_w && $new_h >= $orig_h)
     158                return false;
     159
     160        // the return array matches the parameters to imagecopyresampled()
     161        // int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h
     162        return array(0, 0, $s_x, $s_y, $new_w, $new_h, $crop_w, $crop_h);
     163
     164}
     165
     166// Scale down an image to fit a particular size and save a new copy of the image
     167function image_resize( $file, $max_w, $max_h, $crop=false, $suffix=null, $dest_path=null, $jpeg_quality=75) {
     168
     169        $image = wp_load_image( $file );
     170        if ( !is_resource( $image ) )
     171                return new WP_Error('error_loading_image', $image);
     172
     173        list($orig_w, $orig_h, $orig_type) = getimagesize( $file );
     174        $dims = image_resize_dimensions($orig_w, $orig_h, $max_w, $max_h, $crop);
     175        if (!$dims)
     176                return $dims;
     177        list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims;
     178       
     179        $newimage = imagecreatetruecolor( $dst_w, $dst_h);
     180
     181        // preserve PNG transparency
     182        if ( IMAGETYPE_PNG == $orig_type && function_exists( 'imagealphablending' ) && function_exists( 'imagesavealpha' ) ) {
     183                imagealphablending( $newimage, false);
     184                imagesavealpha( $newimage, true);
     185        }
     186
     187        imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
     188
     189        // we don't need the original in memory anymore
     190        imagedestroy( $image );
     191
     192        // $suffix will be appended to the destination filename, just before the extension
     193        if ( !$suffix )
     194                $suffix = "{$dst_w}x{$dst_h}";
     195
     196        $info = pathinfo($file);
     197        $dir = $info['dirname'];
     198        $ext = $info['extension'];
     199        $name = basename($file, ".{$ext}");
     200        if ( !is_null($dest_path) and $_dest_path = realpath($dest_path) )
     201                $dir = $_dest_path;
     202        $destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
     203
     204        if ( $orig_type == IMAGETYPE_GIF ) {
     205                if (!imagegif( $newimage, $destfilename ) )
     206                        return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
     207        }
     208        elseif ( $orig_type == IMAGETYPE_PNG ) {
     209                if (!imagepng( $newimage, $destfilename ) )
     210                        return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
     211        }
     212        else {
     213                // all other formats are converted to jpg
     214                $destfilename = "{$dir}/{$name}-{$suffix}.jpg";
     215                if (!imagejpeg( $newimage, $destfilename, $jpeg_quality ) )
     216                        return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
     217        }
     218
     219        imagedestroy( $newimage );
     220
     221        // Set correct file permissions
     222        $stat = stat( dirname( $destfilename ));
     223        $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
     224        @ chmod( $destfilename, $perms );
     225
     226        return $destfilename;
     227}
     228
    95229?>
     230 No newline at end of file