169 |
169 |
170 return new WP_Error( 'image_resize_error', __( 'Image resize failed.' ), $this->file ); |
170 return new WP_Error( 'image_resize_error', __( 'Image resize failed.' ), $this->file ); |
171 } |
171 } |
172 |
172 |
173 /** |
173 /** |
174 * @param int $max_w |
174 * @param int $max_w |
175 * @param int $max_h |
175 * @param int $max_h |
176 * @param bool|array $crop |
176 * @param bool|array $crop |
177 * @return resource|WP_Error |
177 * @return resource|WP_Error |
178 */ |
178 */ |
179 protected function _resize( $max_w, $max_h, $crop = false ) { |
179 protected function _resize( $max_w, $max_h, $crop = false ) { |
180 $dims = image_resize_dimensions( $this->size['width'], $this->size['height'], $max_w, $max_h, $crop ); |
180 $dims = image_resize_dimensions( $this->size['width'], $this->size['height'], $max_w, $max_h, $crop ); |
|
181 |
181 if ( ! $dims ) { |
182 if ( ! $dims ) { |
182 return new WP_Error( 'error_getting_dimensions', __( 'Could not calculate resized image dimensions' ), $this->file ); |
183 return new WP_Error( 'error_getting_dimensions', __( 'Could not calculate resized image dimensions' ), $this->file ); |
183 } |
184 } |
|
185 |
184 list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims; |
186 list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims; |
185 |
187 |
186 $resized = wp_imagecreatetruecolor( $dst_w, $dst_h ); |
188 $resized = wp_imagecreatetruecolor( $dst_w, $dst_h ); |
187 imagecopyresampled( $resized, $this->image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ); |
189 imagecopyresampled( $resized, $this->image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ); |
188 |
190 |
193 |
195 |
194 return new WP_Error( 'image_resize_error', __( 'Image resize failed.' ), $this->file ); |
196 return new WP_Error( 'image_resize_error', __( 'Image resize failed.' ), $this->file ); |
195 } |
197 } |
196 |
198 |
197 /** |
199 /** |
198 * Resize multiple images from a single source. |
200 * Create multiple smaller images from a single source. |
|
201 * |
|
202 * Attempts to create all sub-sizes and returns the meta data at the end. This |
|
203 * may result in the server running out of resources. When it fails there may be few |
|
204 * "orphaned" images left over as the meta data is never returned and saved. |
|
205 * |
|
206 * As of 5.3.0 the preferred way to do this is with `make_subsize()`. It creates |
|
207 * the new images one at a time and allows for the meta data to be saved after |
|
208 * each new image is created. |
199 * |
209 * |
200 * @since 3.5.0 |
210 * @since 3.5.0 |
201 * |
211 * |
202 * @param array $sizes { |
212 * @param array $sizes { |
203 * An array of image size arrays. Default sizes are 'small', 'medium', 'medium_large', 'large'. |
213 * An array of image size data arrays. |
204 * |
214 * |
205 * Either a height or width must be provided. |
215 * Either a height or width must be provided. |
206 * If one of the two is set to null, the resize will |
216 * If one of the two is set to null, the resize will |
207 * maintain aspect ratio according to the provided dimension. |
217 * maintain aspect ratio according to the source image. |
208 * |
218 * |
209 * @type array $size { |
219 * @type array $size { |
210 * Array of height, width values, and whether to crop. |
220 * Array of height, width values, and whether to crop. |
211 * |
221 * |
212 * @type int $width Image width. Optional if `$height` is specified. |
222 * @type int $width Image width. Optional if `$height` is specified. |
215 * } |
225 * } |
216 * } |
226 * } |
217 * @return array An array of resized images' metadata by size. |
227 * @return array An array of resized images' metadata by size. |
218 */ |
228 */ |
219 public function multi_resize( $sizes ) { |
229 public function multi_resize( $sizes ) { |
220 $metadata = array(); |
230 $metadata = array(); |
|
231 |
|
232 foreach ( $sizes as $size => $size_data ) { |
|
233 $meta = $this->make_subsize( $size_data ); |
|
234 |
|
235 if ( ! is_wp_error( $meta ) ) { |
|
236 $metadata[ $size ] = $meta; |
|
237 } |
|
238 } |
|
239 |
|
240 return $metadata; |
|
241 } |
|
242 |
|
243 /** |
|
244 * Create an image sub-size and return the image meta data value for it. |
|
245 * |
|
246 * @since 5.3.0 |
|
247 * |
|
248 * @param array $size_data { |
|
249 * Array of size data. |
|
250 * |
|
251 * @type int $width The maximum width in pixels. |
|
252 * @type int $height The maximum height in pixels. |
|
253 * @type bool $crop Whether to crop the image to exact dimensions. |
|
254 * } |
|
255 * @return array|WP_Error The image data array for inclusion in the `sizes` array in the image meta, |
|
256 * WP_Error object on error. |
|
257 */ |
|
258 public function make_subsize( $size_data ) { |
|
259 if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) { |
|
260 return new WP_Error( 'image_subsize_create_error', __( 'Cannot resize the image. Both width and height are not set.' ) ); |
|
261 } |
|
262 |
221 $orig_size = $this->size; |
263 $orig_size = $this->size; |
222 |
264 |
223 foreach ( $sizes as $size => $size_data ) { |
265 if ( ! isset( $size_data['width'] ) ) { |
224 if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) { |
266 $size_data['width'] = null; |
225 continue; |
267 } |
226 } |
268 |
227 |
269 if ( ! isset( $size_data['height'] ) ) { |
228 if ( ! isset( $size_data['width'] ) ) { |
270 $size_data['height'] = null; |
229 $size_data['width'] = null; |
271 } |
230 } |
272 |
231 if ( ! isset( $size_data['height'] ) ) { |
273 if ( ! isset( $size_data['crop'] ) ) { |
232 $size_data['height'] = null; |
274 $size_data['crop'] = false; |
233 } |
275 } |
234 |
276 |
235 if ( ! isset( $size_data['crop'] ) ) { |
277 $resized = $this->_resize( $size_data['width'], $size_data['height'], $size_data['crop'] ); |
236 $size_data['crop'] = false; |
278 |
237 } |
279 if ( is_wp_error( $resized ) ) { |
238 |
280 $saved = $resized; |
239 $image = $this->_resize( $size_data['width'], $size_data['height'], $size_data['crop'] ); |
281 } else { |
240 $duplicate = ( ( $orig_size['width'] == $size_data['width'] ) && ( $orig_size['height'] == $size_data['height'] ) ); |
282 $saved = $this->_save( $resized ); |
241 |
283 imagedestroy( $resized ); |
242 if ( ! is_wp_error( $image ) && ! $duplicate ) { |
284 } |
243 $resized = $this->_save( $image ); |
285 |
244 |
286 $this->size = $orig_size; |
245 imagedestroy( $image ); |
287 |
246 |
288 if ( ! is_wp_error( $saved ) ) { |
247 if ( ! is_wp_error( $resized ) && $resized ) { |
289 unset( $saved['path'] ); |
248 unset( $resized['path'] ); |
290 } |
249 $metadata[ $size ] = $resized; |
291 |
250 } |
292 return $saved; |
251 } |
|
252 |
|
253 $this->size = $orig_size; |
|
254 } |
|
255 |
|
256 return $metadata; |
|
257 } |
293 } |
258 |
294 |
259 /** |
295 /** |
260 * Crops Image. |
296 * Crops Image. |
261 * |
297 * |
269 * @param int $dst_h Optional. The destination height. |
305 * @param int $dst_h Optional. The destination height. |
270 * @param bool $src_abs Optional. If the source crop points are absolute. |
306 * @param bool $src_abs Optional. If the source crop points are absolute. |
271 * @return bool|WP_Error |
307 * @return bool|WP_Error |
272 */ |
308 */ |
273 public function crop( $src_x, $src_y, $src_w, $src_h, $dst_w = null, $dst_h = null, $src_abs = false ) { |
309 public function crop( $src_x, $src_y, $src_w, $src_h, $dst_w = null, $dst_h = null, $src_abs = false ) { |
274 // If destination width/height isn't specified, use same as |
310 // If destination width/height isn't specified, |
275 // width/height from source. |
311 // use same as width/height from source. |
276 if ( ! $dst_w ) { |
312 if ( ! $dst_w ) { |
277 $dst_w = $src_w; |
313 $dst_w = $src_w; |
278 } |
314 } |
279 if ( ! $dst_h ) { |
315 if ( ! $dst_h ) { |
280 $dst_h = $src_h; |
316 $dst_h = $src_h; |
377 |
413 |
378 return $saved; |
414 return $saved; |
379 } |
415 } |
380 |
416 |
381 /** |
417 /** |
382 * @param resource $image |
418 * @param resource $image |
383 * @param string|null $filename |
419 * @param string|null $filename |
384 * @param string|null $mime_type |
420 * @param string|null $mime_type |
385 * @return WP_Error|array |
421 * @return array|WP_Error |
386 */ |
422 */ |
387 protected function _save( $image, $filename = null, $mime_type = null ) { |
423 protected function _save( $image, $filename = null, $mime_type = null ) { |
388 list( $filename, $extension, $mime_type ) = $this->get_output_format( $filename, $mime_type ); |
424 list( $filename, $extension, $mime_type ) = $this->get_output_format( $filename, $mime_type ); |
389 |
425 |
390 if ( ! $filename ) { |
426 if ( ! $filename ) { |
391 $filename = $this->generate_filename( null, null, $extension ); |
427 $filename = $this->generate_filename( null, null, $extension ); |
392 } |
428 } |
393 |
429 |
394 if ( 'image/gif' == $mime_type ) { |
430 if ( 'image/gif' === $mime_type ) { |
395 if ( ! $this->make_image( $filename, 'imagegif', array( $image, $filename ) ) ) { |
431 if ( ! $this->make_image( $filename, 'imagegif', array( $image, $filename ) ) ) { |
396 return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); |
432 return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); |
397 } |
433 } |
398 } elseif ( 'image/png' == $mime_type ) { |
434 } elseif ( 'image/png' === $mime_type ) { |
399 // convert from full colors to index colors, like original PNG. |
435 // Convert from full colors to index colors, like original PNG. |
400 if ( function_exists( 'imageistruecolor' ) && ! imageistruecolor( $image ) ) { |
436 if ( function_exists( 'imageistruecolor' ) && ! imageistruecolor( $image ) ) { |
401 imagetruecolortopalette( $image, false, imagecolorstotal( $image ) ); |
437 imagetruecolortopalette( $image, false, imagecolorstotal( $image ) ); |
402 } |
438 } |
403 |
439 |
404 if ( ! $this->make_image( $filename, 'imagepng', array( $image, $filename ) ) ) { |
440 if ( ! $this->make_image( $filename, 'imagepng', array( $image, $filename ) ) ) { |
405 return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); |
441 return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); |
406 } |
442 } |
407 } elseif ( 'image/jpeg' == $mime_type ) { |
443 } elseif ( 'image/jpeg' === $mime_type ) { |
408 if ( ! $this->make_image( $filename, 'imagejpeg', array( $image, $filename, $this->get_quality() ) ) ) { |
444 if ( ! $this->make_image( $filename, 'imagejpeg', array( $image, $filename, $this->get_quality() ) ) ) { |
409 return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); |
445 return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); |
410 } |
446 } |
411 } else { |
447 } else { |
412 return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); |
448 return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); |
413 } |
449 } |
414 |
450 |
415 // Set correct file permissions |
451 // Set correct file permissions. |
416 $stat = stat( dirname( $filename ) ); |
452 $stat = stat( dirname( $filename ) ); |
417 $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits |
453 $perms = $stat['mode'] & 0000666; // Same permissions as parent folder, strip off the executable bits. |
418 @ chmod( $filename, $perms ); |
454 chmod( $filename, $perms ); |
419 |
455 |
420 /** |
|
421 * Filters the name of the saved image file. |
|
422 * |
|
423 * @since 2.6.0 |
|
424 * |
|
425 * @param string $filename Name of the file. |
|
426 */ |
|
427 return array( |
456 return array( |
428 'path' => $filename, |
457 'path' => $filename, |
|
458 /** |
|
459 * Filters the name of the saved image file. |
|
460 * |
|
461 * @since 2.6.0 |
|
462 * |
|
463 * @param string $filename Name of the file. |
|
464 */ |
429 'file' => wp_basename( apply_filters( 'image_make_intermediate_size', $filename ) ), |
465 'file' => wp_basename( apply_filters( 'image_make_intermediate_size', $filename ) ), |
430 'width' => $this->size['width'], |
466 'width' => $this->size['width'], |
431 'height' => $this->size['height'], |
467 'height' => $this->size['height'], |
432 'mime-type' => $mime_type, |
468 'mime-type' => $mime_type, |
433 ); |
469 ); |