首先在app.blade.php中引入jcrop(在github上可以找到)
{{--引入jcrop--}} <link rel="stylesheet" href="/css/jquery.Jcrop.css"> <script src="/js/jquery.Jcrop.min.js"></script>
在bootstrap官网中copy一段模态框的代码到avatar.blade.php中,根据实际情况进行修改:
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> {!! Form::open(['method'=>'POST','url'=>'/crop/api', 'onsubmit'=>'return checkCoords();','files' => true]) !!} <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true" style="color: #ffffff">×</span></button> <h4 class="modal-title" id="exampleModalLabel">裁剪头像</h4> </div> <div class="modal-body"> <div class="content"> <div class="crop-image-wrapper"> <img src="/images/default-avatar.jpeg" class="ui centered image" id="cropbox" > <input type="hidden" id="photo" name="photo" /> <input type="hidden" id="x" name="x" /> <input type="hidden" id="y" name="y" /> <input type="hidden" id="w" name="w" /> <input type="hidden" id="h" name="h" /> </div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">取消</button> <button type="submit" class="btn btn-primary">裁剪头像</button> </div> {!! Form::close() !!} </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal -->
重新修改我们的js代码,当头像上传成功后弹出模态框:
function showResponse(response) { if(response.success == false) { var responseErrors = response.errors; $.each(responseErrors, function(index, value) { if (value.length != 0) { $("#validation-errors").append('<div class="alert alert-error"><strong>'+ value +'</strong><div>'); } }); $("#validation-errors").show(); } else { // $('#user-avatar').attr('src',response.avatar); // $('#upload-avatar').html('更换新的头像'); // 取到cropbox var cropbox = $('#cropbox'); // 设置cropbox的图片地址 cropbox.attr('src', response.avatar); // 设置 id为photo的input标签的值 $('#photo').val(response.avatar); // 设置按钮 $('#upload-avatar').html('上传新头像'); // 弹出模态框 $('#exampleModal').modal('show'); cropbox.Jcrop({ aspectRatio: 1, onSelect: updateCoords, setSelect: [200,200,0,0] }) $('.jcrop-holder img').attr('src', response.avatar); } }
// 对应着onSelect的配置 function updateCoords(c) { $('#x').val(c.x); $('#y').val(c.y); $('#w').val(c.w); $('#h').val(c.h); }
// 对应着表单的onsubmit function checkCoords() { if (parseInt($('#w').val())) return true; alert('请选择图片.'); return false; }
到此为止前端的工作就差不多完成了,下面来写后端的逻辑:
前端代码新增了一个表单,我们注册对应的路由:
Route::post('/crop/api', 'UsersController@cropAvatar');
我们把存储到数据库的操作放到裁剪方法中,具体是这样的,注释很清楚:
public function changeAvatar(Request $request) { // 声明路径名 $destinationPath = 'uploads/'; // 取到图片 $file = $request->file('avatar'); // 验证 $input = array('image' => $file); $rules = array( 'image' => 'image' ); $validator = \Validator::make($input, $rules); if ( $validator->fails() ) { return \Response::json([ 'success' => false, 'errors' => $validator->getMessageBag()->toArray() ]); } // 获得图片的名称 为了保证不重复 我们加上userid和time $file_name = \Auth::user()->id . '_' . time() . $file->getClientOriginalName(); // 执行move方法 $file->move($destinationPath, $file_name); // 裁剪图片 生成400的缩略图 Image::make($destinationPath . $file_name)->fit(500)->save(); return \Response::json([ 'success' => true, 'avatar' => asset($destinationPath.$file_name), ]); } public function cropAvatar(Request $request) { // array:6 [▼ // "_token" => "PB7DoFssm6vTQGsDREbpm2zZppSb80BdfKCFpmCf" // "photo" => "http://localhost:8000/uploads/21_1492618494IMG_2332.JPG" // "x" => "0" // "y" => "29" // "w" => "450" // "h" => "450" //] // dd($request->all()); // 拿到数据 $photo=strstr($request->get('photo'),'uploads'); $width = (int) $request->get('w'); $height = (int) $request->get('h'); $x = (int) $request->get('x'); $y = (int) $request->get('y'); // 使用Image对图像进行裁剪后保存 Image::make($photo)->crop($width, $height, $x, $y)->save(); // 保存到数据库 $user = \Auth::user(); $user->avatar = '/' . $photo; $user->save(); return redirect('/user/avatar'); }