使用cropper实现图片裁剪功能并保存图片到数据库

今天实现了图片裁剪上传的功能,写下这篇blog,预防以后忘记 图片外链托管在github,图片无法加载请自备梯子

(1)前端实现

(1.1)cropper插件介绍

我们可以使用 cropper插件实现裁切和缩略图功能
下载地址为:https://github.com/fengyuanchen/cropper

(1.2)cropper插件使用

(1.2.1)准备

解压下载下来的压缩包
并把dist目录下的:cropper.min.js和cropper.min.css文件复制到项目目录下

(1.2.2)引入类库

<!--使用绝对路径引入类库,因为cropper是基于jquery的,所以jquery也要引入-->
<script src="/js/jquery.min.js"></script>
<link rel="stylesheet" href="/css/cropper.min.css">
<script src="/js/cropper.min.js"></script>

(1.2.3)html结构

<form action="{{ route('setface') }}" method="POST" enctype="multipart/form-data">
  {{ csrf_field() }}
    <div class="form-div">
        <input type="file" name="face">
    </div>
    <!-- 预览图片区域 -->
    <div class="img-container">
        <img id="pre_image">
    </div>
    <!-- 三个缩略图预区域 -->
    <div class="docs-preview clearfix">
        <div class="img-preview preview-lg"></div>
        <div class="img-preview preview-md"></div>
        <div class="img-preview preview-sm"></div>
    </div>
    <!-- 保存裁切参数的四个框 -->
    <input type="hidden" name="x">
    <input type="hidden" name="y">
    <input type="hidden" name="w">
    <input type="hidden" name="h">

    <div class="form-div">
        <input type="submit" value="确认">
    </div>
</form>

(1.2.4)样式文件

<!--在头部把样式文件导入,也可以自己修改样式控制裁剪框-->
<style>
    .img-container {
        width: 240px;
        height: 240px;
        float:left;
    }
    .img-container #pre_image {
        width: 100%;
    }
    .img-preview {
        float: left;
        overflow: hidden;
        margin-left: 20px;
    }

    .preview-lg {
        width: 240px;
        height: 240px;
    }

    .preview-md {
        width: 80px;
        height: 80px;
    }

    .preview-sm {
        width: 35px;
        height: 35px;
    }
</style>

(1.2.5)js代码

<script>

var preImg = $("#pre_image");
// 获取裁切时的四个框
var x = $("input[name=x]");
var y = $("input[name=y]");
var w = $("input[name=w]");
var h = $("input[name=h]");
// 选择图片时预览图片 并 调用cropper插件
$("input[name=face]").change(function(){
    // 先消毁,清除一下插件,否则连续调用插件时会失败
    preImg.cropper("destroy");
    // this.files[0]:获取当前图片并转成URL地址
    var url = getObjectUrl( this.files[0] );
    console.log( url )
    // 设置url到预览图片上
    preImg.attr('src', url);
    // 调出插件
    preImg.cropper({
        aspectRatio: 1,         // 裁切的框形状
        preview:'.img-preview',    // 显示预览的位置
        viewMode:3,                // 显示模式:图片不能无限缩小,但可以放大
        // 裁切时把参数保存到表单中
        crop: function(event) {
            x.val( event.detail.x );
            y.val( event.detail.y );
            w.val( event.detail.width );
            h.val( event.detail.height );
        }
    });
});
// 预览时需要使用下面这个函数转换一下
function getObjectUrl(file) {
    var url = null;
    if (window.createObjectURL != undefined) {
        url = window.createObjectURL(file)
    } else if (window.URL != undefined) {
        url = window.URL.createObjectURL(file)
    } else if (window.webkitURL != undefined) {
        url = window.webkitURL.createObjectURL(file)
    }
    return url
}

</script>

(1.2.6)

前端实现效果预览


(2)后端保存图片到数据库

(2.1)创建迁移文件

<!--为用户表表添加三个字段,用来保存三张缩略图-->
php artisan make:migration add_faces_users --table=users

(2.1.1)编写迁移文件

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddFacesUsers extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('bgface')->nullable()->comment('大脸');
            $table->string('mdface')->nullable()->comment('中脸');
            $table->string('smface')->nullable()->comment('小脸');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn(['bgface','mdface','smface']);
        });
    }
}

(2.1.2)执行迁移

php artisan migrate

(2.2)创建表单验证类

(2.2.1)创建验证类文件

php artisan make:request FaceRequest

(2.2.2)编写验证规则

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class FaceRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
        <!--最大上传大小不能超过4m-->
            'face' => 'required|image|max:4096',
            'x' => 'required|numeric|min:0',
            'y' => 'required|numeric|min:0',
            'w' => 'required|numeric|min:200',
            'h' => 'required|numeric|min:200',
        ];
    }
}

(2.3)配置路由

<!--配置一个用来处理头像的路由-->
//修改头像
Route::post("/face",'FaceController@face')->name('setface');

