| | 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. |
|---|
| | 97 | function 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 |
|---|
| | 117 | function 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 |
|---|
| | 167 | function 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 | |
|---|