vue中使用vue-cropper实现图片裁剪

最近我司一项目,在个人中心页面上需用户上传个性传封面图(类似知乎个人主页上部),用户上传图片大小不一,且封面图大小为1000px*240px;这就需要在用户上传的时候对图片进行合适大小裁剪。

大概思路:
用户上传图片时

  1. 判断图片尺寸大小,宽高不能小于1200px240;小于这个尺寸将无法完美裁剪。
  2. 将图片转化为base64格式,即时回显图片和不浪费服务器资源。

这两步完成后,将进入到vue-cropper的裁剪操作了,具体操作可见文档,我在下面写了我的配置供参考;
vue-cropper地址: https://github.com/xyxiao001/vue-cropper

裁剪操作结束,点击确认,得到裁剪后返回图片对象为blod类型,但服务器只接收file类型,故需转为file类型给服务器;得到服务器图片路径后,替换掉原本图片路径,完成✅

  1. 下载

    npm install vue-cropper
    
  2. 配置

    我使用的是全局配置,此处只写出全局配置

2.1 在~/plugins文件夹下,新建 cropper.js文件;引入vue-cropper

import vueCropper from 'vue-cropper';
import Vue from 'vue';
Vue.use(vueCropper);

2.2 在~/nuxt.config.js文件中,配置插件

export default{
    plugins: [
        { src: '~/plugins/cropper', ssr: false }
    ]
}
  1. 使用
    template
    <div>
     <div>
         <input v-if="status" id="uploadFileInput" type="file" accept="image/png,image/jpeg" >
     </div>
     <div class="cropper-content" v-else>
         <div class="cropper" style="text-align:center">
             <vueCropper
                 ref="cropper"
                 :img="option.img"
                 :outputSize="option.size"
                 :outputType="option.outputType"
                 :info="true"
                 :full="option.full"
                 :canMove="option.canMove"
                 :canMoveBox="option.canMoveBox"
                 :original="option.original"
                 :autoCrop="option.autoCrop"
                 :fixed="option.fixed"
                 :fixedNumber="option.fixedNumber"
                 :centerBox="option.centerBox"
                 :infoTrue="option.infoTrue"
                 :fixedBox="option.fixedBox"
                 :mode="option.mode">
            </vueCropper>
         </div>
         <div class="btnGroup">
             <el-button @click="dialogVisible = false">取 消</el-button>
             <el-button type="primary" @click="finish" :loading="loading">确认</el-button>
         </div>
    </div>
    

style

    .cropper-content{
        width: 100%;
        height: 300px;
    }
    .cropper {
        width: 100%;
        height: 240px;
    }
    .btnGroup{
        float: right;
        margin-top: 10px;
        margin-right: 15px;
    }

script

export default{
    data(){
        status: true,
        option: {
            img: '', // 裁剪图片的地址
            info: true, // 裁剪框的大小信息
            outputSize: 0.8, // 裁剪生成图片的质量
            outputType: 'jpeg', // 裁剪生成图片的格式
            canScale: true, // 图片是否允许滚轮缩放
            autoCrop: true, // 是否默认生成截图框
            autoCropWidth: 1200, // 默认生成截图框宽度
            autoCropHeight: 240, // 默认生成截图框高度
            fixedBox: true, // 固定截图框大小 不允许改变
            fixed: true, // 是否开启截图框宽高固定比例
            fixedNumber: [25, 6], // 截图框的宽高比例
            // full: true, // 是否输出原图比例的截图
            canMoveBox: false, // 截图框能否拖动
            original: false, // 上传图片按照原始比例渲染
            centerBox: true, // 截图框是否被限制在图片里面
            infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
            mode: 'cover',    // cover  图片铺满容器
         },
    },
    methods:{
      // 触发 input:file
      uploadFile() {
          try{
              this.$refs.upload.querySelector('input').click();
          }catch (e) {}
      }, 
      // 点击上传按钮后的事件
     upload(e) {
         let file = e.target.files[0];
         var self = this;
         this.createReader(file, function (w, h) {
              if(w<1200 || h<240){
                  self.$message.error("请上传宽度大于 1200px,高度大于 240px 的封面图片。");
                  let UFI = document.getElementById("uploadFileInput");
                  UFI.value = '';
              }else{
                 self.file2base64(file)
              }
         })
     } ,

    // 获取图片宽高
   createReader(file, whenReady) {
      var reader = new FileReader;
      reader.onload = function (evt) {
         var image = new Image();
         image.onload = function () {
             var width = this.width;
              var height = this.height;
               if (whenReady) whenReady(width, height);
         };
         image.src = evt.target.result;
      };
      reader.readAsDataURL(file);
   },

    // file类型文件 转base64文件类型
   file2base64(file){
       var reader = new FileReader();
       reader.readAsDataURL(file);
       var self = this;
       reader.onload = function (e) {
         // 图片base64化
         let newUrl = this.result;    //图片路径
         self.$nextTick(() => {
             self.pageImage = newUrl;
             self.option.img = newUrl;
              self.dialogVisible = true
          })
       }
  },

  // 点击确定,这一步是可以拿到处理后的地址, 然后上传到服务器
  finish() {
      this.$refs.cropper.getCropBlob((data) => {
          // 将接收到blod文件对象转为file
          let file = new File([data], 'proFileCover.jpg',{type: data.type,  lastModified: Date.now()});
          let params = new FormData();
          params.append("image", file);
          var self = this;
          self.$axios.post("upload_image", params)
            .then(res=>{
                if(res.data.code == 0){
                  //  显示图片
                  self.pageImage = res.data.data;
                  // 关闭隐藏div,显示图片
                  self.status = false;
                 }  
             })
        }
    },
}

  1. 最后
    通过上述代码操作,就完成了上传图片裁剪的功能。

有我没写明白的地方请评论、私信或邮箱告知我,
邮箱:manbanzhen@qq.com

欢迎访问: http://blog.zhanghaoran.ren

写于2020年, 2022.09.06再次发布