vue-cropper组件实现图片切割上传


Posted in Vue.js onMay 27, 2021

本文实例为大家分享了vue-cropper组件实现图片切割上传的具体代码,供大家参考,具体内容如下

这几日,等来了些空闲,用vue和spring boot实践一次头像上传,因此记下了,望将来的开发有所帮助。

vue-cropper在vue中的引入

1、组件内引入

import { VueCropper }  from 'vue-cropper' 
components: {
  VueCropper,
},

2、全局引入

在main.js中配置如下代码

import VueCropper from 'vue-cropper' 

Vue.use(VueCropper)

3、使用示例

vue文件

<template>
  <el-dialog
    title="编辑头像"
    :visible.sync="dialogFormVisible"
    :close-on-click-modal="false"
    append-to-body
  >
    <label class="btn" for="uploads">选择图片</label>
    <input
      type="file"
      id="uploads"
      :value="imgFile"
      style="position:absolute; clip:rect(0 0 0 0);"
      accept="image/png, image/jpeg, image/gif, image/jpg"
      @change="uploadImg($event, 1)"
    >
    <div style="margin-left:20px;">
      <div class="show-preview" :style="{'overflow': 'hidden', 'margin': '5px'}">
        <div :style="previews.div" class="preview" style="width: 40px;height: 40px;">
          <img :src="previews.url" :style="previews.img">
        </div>
      </div>
    </div>
    <div class="cut">
      <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"
        :autoCropWidth="option.autoCropWidth"
        :autoCropHeight="option.autoCropHeight"
        :fixedBox="option.fixedBox"
        @realTime="realTime"
        @imgLoad="imgLoad"
      ></vueCropper>
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible = false" size="small">取 消</el-button>
      <el-button type="primary" @click="finish('blob')" size="small">确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { VueCropper } from "vue-cropper";
export default {
  components: {
    VueCropper
  },
  data() {
    return {
      previews: {},
      model: false,
      modelSrc: "",
      fileName: "",
      imgFile: "",
      dialogFormVisible: false,
      option: {
        img: "",
        outputSize: 1, //剪切后的图片质量(0.1-1)
        full: false, //输出原图比例截图 props名full
        outputType: "png",
        canMove: true,
        original: false,
        canMoveBox: true,
        autoCrop: true,
        autoCropWidth: 40,
        autoCropHeight: 40,
        fixedBox: true
      }
    };
  },
  methods: {
    //上传图片(点击上传按钮)
    finish(type) {
      let selft = this;
      let formData = new FormData();
      // 输出
      if (type === "blob") {
        selft.$refs.cropper.getCropBlob(data => {
          let img = window.URL.createObjectURL(data);
          selft.model = true;
          selft.modelSrc = img;
          formData.append("file", data, selft.fileName);
          selft.$api.writer.userUpload(formData, r => {
            if (r.code) {
              selft.$alert.error(r.msg);
            } else {
              selft.$message({
                message: r.data.msg,
                type: "success"
              });
              selft.$store.state.userInfo = r.data.data;
              selft.dialogFormVisible = false;
            }
          });
        });
      } else {
        this.$refs.cropper.getCropData(data => {});
      }
    },
    //选择本地图片
    uploadImg(e, num) {
      console.log("uploadImg");
      var selft = this;
      //上传图片
      var file = e.target.files[0];
      selft.fileName = file.name;
      if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
        alert("图片类型必须是.gif,jpeg,jpg,png,bmp中的一种");
        return false;
      }
      var reader = new FileReader();
      reader.onload = e => {
        let data;
        if (typeof e.target.result === "object") {
          // 把Array Buffer转化为blob 如果是base64不需要
          data = window.URL.createObjectURL(new Blob([e.target.result]));
        } else {
          data = e.target.result;
        }
        if (num === 1) {
          selft.option.img = data;
        } else if (num === 2) {
          selft.example2.img = data;
        }
      };
      // 转化为base64
      // reader.readAsDataURL(file)
      // 转化为blob
      reader.readAsArrayBuffer(file);
    },
    show() {
      this.dialogFormVisible = true;
    },
    // 实时预览函数
    realTime(data) {
      console.log("realTime");
      this.previews = data;
    },
    imgLoad(msg) {
      console.log("imgLoad");
      console.log(msg);
    }
  }
};
</script>

