55. 裁剪头像
简介
在本节里,我们完成当用户上传图片太大时进行裁剪显示。
需求分解
在上节我们对上传的头像图片格式和最小尺寸进行了限制,但没有限制用户上传图片的最大尺寸,而我们在显示用户头像时直接显示用户的头像图片。这样当用户上传的图片很大时会拖慢页面的加载速度,所以我们对用户上传的头像进行裁剪。
因为在个人中心页面里头像显示区域最大也就 208px,即使要兼容 视网膜屏幕(Retina Screen) 的话,最多也就需要 208px * 2 = 416px 。所以当上传头像图片宽度大于 416px 时我们对该图片进行等比缩小裁剪再保存。
我们计划用官方提供的 think-image
实现对头像图片的裁剪。
扩展包
首先,我们来安装 think-image
:
$ composer require topthink/think-image
模型
因为 think-image 的裁剪方法默认是等比缩放,所以我们只需要给 Upload::saveImage
方法再添加一个参数 $max_width
指定图片裁剪后的宽度,就可以实现等比缩放功能。
另外,当调用该方法时传参 $max_width=0
时,我们将不对图片进行裁剪,这样我们就可以扩大该方法的使用范围。
application/common/model/Upload.php
<?php
.
.
.
use think\Image;
class Upload
{
/**
* 保存上传图片
* @Author zhanghong(Laifuzi)
* @DateTime 2019-02-21
* @param File $file 上传文件
* @param string $max_width 最大宽度
* @return array
*/
public static function saveImage($file, $max_width = 0){
.
.
.
$local_dir = 'uploads';
$ds = DIRECTORY_SEPARATOR;
$info = $file->rule('md5')->move($local_dir);
$save_name = $info->getSaveName();
$save_path = $ds.$local_dir.$ds.$save_name;
if($max_width > 0){
//对图片进行等比缩小裁剪,并直接覆盖原图
$image = Image::open('.'.$save_path);
$image->thumb($max_width, $max_width)->save('.'.$save_path);
}
return [
'ext' => $info->getExtension(),
'save_path' => $save_path,
'sha1' => $info->hash("sha1"),
'md5' => $info->hash("md5"),
'size' => $info->getSize(),
'origin_name' => $file->getInfo('name'),
];
}
}
控制器
在控制器里调用时添加上新增加的参数:
application/index/controller/Upload.php
<?php
.
.
.
private function save_image($request)
{
.
.
.
if($request->isPost()){
$file = $request->file('image');
try{
// 把用户头像等比缩小裁剪成宽度 416px
$upload_info = UploadModel::saveImage($file, 416);
$image = $upload_info['save_path'];
}catch(ValidateException $e){
$errors = $e->getData();
$error_msg = $errors['file'];
}
}
.
.
.
}
.
.
.
效果展示
提交代码
下面把代码纳入到版本管理:
$ git add -A
$ git commit '裁剪头像'