wordpress從頂部開(kāi)始裁剪圖片的方法
wordpress默認(rèn)情況下,裁剪的圖片會(huì)直接裁剪圖片的中間部分,例如你上傳了一張美女圖片,上傳上去由于圖片的尺寸超出了內(nèi)部規(guī)定的尺寸,wordpress會(huì)對(duì)其進(jìn)行裁剪,按照規(guī)定的尺寸裁剪好后生成另外一張圖片進(jìn)行保存,可惜的是,當(dāng)你調(diào)用這張圖片的時(shí)候發(fā)現(xiàn),美女的頭被卡擦了,這樣的縮略圖完全失去了吸引讀者的功效,下面我們就來(lái)解決這個(gè)問(wèn)題
<?php
/* Example Usage:
* bt_add_image_size( 'product-screenshot', 300, 300, array( 'left', 'top' ) );
* bt_add_image_size( 'product-feature', 460, 345, array( 'center', 'top' ) );
*/
add_filter( 'intermediate_image_sizes_advanced', 'bt_intermediate_image_sizes_advanced' );
add_filter( 'wp_generate_attachment_metadata', 'bt_generate_attachment_metadata', 10, 2 );
/**
* Registers a new image size with cropping positions
*
* The $crop parameter works as in the 'add_image_size' function taking true or
* false values. If set to true, the default cropping position is 'center', 'center'.
*
* The $crop parameter also takes an array of the format
* array( x_crop_position, y_crop_position )
* x_crop_position can be 'left', 'center', 'right'
* y_crop_position can be 'top', 'center', 'bottom'
*
* @param string $name Image size identifier.
* @param int $width Image width.
* @param int $height Image height.
* @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.
* @return bool|array False, if no image was created. Metadata array on success.
*/
function bt_add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
global $_wp_additional_image_sizes;
$_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => $crop );
}
/**
* Returning no sizes (an empty array) will force
* wp_generate_attachment_metadata to skip creating intermediate image sizes on
* upload, then we can run our own resizing functions by hooking into the
* 'wp_generate_attachment_metadata' filter
*/
function bt_intermediate_image_sizes_advanced( $sizes ) {
return array();
}
function bt_generate_attachment_metadata( $metadata, $attachment_id ) {
$attachment = get_post( $attachment_id );
$uploadPath = wp_upload_dir();
$file = path_join($uploadPath['basedir'], $metadata['file']);
if ( !preg_match('!^image/!', get_post_mime_type( $attachment )) || !file_is_displayable_image( $file ) ) return $metadata;
global $_wp_additional_image_sizes;
foreach ( get_intermediate_image_sizes() as $s ) {
$sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => FALSE );
if ( isset( $_wp_additional_image_sizes[$s]['width'] ) )
$sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] ); // For theme-added sizes
else
$sizes[$s]['width'] = get_option( "{$s}_size_w" ); // For default sizes set in options
if ( isset( $_wp_additional_image_sizes[$s]['height'] ) )
$sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] ); // For theme-added sizes
else
$sizes[$s]['height'] = get_option( "{$s}_size_h" ); // For default sizes set in options
if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) )
$sizes[$s]['crop'] = $_wp_additional_image_sizes[$s]['crop'];
else
$sizes[$s]['crop'] = get_option( "{$s}_crop" );
}
foreach ( $sizes as $size => $size_data ) {
$resized = bt_image_make_intermediate_size( $file, $size_data['width'], $size_data['height'], $size_data['crop'] );
if ( $resized )
$metadata['sizes'][$size] = $resized;
}
return $metadata;
}
/**
* Resize an image to make a thumbnail or intermediate size.
*
* The returned array has the file size, the image width, and image height. The
* filter 'image_make_intermediate_size' can be used to hook in and change the
* values of the returned array. The only parameter is the resized file path.
*
* @param string $file File path.
* @param int $width Image width.
* @param int $height Image height.
* @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.
* @return bool|array False, if no image was created. Metadata array on success.
*/
function bt_image_make_intermediate_size( $file, $width, $height, $crop = false ) {
if ( $width || $height ) {
$resized_file = bt_image_resize( $file, $width, $height, $crop, null, null, 90 );
if ( !is_wp_error( $resized_file ) && $resized_file && $info = getimagesize( $resized_file ) ) {
$resized_file = apply_filters('image_make_intermediate_size', $resized_file);
return array(
'file' => wp_basename( $resized_file ),
'width' => $info[0],
'height' => $info[1],
);
}
}
return false;
}
/**
* Retrieve calculated resized dimensions for use in imagecopyresampled().
*
* Calculate dimensions and coordinates for a resized image that fits within a
* specified width and height. If $crop is true, the largest matching central
* portion of the image will be cropped out and resized to the required size.
*
* @param int $orig_w Original width.
* @param int $orig_h Original height.
* @param int $dest_w New width.
* @param int $dest_h New height.
* @param bool $crop Optional, default is false. Whether to crop image or resize.
* @return bool|array False, on failure. Returned array matches parameters for imagecopyresampled() PHP function.
*/
function bt_image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = false) {
if ($orig_w <= 0 || $orig_h <= 0)
return false;
// at least one of dest_w or dest_h must be specific
if ($dest_w <= 0 && $dest_h <= 0)
return false;
if ( $crop ) {
// crop the largest possible portion of the original image that we can size to $dest_w x $dest_h
$aspect_ratio = $orig_w / $orig_h;
$new_w = min($dest_w, $orig_w);
$new_h = min($dest_h, $orig_h);
if ( !$new_w ) {
$new_w = intval($new_h * $aspect_ratio);
}
if ( !$new_h ) {
$new_h = intval($new_w / $aspect_ratio);
}
$size_ratio = max($new_w / $orig_w, $new_h / $orig_h);
$crop_w = round($new_w / $size_ratio);
$crop_h = round($new_h / $size_ratio);
if ( !is_array( $crop ) || count( $crop ) != 2 ) {
$crop = apply_filters( 'image_resize_crop_default', array( 'center', 'center' ) );
}
switch ( $crop[0] ) {
case 'left': $s_x = 0; break;
case 'right': $s_x = $orig_w - $crop_w; break;
default: $s_x = floor( ( $orig_w - $crop_w ) / 2 );
}
switch ( $crop[1] ) {
case 'top': $s_y = 0; break;
case 'bottom': $s_y = $orig_h - $crop_h; break;
default: $s_y = floor( ( $orig_h - $crop_h ) / 2 );
}
} else {
// don't crop, just resize using $dest_w x $dest_h as a maximum bounding box
$crop_w = $orig_w;
$crop_h = $orig_h;
$s_x = 0;
$s_y = 0;
list( $new_w, $new_h ) = wp_constrain_dimensions( $orig_w, $orig_h, $dest_w, $dest_h );
}
// if the resulting image would be the same size or larger we don't want to resize it
if ( $new_w >= $orig_w && $new_h >= $orig_h )
return false;
// the return array matches the parameters to imagecopyresampled()
// int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h
return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h );
}
/**
* Scale down an image to fit a particular size and save a new copy of the image.
*
* The PNG transparency will be preserved using the function, as well as the
* image type. If the file going in is PNG, then the resized image is going to
* be PNG. The only supported image types are PNG, GIF, and JPEG.
*
* Some functionality requires API to exist, so some PHP version may lose out
* support. This is not the fault of WordPress (where functionality is
* downgraded, not actual defects), but of your PHP version.
*
* @since 2.5.0
*
* @param string $file Image file path.
* @param int $max_w Maximum width to resize to.
* @param int $max_h Maximum height to resize to.
* @param bool $crop Optional. Whether to crop image or resize.
* @param string $suffix Optional. File Suffix.
* @param string $dest_path Optional. New image file path.
* @param int $jpeg_quality Optional, default is 90. Image quality percentage.
* @return mixed WP_Error on failure. String with new destination path.
*/
function bt_image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
$image = wp_load_image( $file );
if ( !is_resource( $image ) )
return new WP_Error( 'error_loading_image', $image, $file );
$size = @getimagesize( $file );
if ( !$size )
return new WP_Error('invalid_image', __('Could not read image size'), $file);
list($orig_w, $orig_h, $orig_type) = $size;
// Rotate if EXIF 'Orientation' is set
// This code is from the reverted patch at
// <a >http://core.trac.wordpress.org/changeset/11746/trunk/wp-includes/media.php</a>
$rotate = false;
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 ) ) ) ) {
$exif = @exif_read_data( $file, null, true );
if ( $exif && isset( $exif['IFD0'] ) && is_array( $exif['IFD0'] ) && isset( $exif['IFD0']['Orientation'] ) ) {
if ( 6 == $exif['IFD0']['Orientation'] )
$rotate = 90;
elseif ( 8 == $exif['IFD0']['Orientation'] )
$rotate = 270;
}
}
if ( $rotate )
list($max_h,$max_w) = array($max_w,$max_h);
$dims = bt_image_resize_dimensions($orig_w, $orig_h, $max_w, $max_h, $crop);
if ( !$dims )
return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') );
list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims;
$newimage = wp_imagecreatetruecolor( $dst_w, $dst_h );
if ( $rotate )
list($src_y,$src_x) = array($src_x,$src_y);
imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
// convert from full colors to index colors, like original PNG.
if ( IMAGETYPE_PNG == $orig_type && function_exists('imageistruecolor') && !imageistruecolor( $image ) )
imagetruecolortopalette( $newimage, false, imagecolorstotal( $image ) );
// we don't need the original in memory anymore
imagedestroy( $image );
// $suffix will be appended to the destination filename, just before the extension
if ( !$suffix ) {
if ( $rotate )
$suffix = "{$dst_h}x{$dst_w}";
else
$suffix = "{$dst_w}x{$dst_h}";
}
$info = pathinfo($file);
$dir = $info['dirname'];
$ext = $info['extension'];
$name = wp_basename($file, ".$ext");
if ( !is_null($dest_path) and $_dest_path = realpath($dest_path) )
$dir = $_dest_path;
$destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
if ( IMAGETYPE_GIF == $orig_type ) {
if ( !imagegif( $newimage, $destfilename ) )
return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
} elseif ( IMAGETYPE_PNG == $orig_type ) {
if ( !imagepng( $newimage, $destfilename ) )
return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
} else {
if ( $rotate ) {
$newimage = _rotate_image_resource( $newimage, 360 - $rotate );
}
// all other formats are converted to jpg
$destfilename = "{$dir}/{$name}-{$suffix}.jpg";
$return = imagejpeg( $newimage, $destfilename, apply_filters( 'jpeg_quality', $jpeg_quality, 'image_resize' ) );
if ( !$return )
return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
}
imagedestroy( $newimage );
// Set correct file permissions
$stat = stat( dirname( $destfilename ));
$perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
@ chmod( $destfilename, $perms );
return $destfilename;
}
這種方法需要你用bt_add_image_size代替原來(lái)我們習(xí)慣的add_image_size,具體的使用方法我們就不詳細(xì)解釋?zhuān)傊@個(gè)函數(shù)給出了第三個(gè)參數(shù),讓你可以規(guī)定裁剪的開(kāi)始位置。
而實(shí)際上,更為簡(jiǎn)潔的方法是,我找到一個(gè)插件,似乎可以實(shí)現(xiàn)這個(gè)功能,你不妨下載嘗試。
Shailan.com Staff則提供了一個(gè)更直接的方法,就是修改wordpress系統(tǒng)文件/wp-includes/media.php,找到:
$s_x = floor( ($orig_w - $crop_w) / 2 );
$s_y = floor( ($orig_h - $crop_h) / 2 );
把其中的$s_y修改為:
$s_y = 0;// 或者你想要的值
總之,這種方法直接有效且最容易令人理解,因?yàn)?s_x和$s_y就是wordpress系統(tǒng)在裁剪時(shí),裁剪區(qū)域的起始位置。而且他還推薦了一個(gè)插件:Regenerate Thumbnails,應(yīng)是基于這種方法來(lái)實(shí)現(xiàn)的。
在stackexchange社區(qū)還有人用這樣的方法更加便捷,或許你可以借鑒,但是否奏效還需要驗(yàn)證:
add_filter('wp_generate_attachment_metadata', 'custom_crop');</p> <p>function custom_crop($metadata) {</p> <p> $uploads = wp_upload_dir();
$file = path_join( $uploads['basedir'], $metadata['file'] ); // original image file
list( $year, $month ) = explode( '/', $metadata['file'] );
$target = path_join( $uploads['basedir'], "{$year}/{$month}/".$metadata['sizes']['medium']['file'] ); // intermediate size file
$image = imagecreatefromjpeg($file); // original image resource
$image_target = wp_imagecreatetruecolor( 44, 44 ); // blank image to fill
imagecopyresampled($image_target, $image, 0, 0, 25, 15, 44, 44, 170, 170); // crop original
imagejpeg($image_target, $target, apply_filters( 'jpeg_quality', 90, 'image_resize' )); // write cropped to file</p> <p> return $metadata;
}
相關(guān)文章