<style lang="less">
@import "./userLogo.less";
</style>

less文件

.cut {
    width: 300px;
    height: 300px;
    margin: 0px auto;
}

.hh {
    .el-dialog__header {
        padding: 0px;
        line-height: 2;
        background-color: #f3f3f3;
        height: 31px;
        border-bottom: 1px solid #e5e5e5;
        background: #f3f3f3;
        border-top-left-radius: 5px;
        border-top-right-radius: 5px;
    }
    .el-dialog__title {
        float: left;
        height: 31px;
        color: #4c4c4c;
        font-size: 12px;
        line-height: 31px;
        overflow: hidden;
        margin: 0;
        padding-left: 10px;
        font-weight: bold;
        text-shadow: 0 1px 1px #fff;
    }
    .el-dialog__headerbtn {
        position: absolute;
        top: 8px;
        right: 10px;
        padding: 0;
        background: 0 0;
        border: none;
        outline: 0;
        cursor: pointer;
        font-size: 16px;
    }
}

.btn {
    display: inline-block;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    background: #fff;
    border: 1px solid #c0ccda;
    color: #1f2d3d;
    text-align: center;
    box-sizing: border-box;
    outline: none;
    //margin: 20px 10px 0px 0px;
    padding: 9px 15px;
    font-size: 14px;
    border-radius: 4px;
    color: #fff;
    background-color: #50bfff;
    border-color: #50bfff;
    transition: all 0.2s ease;
    text-decoration: none;
    user-select: none;
}

.show-preview {
    flex: 1;
    -webkit-flex: 1;
    display: flex;
    display: -webkit-flex;
    justify-content: center;
    -webkit-justify-content: center;
    .preview {
        overflow: hidden;
        border-radius: 50%;
        border: 1px solid #cccccc;
        background: #cccccc;
    }
}

发送请求的时候配置axios的Content-Type

// http request 拦截器
axios.interceptors.request.use(
  config => {debugger
    let token = sessionStorage.getItem('token')
    if (token) {
      config.headers.Authorization = token;
    }
    if (config && config.url && config.url.indexOf('upload') > 0) {
      config.headers['Content-Type'] = 'multipart/form-data'
    }
    return config
  },
  err => {
    return Promise.reject(err)
  }
)

boot的controller

@RequestMapping("/upload")
 public ResultData upload(@RequestParam("file") MultipartFile file) {
  return userService.upload(file);
 }

boot的service

@Override
 public ResultData upload(MultipartFile file) {
  if (!file.isEmpty()) {
   
   StringBuffer requestURL = sessionUtil.getRequestURL();
   int end = requestURL.indexOf("/user/upload");
   String basePath = requestURL.substring(0, end);
   String savePath = basePath + "/static/img/logo/";
   // 获取文件名称,包含后缀
   String fileName = file.getOriginalFilename();

   String saveDbPath = savePath + fileName;

   // 存放在这个路径下:该路径是该工程目录下的static文件下:(注:该文件可能需要自己创建)
   // 放在static下的原因是,存放的是静态文件资源,即通过浏览器输入本地服务器地址,加文件名时是可以访问到的
   String path = ClassUtils.getDefaultClassLoader().getResource("").getPath() + "static/img/logo/";

   // 该方法是对文件写入的封装,在util类中,导入该包即可使用,后面会给出方法
   try {
    FileUtil.fileupload(file.getBytes(), path, fileName);
    // 接着创建对应的实体类,将以下路径进行添加,然后通过数据库操作方法写入
    User user = sessionUtil.getSessionUser();
    user.setLogo(saveDbPath);
    User whereUser = new User();
    whereUser.setId(user.getId());
    ConfigHelper.upate(user, "user", whereUser);
    Map<String, Object> map = new HashMap<>();
    map.put("msg", "头像修改成功");
    map.put("data", user);
    return ResultData.ok(map);
   } catch (IOException e) {
    log.error("图片上传==》" + e.getMessage());
    e.printStackTrace();
    return ResultData.failed(e.getMessage());
   } catch (Exception e) {
    log.error("图片上次==》" + e.getMessage());
    e.printStackTrace();
    return ResultData.failed(e.getMessage());
   }

  } else {
   return ResultData.failed("上传图片失败");
  }
 }