(2.4)FaceController中添加处理头像的代码

<!--使用composer安装图片处理类-->
composer require intervention/image
<!--修改 config/app.php ,注册类到 $providers 数组-->
Intervention\Image\ImageServiceProvider::class
<!--在 $alias 数组中定义类别名-->
'Image'=> Intervention\Image\Facades\Image::class
<!--引入相关类-->
use Image;
use App\Models\User;
use Storage;
use App\Http\Requests\FaceRequest;
<!--添加face方法-->
public function face(FaceRequest $req) {

        if($req->has('face') && $req->face->isValid())
        {
            // 当前图片上传的位置
            $oldimage = $req->face->path();
            // 保存原图片
            // 获取当前日期
            $date = date('Ymd');
            $oriImg = $req->face->store('face/'.$date);  
            // 打开要处理的图片
            $img = Image::make($oldimage);
            // 裁切图片
            $img->crop((int)$req->w,(int)$req->h,(int)$req->x,(int)$req->y);
            // 生成缩略图并保存
            // 拼出这个缩略图的名字
            $bgname = str_replace('face/'.$date.'/', 'face/'.$date.'/bg_', $oriImg);         
            $img->resize(240,240);
            $img->save('./uploads/'.$bgname);                     
            $mdname = str_replace('face/'.$date.'/', 'face/'.$date.'/md_', $oriImg);
            $img->resize(80,80);
            $img->save('./uploads/'.$mdname);         
            $smname = str_replace('face/'.$date.'/', 'face/'.$date.'/sm_', $oriImg);
            $img->resize(35,35);
            $img->save('./uploads/'.$smname);       
            // 先取出用户的信息
            $user = User::find( session('id') );
            // 删除原头像
            Storage::delete( $user->face );
            Storage::delete( $user->bgface );
            Storage::delete( $user->mdface );
            Storage::delete( $user->smface );
            // 更新新脸
            $user->face = $oriImg;
            $user->bgface = $bgname;
            $user->mdface = $mdname;
            $user->smface = $smname;
            $user->save();
            // 修改SESSION中的图片
            session([
                'smface' => $smname,
                'bgface' => $bgname,
            ]);
            return redirect()->route('face');
        }
    }

(3)注意事项

  • 数据库字段要对应正确,不然保存数据库会失败
  • 因为新的头像要保存到session中,所以如果没效果要多清空缓存试试
  • 最重要的是一定要有耐心
  • 注意一下文件的上传大小
  • 有问题请给我发邮件

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏施炯的IoT开发专栏

《101 Windows Phone 7 Apps》读书笔记-ALARM CLOCK

课程内容 Ø 隔离存储空间 Ø 设置 Ø 设置页面向导 Ø Toggle Switch控件 Ø 使用自定义字体     Alarm Clock模仿的...

2096
来自专栏落影的专栏

iOS开发笔记(八)---- 键盘、静态库、动画、Crash定位

4129
来自专栏TechBox

跟着官方文档学习3D Touch前言(一)app外3D Touch—Home Screen Quick Actions(二)app内的3D Touch - Peek and Pop名词解释

2544
来自专栏Google Dart

为Flutter应用程序添加交互性 顶

你如何修改你的应用程序,使其对用户输入做出反应? 在本教程中,您将为仅包含非交互式小部件的应用添加交互性。 具体来说,您将通过创建一个管理两个无状态小部件的自定...

2252
来自专栏java学习

面试题27(关于 java 的异常处理机制的叙述哪些正确?)

? 关于 java 的异常处理机制的叙述哪些正确? A)不论程序是否发生错误及捕捉到异常情况,都会执行finally部分 B) 当try区段的程序发生异常时...

4034
来自专栏破晓之歌

Python 的 GUI 开发工具 原

Flexx 是一个纯 Python 工具包,用来创建图形化界面应用程序。其使用 Web 技术进行界面的渲染。你可以用 Flexx 来创建桌面应用,同时也可以导出...

7702
来自专栏技术之路

Qt5 新特性

Qt 5 已经临近发布,其最大的特点就是模块化。将原来庞大的模块更细分为不同的部分,同时,一个大版本的升级,当然少不了添加、删除各个功能类。文本简单介绍 Qt5...

3928
来自专栏Jackson0714

【博客美化】04.自定义地址栏logo

43711
来自专栏不知的专栏

反-反爬虫:用几行代码写出和人类一样的动态爬虫

本文将从 Phantomjs 动态爬虫介绍起,用3行代码傻瓜式完成基于 Casper 的动态爬虫来绕过对抗策略获取页面数据。

1.3K1
来自专栏CSDN技术头条

前端知识点总结——Vue

作用:将表达式执行的结果 输出当调用元素的 innerHTML 中;还可以将数据绑定到视图。

1312

扫码关注云+社区

领取腾讯云代金券