默认情况下,wordpress会直接裁剪图片的中间部分。这篇文章旨在让wordpress从顶部裁剪图片。请参考。
默认情况下,wordpress会直接剪切图片的中间部分。比如你上传了一张漂亮的图片,wordpress会因为图片尺寸超过规定尺寸而把它剪下来。按照指定尺寸裁剪出来后,会生成另一张图片并保存。不幸的是,当你调用这张图片时,你发现美女的头被卡片划伤了,这样的缩略图完全失去了吸引读者的效果。让我们来解决这个问题。
复制代码如下:
<?php
/*示例用法:
*Bt_add_image_size('product-截图',300,300,array('left','top');
*Bt_add_image_size('product-feature',460,345,array('center','top');
*/
add_filter('intermediate_image_size_advanced','Bt_intermediate_image_size_advanced');
add_filter('WP_generate_attachment_metadata','Bt_generate_attachment_metadata',10,2);
/**
*用裁剪位置注册新的图像尺寸
*
*$crop参数的工作方式与“add_image_size”函数相同,它采用true或
*false值。如果设置为true,默认的裁剪位置是“居中”、“居中”。
*
*crop参数也采用格式为
*array(x_crop_position,y_crop_position)
*x_crop_position可以是'left','center','right'
*y_crop_position可以是'top','center','bottom'
*
*@paramstring$name图像大小标识符。
*@paramint$width图像宽度。
*@paramint$height图像高度。
*@parambool|array$crop可选,默认值为false。是否将图像裁剪到指定的高度和宽度或调整大小。数组可以指定裁剪区域的位置。
*@如果没有创建图像,则返回bool|arrayFalse。成功时的元数据数组。
*/
函数bt_add_image_size($name,$width=0,$height=0,$crop=false){
global$_WP_additional_image_size;
$_WP_additional_image_size[$name]=array('width'=>;absint($width),'height'=>absint($height),'crop'=>$crop);
}
/**
*不返回大小(空数组)将强制
*WP_generate_attachment_metadata在
*上传时跳过创建中间图像大小,然后我们可以通过挂钩到
*"WP_generate_attachment_metadata'filter
*/
函数Bt_intermediate_image_size_advanced($size)来运行我们自己的调整大小函数{
}
函数Bt_generate_attachment_metadata($metadata,$attachment_id){
$attachment=get_post($attachment_id);
$uploadpath=WP_upload_dir();
$file=path_join($uploadpath['basedir'],$metadata['file']);
如果(!preg_match('!^image/!',get_post_mime_type($attachment))||!file_is_displayable_image($file))返回$metadata
global$_WP_additional_image_size;
foreach(get_intermediate_image_size()as$s){
$size[$s]=array('width'=>;','height'=>','crop'=>假);
if(isset($_WP_additional_image_size[$s]['width'])
$size[$s]['width']=intval($_WP_additional_image_size[$s]['width']);//Fortheme-addedsize
else
$size[$s]['width']=get_option("{$s}_size_w");//对于options
if中设置的默认大小(isset($_WP_additional_image_size[$s]['height'])
$size[$s]['height']=intval($_WP_additional_image_size[$s]['height']);//对于主题添加的size
else
$size[$s]['height']=get_option("{$s}_size_h");//对于options
if中设置的默认大小(isset($_WP_additional_image_size[$s]['crop'])
$size[$s]['crop']=$_WP_additional_image_size[$s]['crop'];
else
$size[$s]['crop']=get_option("{$s}_crop");
}
foreach($sizeas$size=>;$size_data){
$resized=Bt_image_make_intermediate_size($file,$size_data['width'],$size_data['height'],$size_data['crop']);
if($resized)
$metadata['size'][$size]=$resized;
}
return$metadata;
}
/**
*调整图像大小,使其成为缩略图或中间大小。
*
*返回的数组具有文件大小、图像宽度和图像高度。
*筛选器“image_make_intermediate_size”可用于挂钩并更改返回数组的
*值。唯一的参数是调整大小的文件路径。
*
*@paramstring$File文件路径。
*@paramint$width图像宽度。
*@paramint$height图像高度。
*@parambool|array$crop可选,默认值为false。是否将图像裁剪到指定的高度和宽度或调整大小。数组可以指定裁剪区域的位置。
*@如果没有创建图像,则返回bool|arrayFalse。成功时的元数据数组。
*/
函数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);
如果(!is_WP_error($resized_file)&;&$resized_file&&$info=getimagesize($resized_file)){
$resized_file=apply_filters('image_make_intermediate_size',$resized_file);
返回数组(
'file'=>;wp_basename($resized_file),
'width'=>;$info[0],
'height'=>;$info[1],
);
}
}
返回false
}
/**
*检索计算出的调整大小的尺寸,以便在imagecopyresampled()中使用。
*
*计算符合
*指定宽度和高度的调整后图像的尺寸和坐标。如果$crop为true,则图像的最大匹配中心
*部分将被裁剪掉并调整到所需的大小。
*
*@paramint$orig_w原始宽度。
*@paramint$orig_h原始高度。
*@paramint$dest_w新宽度。
*@paramint$dest_h新高度。
*@parambool$crop可选,默认值为false。是否裁剪图像或调整大小。
*@returnbool|arrayFalse,失败时。返回的数组匹配imagecopyresampled()PHP函数的参数。
*/
functionBt_image_resize_dimensions($orig_w,$orig_h,$dest_w,$dest_h,$crop=false){
if($orig_w<;=0||$orig_h<=0)
返回false
//dest_w或dest_h中至少有一个必须是特定的
if($dest_w<;=0&&$dest_h<=0)
返回false
if($crop){
//裁剪原始图像中我们可以调整到$dest_wx$dest_h
$aspect_ratio=$orig_w/$orig_h的最大可能部分;
$new_w=min($dest_w,$orig_w);
$new_h=min($dest_h,$orig_h);
如果(!$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);
如果(!is_array($crop)||count($crop)!=2){
$crop=apply_filters('image_resize_crop_default',array('center','center');
}
开关($crop[0]){
case'left':$s_x=0;打破;
case'right':$s_x=$orig_w-$crop_w;打破;
default:$s_x=floor(($orig_w-$crop_w)/2);
}
开关($crop[1]){
case'top':$s_y=0;打破;
case'bottom':$s_y=$orig_h-$crop_h;打破;
default:$s_y=floor(($orig_h-$crop_h)/2);
}
}else{
//不裁剪,只使用$dest_wx$dest_h作为最大边界框来调整大小
$crop_w=$orig_w;
$crop_h=$orig_h;
$s_x=0;
$s_y=0;
list($new_w,$new_h)=WP_constraint_dimensions($orig_w,$orig_h,$dest_w,$dest_h);
}
//如果生成的图像大小相同或更大,我们不想调整它的大小
,如果(new_w>=$orig_w&&$new_h>=$orig_h)
返回false
//返回数组匹配imagecopyresampled()
//intdst_x,intdst_y,intsrc_x,intsrc_y,intdst_w,intdst_h,intsrc_w,intsrc_h
返回数组(0,0,(int)$s_x,(int)$s_y,(int)$new_w,(int)$new_h,(int)$crop_w,(int)
}
/**
*缩小图像以适合特定的大小,并保存图像的新副本。
*
*使用该功能将保留PNG透明度,以及
*图像类型。如果传入的文件是PNG,那么调整大小后的图像将
*为PNG。唯一支持的图像类型是PNG、GIF和JPEG。
*
*一些功能需要API存在,因此一些PHP版本可能会失去
*支持。这不是WordPress的错(这里功能被
*降级,不是实际缺陷),而是你的PHP版本的错。
*
*@自2.5.0
*
*@paramstring$file镜像文件路径。
*@paramint$max_w要调整到的最大宽度。
*@paramint$max_h要调整到的最大高度。
*@parambool$crop可选。是否裁剪图像或调整大小。
*@paramstring$suffix可选。文件后缀。
*@paramstring$dest_path可选。新图像文件路径。
*@paramint$jpeg_quality可选,默认为90。图像质量百分比。
*@失败时返回混合WP_Error。带有新目标路径的字符串。
*/
函数bt_image_resize($file,$max_w,$max_h,$crop=false,$suffix=null,$dest_path=null,$JPEG_quality=90){
$image=WP_load_image($file);
如果(!is_resource($image))
返回新的WP_Error('error_loading_image',$image,$file);
$size=@getimagesize($file);
如果(!$size)
返回新的WP_Error('invalid_image',__('无法读取图像大小'),$file);
list($orig_w,$orig_h,$orig_type)=$size;
//如果设置了EXIF“方向”则旋转
//此代码来自位于
//<;ahref="http://core.TRAC.WordPress.org/changeset/11746/trunk/WP-includes/media.PHP">;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);
如果(!$dims)
返回新的WP_Error('Error_getting_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);
//从全色转换为索引色,就像原始PNG一样。
if(IMAGETYPE_PNG==$orig_type&;&function_exists('imageistruecolor')&;&!imageistruecolor($image))
imagetruecolortopalette($newimage,false,imagecolorstotal($image));
//我们不再需要内存中的原件
imagedestroy($image);
//$后缀将被附加到目标文件名,就在扩展名
之前,如果(!$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");
如果(!is_null($dest_path)和$_dest_path=realpath($dest_path))
$dir=$_dest_path;
$destfilename="{$dir}/{$name}-{$suffix}。{$ext}";
if(IMAGETYPE_GIF==$orig_type){
if(!imagegif($newimage,$destfilename))
returnnewWP_Error('Resize_path_invalid',__('Resizepathinvalid');
}elseif(IMAGETYPE_PNG==$orig_type){
if(!imagepng($newimage,$destfilename))
returnnewWP_Error('Resize_path_invalid',__('Resizepathinvalid');
}else{
if($rotate){
$newimage=_rotate_image_resource($newimage,360-$rotate);
}
//所有其他格式都转换为jpg
$destfilename="{$dir}/{$name}-{$suffix}。jpg";
$return=imageJPEG($newimage,$destfilename,apply_filters('jpeg_quality',$jpeg_quality,'image_resize');
如果(!$return)
returnnewWP_Error('Resize_path_invalid',__('Resizepathinvalid');
}
imagedestroy($newimage);
//设置正确的文件权限
$stat=stat(dirname($destfilename));
$perms=$stat['mode']&;0000666;//与父文件夹权限相同,剥离可执行位
@chmod($destfilename,$perms);
return$destfilename;
}
这个方法需要你把原来的add_image_size替换成bt_add_image_size,具体使用方法我们就不详细解释了。简而言之,这个函数给出了第三个参数,它允许您指定裁剪的开始位置。
其实更简洁的方法是我找了一个插件好像可以实现这个功能。你不妨下载下来试试。
Shailan.com工作人员提供了一个更直接的方法,就是修改wordpress系统文件/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;//或者您想要的值
总之,这种方法直接有效,容易理解,因为$s_x和$s_y是wordpress系统裁剪时裁剪区域的起始位置。而且他还推荐了一个插件:重新生成缩略图,应该是基于这个方法实现的。
stackexchange社区里有人用这个方法更方便。也许可以借鉴,但是否管用还需要验证:
复制代码如下:
Add_filter('WP_generate_attachment_metadata','custom_crop');</p>;
<;p>函数custom_crop($metadata){<;/p>;
<;p>$uploads=WP_upload_dir();
$file=path_join($uploads['basedir'],$metadata['file']);//原图像文件
列表($year,$month)=explode('/',$metadata['file']);
$target=path_join($uploads['basedir'],"{$year}/{$month}/"。$metadata['sizes']['medium']['file']);//中间大小文件
$image=imagecreatefromjpeg($file);//原始图像资源
$image_target=WP_imagecreatetruecolor(44,44);//要填充的空白图像
imagecopyresampled($image_target,$image,0,0,25,15,44,44,170,170);//croporiginal
imageJPEG($image_target,$target,apply_filters('jpeg_quality',90,'image_resize');//将裁剪后的内容写入文件</p>;
<;p>返回$metadata
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)