CyberPanel安裝WordPress并配置偽靜態(tài)規(guī)則
下面教你如何在 CyberPanel安裝WordPress以及配置偽靜態(tài),需要的朋友可以參考下2023-12-27
這篇文章主要介紹了wordpress無(wú)法安裝更新主題插件的解決辦法,需要的朋友可以參考下2020-12-27WordPress必備數(shù)據(jù)庫(kù)SQL查詢語(yǔ)句整理
發(fā)現(xiàn)幾條比較實(shí)用的,適合 WordPress 實(shí)用的SQL語(yǔ)句。于是就趕緊收集分享出來(lái)了,需要的朋友可以參考下2017-09-23wordpress在安裝使用中出現(xiàn)404、403、500及502問(wèn)題的分析與解決方法
wordpress是很多新手站長(zhǎng)搭建個(gè)人博客最喜愛(ài)的程序,但是最近在使用WordPress的時(shí)候遇到了一些問(wèn)題,所以想著將遇到問(wèn)題總結(jié)分享出來(lái),下面這篇文章主要給大家介紹了關(guān)于wo2017-08-11WordPress取消英文標(biāo)點(diǎn)符號(hào)自動(dòng)替換中文標(biāo)點(diǎn)符號(hào)的優(yōu)雅方法
這篇文章主要介紹了WordPress取消英文標(biāo)點(diǎn)符號(hào)自動(dòng)替換中文標(biāo)點(diǎn)符號(hào)的優(yōu)雅方法,需要的朋友可以參考下2017-04-04- 這篇文章主要給大家介紹了wordpress自定義上傳文件類(lèi)型的方法,如WordPress默認(rèn)允許上傳 .exe 后綴名的可運(yùn)行文件,那么我們?cè)趺唇褂脩粼赪ordPress后臺(tái)發(fā)表文章時(shí)上傳 .e2016-12-19
- 大家可能發(fā)現(xiàn)了當(dāng)實(shí)現(xiàn)了前端用戶中心,后臺(tái)控制面板就失去了作用,那么限制其他用戶進(jìn)入后臺(tái)控制面板就很有必要了!那么我們要怎么做呢?通過(guò)下面這篇文章分享的方法后,只2016-12-19
WordPress實(shí)現(xiàn)回復(fù)文章評(píng)論后發(fā)送郵件通知的功能
這篇文章主要介紹了WordPress實(shí)現(xiàn)回復(fù)文章評(píng)論后發(fā)送郵件通知的功能,涉及wordpress針對(duì)評(píng)論與郵件的相關(guān)操作技巧,需要的朋友可以參考下2016-10-11WordPress使用自定義文章類(lèi)型實(shí)現(xiàn)任意模板的方法
這篇文章主要介紹了WordPress使用自定義文章類(lèi)型實(shí)現(xiàn)任意模板的方法,可通過(guò)自定義文章類(lèi)型來(lái)實(shí)現(xiàn)任意模版的使用,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-10-11WordPress后臺(tái)地址被改導(dǎo)致無(wú)法登陸后臺(tái)的簡(jiǎn)單解決方法
這篇文章主要介紹了WordPress后臺(tái)地址被改導(dǎo)致無(wú)法登陸后臺(tái)的簡(jiǎn)單解決方法,簡(jiǎn)單分析了后臺(tái)無(wú)法登陸的原因與相應(yīng)的解決方法,涉及針對(duì)wordpress配置項(xiàng)的簡(jiǎn)單修改,需要的朋友2016-10-11


