G2A Many GEOs
SHARE
TWEET

WPSE 51920

brasofilo May 12th, 2012 533 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2. /* Original code from:
  3.  * http://bradt.ca/archives/image-crop-position-in-wordpress/
  4.  *
  5.  * Modified to WordPress Answers:
  6.  * http://wordpress.stackexchange.com/q/51920/12615
  7.  *
  8.  * Check the function bt_image_make_intermediate_size
  9.  * That's where the Thumbnails renaming occurs and all added images must be inserted
  10.  */
  11.  
  12. /* Example Usage:
  13.  * bt_add_image_size( 'product-screenshot', 300, 300, array( 'left', 'top' ) );
  14.  * bt_add_image_size( 'product-feature', 460, 345, array( 'center', 'top' ) );
  15.  */
  16. add_filter( 'intermediate_image_sizes_advanced', 'bt_intermediate_image_sizes_advanced' );
  17. add_filter( 'wp_generate_attachment_metadata', 'bt_generate_attachment_metadata', 10, 2 );
  18.  
  19. /**
  20.  * Registers a new image size with cropping positions
  21.  *
  22.  * The $crop parameter works as in the 'add_image_size' function taking true or
  23.  * false values. If set to true, the default cropping position is 'center', 'center'.
  24.  *
  25.  * The $crop parameter also takes an array of the format
  26.  * array( x_crop_position, y_crop_position )
  27.  * x_crop_position can be 'left', 'center', 'right'
  28.  * y_crop_position can be 'top', 'center', 'bottom'
  29.  *
  30.  * @param string $name Image size identifier.
  31.  * @param int $width Image width.
  32.  * @param int $height Image height.
  33.  * @param bool|array $crop Optional, default is false. Whether to crop image to specified height and width or resize. An array can specify positioning of the crop area.
  34.  * @return bool|array False, if no image was created. Metadata array on success.
  35.  */
  36. function bt_add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
  37.         global $_wp_additional_image_sizes;
  38.         $_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => $crop );
  39. }
  40.  
  41.  
  42. /**
  43.  * Returning no sizes (an empty array) will force
  44.  * wp_generate_attachment_metadata to skip creating intermediate image sizes on
  45.  * upload, then we can run our own resizing functions by hooking into the
  46.  * 'wp_generate_attachment_metadata' filter
  47.  */
  48. function bt_intermediate_image_sizes_advanced( $sizes ) {
  49.         return array();
  50. }
  51.  
  52.  
  53. function bt_generate_attachment_metadata( $metadata, $attachment_id ) {
  54.     $attachment = get_post( $attachment_id );
  55.    
  56.     $uploadPath = wp_upload_dir();
  57.     $file = path_join($uploadPath['basedir'], $metadata['file']);
  58.  
  59.         if ( !preg_match('!^image/!', get_post_mime_type( $attachment )) || !file_is_displayable_image( $file ) ) return $metadata;
  60.  
  61.     global $_wp_additional_image_sizes;
  62.  
  63.     foreach ( get_intermediate_image_sizes() as $s ) {
  64.         $sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => FALSE );
  65.         if ( isset( $_wp_additional_image_sizes[$s]['width'] ) )
  66.             $sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] ); // For theme-added sizes
  67.         else
  68.             $sizes[$s]['width'] = get_option( "{$s}_size_w" ); // For default sizes set in options
  69.         if ( isset( $_wp_additional_image_sizes[$s]['height'] ) )
  70.             $sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] ); // For theme-added sizes
  71.         else
  72.             $sizes[$s]['height'] = get_option( "{$s}_size_h" ); // For default sizes set in options
  73.         if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) )
  74.             $sizes[$s]['crop'] = $_wp_additional_image_sizes[$s]['crop'];
  75.         else
  76.             $sizes[$s]['crop'] = get_option( "{$s}_crop" );
  77.     }
  78.  
  79.     foreach ( $sizes as $size => $size_data ) {
  80.         $resized = bt_image_make_intermediate_size( $file, $size_data['width'], $size_data['height'], $size_data['crop'], $size );
  81.         if ( $resized )
  82.             $metadata['sizes'][$size] = $resized;
  83.     }
  84.    
  85.     return $metadata;
  86. }
  87.  
  88.  
  89. /**
  90.  * Resize an image to make a thumbnail or intermediate size.
  91.  *
  92.  * The returned array has the file size, the image width, and image height. The
  93.  * filter 'image_make_intermediate_size' can be used to hook in and change the
  94.  * values of the returned array. The only parameter is the resized file path.
  95.  *
  96.  * @param string $file File path.
  97.  * @param int $width Image width.
  98.  * @param int $height Image height.
  99.  * @param bool|array $crop Optional, default is false. Whether to crop image to specified height and width or resize. An array can specify positioning of the crop area.
  100.  * @return bool|array False, if no image was created. Metadata array on success.
  101.  */
  102. function bt_image_make_intermediate_size( $file, $width, $height, $crop = false, $size ) {
  103.         if ( $width || $height ) {
  104.                 switch($size) {
  105.                         case 'thumbnail':
  106.                                 $suffix = 't';
  107.                                 break;
  108.                         case 'medium':
  109.                                 $suffix = 'm';
  110.                                 break;
  111.                         case 'large':
  112.                                 $suffix = 'l';
  113.                                 break;
  114.                         default:
  115.                                 $suffix = null;
  116.                                 break;
  117.                 }
  118.                 $resized_file = bt_image_resize( $file, $width, $height, $crop, $suffix, null, 90 );
  119.                 if ( !is_wp_error( $resized_file ) && $resized_file && $info = getimagesize( $resized_file ) ) {
  120.                         $resized_file = apply_filters('image_make_intermediate_size', $resized_file);
  121.                         return array(
  122.                                 'file' => wp_basename( $resized_file ),
  123.                                 'width' => $info[0],
  124.                                 'height' => $info[1],
  125.                         );
  126.                 }
  127.         }
  128.         return false;
  129. }
  130.  
  131.  
  132.  
  133. /**
  134.  * Retrieve calculated resized dimensions for use in imagecopyresampled().
  135.  *
  136.  * Calculate dimensions and coordinates for a resized image that fits within a
  137.  * specified width and height. If $crop is true, the largest matching central
  138.  * portion of the image will be cropped out and resized to the required size.
  139.  *
  140.  * @param int $orig_w Original width.
  141.  * @param int $orig_h Original height.
  142.  * @param int $dest_w New width.
  143.  * @param int $dest_h New height.
  144.  * @param bool $crop Optional, default is false. Whether to crop image or resize.
  145.  * @return bool|array False, on failure. Returned array matches parameters for imagecopyresampled() PHP function.
  146.  */
  147. function bt_image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = false) {
  148.  
  149.         if ($orig_w <= 0 || $orig_h <= 0)
  150.                 return false;
  151.         // at least one of dest_w or dest_h must be specific
  152.         if ($dest_w <= 0 && $dest_h <= 0)
  153.                 return false;
  154.  
  155.         if ( $crop ) {
  156.                 // crop the largest possible portion of the original image that we can size to $dest_w x $dest_h
  157.                 $aspect_ratio = $orig_w / $orig_h;
  158.                 $new_w = min($dest_w, $orig_w);
  159.                 $new_h = min($dest_h, $orig_h);
  160.  
  161.                 if ( !$new_w ) {
  162.                         $new_w = intval($new_h * $aspect_ratio);
  163.                 }
  164.  
  165.                 if ( !$new_h ) {
  166.                         $new_h = intval($new_w / $aspect_ratio);
  167.                 }
  168.  
  169.                 $size_ratio = max($new_w / $orig_w, $new_h / $orig_h);
  170.  
  171.                 $crop_w = round($new_w / $size_ratio);
  172.                 $crop_h = round($new_h / $size_ratio);
  173.  
  174.         if ( !is_array( $crop ) || count( $crop ) != 2 ) {
  175.                         $crop = apply_filters( 'image_resize_crop_default', array( 'center', 'center' ) );
  176.                 }
  177.                
  178.                 switch ( $crop[0] ) {
  179.                         case 'left': $s_x = 0; break;
  180.                         case 'right': $s_x = $orig_w - $crop_w; break;
  181.                         default: $s_x = floor( ( $orig_w - $crop_w ) / 2 );
  182.                 }
  183.  
  184.                 switch ( $crop[1] ) {
  185.                         case 'top': $s_y = 0; break;
  186.                         case 'bottom': $s_y = $orig_h - $crop_h; break;
  187.                         default: $s_y = floor( ( $orig_h - $crop_h ) / 2 );
  188.                 }
  189.         } else {
  190.                 // don't crop, just resize using $dest_w x $dest_h as a maximum bounding box
  191.                 $crop_w = $orig_w;
  192.                 $crop_h = $orig_h;
  193.  
  194.                 $s_x = 0;
  195.                 $s_y = 0;
  196.  
  197.                 list( $new_w, $new_h ) = wp_constrain_dimensions( $orig_w, $orig_h, $dest_w, $dest_h );
  198.         }
  199.  
  200.         // if the resulting image would be the same size or larger we don't want to resize it
  201.         if ( $new_w >= $orig_w && $new_h >= $orig_h )
  202.                 return false;
  203.  
  204.         // the return array matches the parameters to imagecopyresampled()
  205.         // int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h
  206.         return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h );
  207.  
  208. }
  209.  
  210.  
  211. /**
  212.  * Scale down an image to fit a particular size and save a new copy of the image.
  213.  *
  214.  * The PNG transparency will be preserved using the function, as well as the
  215.  * image type. If the file going in is PNG, then the resized image is going to
  216.  * be PNG. The only supported image types are PNG, GIF, and JPEG.
  217.  *
  218.  * Some functionality requires API to exist, so some PHP version may lose out
  219.  * support. This is not the fault of WordPress (where functionality is
  220.  * downgraded, not actual defects), but of your PHP version.
  221.  *
  222.  * @since 2.5.0
  223.  *
  224.  * @param string $file Image file path.
  225.  * @param int $max_w Maximum width to resize to.
  226.  * @param int $max_h Maximum height to resize to.
  227.  * @param bool $crop Optional. Whether to crop image or resize.
  228.  * @param string $suffix Optional. File Suffix.
  229.  * @param string $dest_path Optional. New image file path.
  230.  * @param int $jpeg_quality Optional, default is 90. Image quality percentage.
  231.  * @return mixed WP_Error on failure. String with new destination path.
  232.  */
  233. function bt_image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
  234.  
  235.         $image = wp_load_image( $file );
  236.         if ( !is_resource( $image ) )
  237.                 return new WP_Error( 'error_loading_image', $image, $file );
  238.  
  239.         $size = @getimagesize( $file );
  240.         if ( !$size )
  241.                 return new WP_Error('invalid_image', __('Could not read image size'), $file);
  242.         list($orig_w, $orig_h, $orig_type) = $size;
  243.  
  244.         // Rotate if EXIF 'Orientation' is set
  245.         // This code is from the reverted patch at
  246.         // http://core.trac.wordpress.org/changeset/11746/trunk/wp-includes/media.php
  247.         $rotate = false;
  248.         if ( is_callable( 'exif_read_data' ) && in_array( $orig_type, apply_filters( 'wp_read_image_metadata_types', array( IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM ) ) ) ) {
  249.                 $exif = @exif_read_data( $file, null, true );
  250.                 if ( $exif && isset( $exif['IFD0'] ) && is_array( $exif['IFD0'] ) && isset( $exif['IFD0']['Orientation'] ) ) {
  251.                         if ( 6 == $exif['IFD0']['Orientation'] )
  252.                                 $rotate = 90;
  253.                         elseif ( 8 == $exif['IFD0']['Orientation'] )
  254.                                 $rotate = 270;
  255.                 }
  256.         }
  257.        
  258.         if ( $rotate )
  259.                 list($max_h,$max_w) = array($max_w,$max_h);
  260.  
  261.         $dims = bt_image_resize_dimensions($orig_w, $orig_h, $max_w, $max_h, $crop);
  262.         if ( !$dims )
  263.                 return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') );
  264.         list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims;
  265.  
  266.         $newimage = wp_imagecreatetruecolor( $dst_w, $dst_h );
  267.  
  268.         if ( $rotate )
  269.                 list($src_y,$src_x) = array($src_x,$src_y);
  270.  
  271.         imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
  272.  
  273.         // convert from full colors to index colors, like original PNG.
  274.         if ( IMAGETYPE_PNG == $orig_type && function_exists('imageistruecolor') && !imageistruecolor( $image ) )
  275.                 imagetruecolortopalette( $newimage, false, imagecolorstotal( $image ) );
  276.  
  277.         // we don't need the original in memory anymore
  278.         imagedestroy( $image );
  279.  
  280.         // $suffix will be appended to the destination filename, just before the extension
  281.         if ( !$suffix ) {
  282.                 if ( $rotate )
  283.                         $suffix = "{$dst_h}x{$dst_w}";
  284.                 else
  285.                         $suffix = "{$dst_w}x{$dst_h}";
  286.         }
  287.  
  288.         $info = pathinfo($file);
  289.         $dir = $info['dirname'];
  290.         $ext = $info['extension'];
  291.         $name = wp_basename($file, ".$ext");
  292.  
  293.         if ( !is_null($dest_path) and $_dest_path = realpath($dest_path) )
  294.                 $dir = $_dest_path;
  295.         $destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
  296.  
  297.         if ( IMAGETYPE_GIF == $orig_type ) {
  298.                 if ( !imagegif( $newimage, $destfilename ) )
  299.                         return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
  300.         } elseif ( IMAGETYPE_PNG == $orig_type ) {
  301.                 if ( !imagepng( $newimage, $destfilename ) )
  302.                         return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
  303.         } else {
  304.                 if ( $rotate ) {
  305.                         $newimage = _rotate_image_resource( $newimage, 360 - $rotate );
  306.                 }
  307.                
  308.                 // all other formats are converted to jpg
  309.                 $destfilename = "{$dir}/{$name}-{$suffix}.jpg";
  310.                 $return = imagejpeg( $newimage, $destfilename, apply_filters( 'jpeg_quality', $jpeg_quality, 'image_resize' ) );
  311.                 if ( !$return )
  312.                         return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
  313.         }
  314.  
  315.         imagedestroy( $newimage );
  316.  
  317.         // Set correct file permissions
  318.         $stat = stat( dirname( $destfilename ));
  319.         $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
  320.         @ chmod( $destfilename, $perms );
  321.  
  322.         return $destfilename;
  323. }
RAW Paste Data
Ledger Nano X - The secure hardware wallet
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top