结束

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Vue.js 相关文章推荐
Vue-router中hash模式与history模式的区别详解
Dec 15 Vue.js
vue.js watch经常失效的场景与解决方案
Jan 07 Vue.js
浅谈Vue开发人员的7个最好的VSCode扩展
Jan 20 Vue.js
Vue常用API、高级API的相关总结
Feb 02 Vue.js
vue+flask实现视频合成功能(拖拽上传)
Mar 04 Vue.js
vue实现倒计时功能
Mar 24 Vue.js
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
May 25 Vue.js
vue中利用mqtt服务端实现即时通讯的步骤记录
Jul 01 Vue.js
vue ref如何获取子组件属性值
Mar 31 Vue.js
vue3引入highlight.js进行代码高亮的方法实例
Apr 08 Vue.js
Vue组件化(ref,props, mixin,.插件)详解
May 15 Vue.js
vue3 自定义图片放大器效果的示例代码
Jul 23 Vue.js
vue-cropper插件实现图片截取上传组件封装
May 27 #Vue.js
HTML+VUE分页实现炫酷物联网大屏功能
Vue实现动态查询规则生成组件
详解vue身份认证管理和租户管理
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
vue-element-admin项目导入和导出的实现
May 21 #Vue.js
vue2实现provide inject传递响应式
May 21 #Vue.js
You might like
PHP缓存技术的使用说明
2011/08/06 PHP
PHP中使用Imagick操作PSD文件实例
2015/01/26 PHP
php实现异步数据调用的方法
2015/12/24 PHP
php实现微信公众号创建自定义菜单功能的实例代码
2019/06/11 PHP
javascript web对话框与弹出窗口
2009/02/22 Javascript
可以用来调试JavaScript错误的解决方案
2010/08/07 Javascript
悄悄用脚本检查你访问过哪些网站的代码
2010/12/04 Javascript
使用 Node.js 做 Function Test实现方法
2013/10/25 Javascript
jQuery DOM删除节点操作指南
2015/03/03 Javascript
jQuery基础_入门必看知识点
2016/07/04 Javascript
微信小程序 基础组件与导航组件详细介绍
2017/02/21 Javascript
vue用addRoutes实现动态路由的示例
2017/09/15 Javascript
微信小程序发送短信验证码完整实例
2019/01/07 Javascript
JS实现简易留言板特效
2019/12/23 Javascript
为Python的web框架编写前端模版的教程
2015/04/30 Python
深入浅出分析Python装饰器用法
2017/07/28 Python
TensorFlow神经网络优化策略学习
2018/03/09 Python
python xlsxwriter创建excel图表的方法
2018/06/11 Python
python MNIST手写识别数据调用API的方法
2018/08/08 Python
利用python和ffmpeg 批量将其他图片转换为.yuv格式的方法
2019/01/08 Python
使用Python-OpenCV向图片添加噪声的实现(高斯噪声、椒盐噪声)
2019/05/28 Python
Python小程序之在图片上加入数字的代码
2019/11/26 Python
实现Python与STM32通信方式
2019/12/18 Python
python matplotlib库的基本使用
2020/09/23 Python
高等教育学自荐书范文
2014/02/10 职场文书
学生个人自我鉴定范文
2014/03/28 职场文书
科长竞聘演讲稿
2014/05/16 职场文书
学生党员一帮一活动总结
2014/07/08 职场文书
2015年八一建军节活动总结
2015/03/20 职场文书
2015秋季开学演讲稿范文
2015/07/16 职场文书
应收账款管理制度
2015/08/06 职场文书
导游经典开场白——导游词
2019/04/17 职场文书
Java数组与堆栈相关知识总结
2021/06/29 Java/Android
python代码实现备忘录案例讲解
2021/07/26 Python
Python编程中Python与GIL互斥锁关系作用分析
2021/09/15 Python
java中如何截取字符串最后一位
2022/07/07 Java/Android