一、背景

目前负责的系统(商城后台管理系统)里面有这么一个需求,为了配合前台的展示,上传的商品图片比较必须是1:1的正方形。(其它地方有时会有5:4或者16:9的需求,但较少)。所以需要对上传的图片先进行裁剪,并且按要求只能裁剪为1:1,然后在进行上传。

当然,为了兼容系统其它地方有5:4或者16:9的图片比例需求,需要给出一个参数,可以随时控制图片裁剪的比例。

二、使用什么插件实现

使用 vue-cropper 显示,该插件是基于 cropper 的二次封装,简单小巧,更合适vue项目。注意:功能没有 cropper 强大。

三、使用 cropper

3.1 封装一下cropper, 配置自己想要的参数

<template><div class="Cropper"><el-dialog:visible.sync="dialogVisible"width="740px"title="图片裁剪":before-close="handleClose":close-on-click-modal="false"><divclass="cropper-container"><div class="cropper-el"><vue-cropperref="cropper":img="cropperImg":output-size="option.size":output-type="option.outputType":info="true":can-move="option.canMove":can-move-box="option.canMoveBox":fixed-box="option.fixedBox":auto-crop="option.autoCrop":auto-crop-width="option.autoCropWidth":auto-crop-height="option.autoCropHeight":center-box="option.centerBox":high="option.high":info-true="option.infoTrue"@realTime="realTime":enlarge="option.enlarge":fixed="option.fixed":fixed-number="option.fixedNumber":limitMinSize="option.limitMinSize"/></div><!-- 预览  ==>> 我不需要预览 --><!-- <div class="prive-el"><strong>预览:</strong><div class="prive-style" :style="{'width': '200px', 'height': '200px', 'overflow': 'hidden', 'margin': '10px 25px', 'display':'flex', 'align-items' : 'center'}"><div class="prive-style" :style="{'width': previews.w + 'px', 'height': previews.h + 'px',  'overflow': 'hidden', 'margin': '10px 25px', 'display':'flex', 'align-items' : 'center'}"><div class="preview" :style="previews.div"><img :src="previews.url" :style="previews.img"></div></div><el-button @click="uploadBth">重新上传</el-button></div> --></div><spanslot="footer"class="dialog-footer"><el-button @click="uploadBth">重新上传</el-button><el-button@click="handleClose">取 消</el-button><el-buttontype="primary"@click="saveImg">确 定</el-button></span></el-dialog></div>
</template><script>
import { VueCropper } from 'vue-cropper';
export default {name: 'Cropper',components: {VueCropper},props: {dialogVisible: {type: Boolean,default: false},imgType: {type: String,default: 'blob'},cropperImg: {type: String,default: ''},zoomScale: {      // 裁剪比例,默认1:1type: Array,default: [1, 1]}},data () {return {previews: {},option: {img: '', // 裁剪图片的地址size: 1, // 裁剪生成图片的质量outputType: 'png', // 裁剪生成图片的格式 默认jpgcanMove: false, // 上传图片是否可以移动fixedBox: false, // 固定截图框大小 不允许改变canMoveBox: true, // 截图框能否拖动autoCrop: true, // 是否默认生成截图框// 只有自动截图开启 宽度高度才生效autoCropWidth: 500, // 默认生成截图框宽度autoCropHeight: 500, // 默认生成截图框高度centerBox: true, // 截图框是否被限制在图片里面high: false, // 是否按照设备的dpr 输出等比例图片enlarge: 1, // 图片根据截图框输出比例倍数mode: 'contain', // 图片默认渲染方式maxImgSize: 2000, // 限制图片最大宽度和高度// limitMinSize: [500,500], // 更新裁剪框最小属性limitMinSize: 500, // 更新裁剪框最小属性infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高fixed: true, // 是否开启截图框宽高固定比例  (默认:true)// fixedNumber: [1, 1] // 截图框的宽高比例 ==>> 这个参数目前没有作用(作者解释的)fixedNumber: this.zoomScale // 截图框的宽高比例},};},methods: {// 裁剪时触发的方法,用于实时预览realTime (data) {this.previews = data;},// 重新上传uploadBth () {this.$emit('update-cropper');},// 取消关闭弹框handleClose () {this.$emit('colse-dialog', false);},// 获取裁剪之后的图片,默认blob,也可以获取base64的图片saveImg () {if (this.imgType === 'blob') {this.$refs.cropper.getCropBlob(data => {this.$emit('upload-img', data);});} else {this.$refs.cropper.getCropData(data => {this.uploadFile = data;this.$emit('upload-img', data);});}}}
};
</script><style lang="scss" scoped>
.Cropper {.cropper-el {height: 700px;width: 700px;flex-shrink: 0;}.cropper-container {display: flex;justify-content: space-between;.prive-el {flex: 1;align-self: center;text-align: center;.prive-style {margin: 0 auto;flex: 1;-webkit-flex: 1;display: flex;display: -webkit-flex;justify-content: center;-webkit-justify-content: center;overflow: hidden;background: #ededed;margin-left: 40px;}.preview {overflow: hidden;}.el-button {margin-top: 20px;}}}
}
</style>
<style lang="scss">
.cropper-box-canvas img{width: 100% !important;height: 100% !important;
}
</style>

3.2 将 el-upload 和 cropper 组合,封装,其他地方可以直接调用

<template><div><!-- 注意:必须关闭自动上传属性 auto-upload --><el-upload:http-request="Upload":multiple="true"list-type="picture-card":file-list="productImageList":on-remove="removeImage":limit="12":before-upload="beforeAvatarUpload"ref="fileUpload":auto-upload="false":on-change="selectChange"action=""class="cropper-upload-box"><i slot="default" class="el-icon-plus"></i></el-upload><cropperv-if="showCropper":dialog-visible="showCropper":cropper-img="cropperImg":zoomScale="zoomScale"@update-cropper="updateCropper"@colse-dialog="closeDialog"@upload-img="uploadImg"/></div>
</template><script>
import Cropper from "@/components/cropper";
import { client, randomWord } from '@/utils/alioss'
export default {name: "CropperUpload",data() {return {productImageList: [],showCropper: false, // 是否显示裁剪框cropperImg: "" // 需要裁剪的图片};},props: {defaultImgList: {     // 默认显示的图片列表type: Array,default: () => []},zoomScale: {         // 裁剪比例,默认1:1type: Array,default: [1, 1]}},components: {Cropper},watch: {defaultImgList: {handler: function(newVal, oldVal){this.productImageList = newVal   // 赋值},deep: true}},methods: {beforeAvatarUpload(file) {const isLt2M = file.size / 1024 / 1024 < 2;     // 原图片// const isLt2M = this.uploadFile.size / 1024 / 1024 < 1;     //裁剪后的图片(会比原图片大很多,应该是转成Blob的原因导致)if (!isLt2M) {this.$message.error("上传图片大小不能超过 2MB!");this.noCanUpload = true     // 如果这里被拦截,将自动删除不能上传的图片return false}// return isLt2M},removeImage(file, fileList) {const index = this.productImageList.findIndex(item => {return item.uid == file.uid;});if (index > -1) {this.productImageList.splice(index, 1);}this.$emit('getUploadImg', this.productImageList)   // 把最新上传的图片列表返回},Upload(file) {var fileName = `img/${randomWord(true,20)}${+new Date()}${file.file.name.substr(file.file.name.indexOf("."))}`;// client().put(fileName, file.file).then(result => {client().put(fileName, this.uploadFile).then(result => {// 上传裁剪后的图片console.log(result);this.productImageList.push({url: result.url,uid: file.file.uid,saveUrl: "/" + result.name});this.showCropper = false;this.$emit('getUploadImg', this.productImageList)    // 把最新上传的图片列表返回}).catch(err => {this.showCropper = false;console.log(err);});},// 更新图片updateCropper() {if(!this.noCanUpload){let fileList = this.$refs.fileUpload.uploadFiles        // 获取文件列表let index02 = fileList.findIndex(item => {        // 把取消裁剪的图片删除return item.uid == this.currentFile.uid;});fileList.splice(index02, 1)}let index = this.$refs.fileUpload.$children.length - 1;this.$refs.fileUpload.$children[index].$el.click();},// 关闭窗口closeDialog() {this.showCropper = false;if(!this.noCanUpload){let fileList = this.$refs.fileUpload.uploadFiles        // 获取文件列表let index = fileList.findIndex(item => {        // 把取消裁剪的图片删除return item.uid == this.currentFile.uid;});fileList.splice(index, 1)}},// 上传图片uploadImg(file) {this.uploadFile = file;// this.$refs.fileUpload.submit();// 判断裁剪后图片的宽高let img =  new Image()img.src = window.URL.createObjectURL(file);     // Blob转成url 才能给img显示img.onload = () => {let minProp = Math.min(img.width, img.height)  //裁剪后的图片宽,高  ==> 取最小值if( minProp < 500){     // 如果最小值比设置的最小值(默认为500)小this.$message.error(`请保证图片短边最小为500`);return false}this.$refs.fileUpload.submit();}},selectChange(file) {this.noCanUpload = falselet files = file.raw;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;}this.cropperImg = data;// 图片图片尺寸,如果是正方形,则直接上传;否则调用裁剪let img =  new Image()img.src = this.cropperImg;img.onload = () => {if(img.width == img.height){    // 本来就是正方形 => 直接上传this.uploadFile = files;this.$refs.fileUpload.submit();   // 调用上传方法}else{this.showCropper = true;      // 不是正方形的图片才开启裁剪this.currentFile = file       // 保存当前操作裁剪的图片}}};// 转化为base64// reader.readAsDataURL(file)// 转化为blobreader.readAsArrayBuffer(files);// this.showCropper = true;     // 默认开启裁剪}}
};
</script><style lang="scss">
.cropper-upload-box{display: flex;.el-upload{width: 148px;height: 148px;}
}
</style>

3.3 其他页面中调用裁剪组件

<!-- zoomScale:定义的裁剪比例;defaultImgList: 默认显示的图片列表@getUploadImg:这个事件将得到更新后(上传、删除)的图片列表,在页面中重新赋值给默认的列表变量后就可以做页面中的逻辑处理了-->
<cropper-upload :zoomScale='[1,1]' :defaultImgList="productImageList" @getUploadImg="getUploadImg"></cropper-upload>

自此,图片裁剪功能实现!!!

3.4 看一下页面中的效果

​​​​​​​

文章仅为本人学习过程的一个记录,仅供参考,如有问题,欢迎指出!

vue实现图片裁剪后上传相关推荐

  1. html上传图片裁剪,基于HTML5+JS实现本地图片裁剪并上传功能

    基于HTML5+JS实现本地图片裁剪并上传功能 2019-01-07 编程之家 https://www.jb51.cc 编程之家收集整理的这篇文章主要介绍了基于HTML5+JS实现本地图片裁剪并上传功 ...

  2. ie js html 压缩,H5图片裁剪-压缩-上传-神奇的Croppie.js

    Croppie.js之图片裁剪压缩上传 h5图片裁剪, 压缩, 上传, 预览是常见功能, 幸运的是我们有cropp.js这款利器. 1. style .actions button, .actions ...

  3. js图片压缩后上传方法,图片超过1M先进行压缩,然后再上传

    js图片压缩后上传方法,图片超过1M先进行压缩,然后再上传 图片上传目录 js图片压缩后上传方法,图片超过1M先进行压缩,然后再上传 html代码 js代码 html代码 <input type ...

  4. Bmob+Luban(鲁班)压缩图片实现相册选择图片压缩后上传到Bmob后台Glide加载图片显示到本地

    源代码已上传CSDN:https://download.csdn.net/download/qq_16519957/11068345 因为本章需要跟前面的知识结合起来看所以就做了一个前面链接方便大家查 ...

  5. 图片裁剪并上传,电脑手机均实用

    第一步:引入相应的js,这里提供裁剪工具的js,关于我里面引用的hui的前端js您可以去hui.admin的官网下载,资源链接:https://pan.baidu.com/s/1Pt47Fqn1UVj ...

  6. HTML5本地图片裁剪并上传

    最近做了一个项目,这个项目中需要实现的一个功能是:用户自定义头像(用户在本地选择一张图片,在本地将图片裁剪成满足系统要求尺寸的大小).这个功能的需求是:头像最初剪切为一个正方形.如果选择的图片小于规定 ...

  7. webuploader插件 前端实现图片旋转后上传

    前端上传图片正向的图片,上传后就被旋转了.这是因为,图片中包含许多属性来记录拍摄信息.引入EXIF就可以读取这些属性. 引入exif.js文件 exif.js文件下载地址:http://code.ci ...

  8. 前端获取图片压缩后上传给后台

    在做移动端图片上传的时候,用户传的都是手机本地图片,而本地图片一般都相对比较大,拿iphone6来说,平时拍很多图片都是一两M的,如果直接这样上传,那图片就太大了,如果用户用的是移动流量,完全把图片上 ...

  9. Mvc检查图片格式后上传

    /// <summary>/// 检查是否文件是否图片并保存/// </summary>/// <param name="file">文件< ...

最新文章

  1. PHP开发调试环境配置(基于wampserver+Eclipse for PHP Developers )
  2. linux 下oracle启动步骤
  3. linux下如何查看chm文件
  4. 应云而生,幽灵的威胁 - 云原生应用交付与运维
  5. Person matching query does not exist;Django增删改查异常
  6. 毛绒材质渲染_学室内设计必进,建模渲染那都不是事儿
  7. 奇妙的安全旅行之MD算法
  8. Java并发编程实战————并发技巧小结
  9. Java 约瑟夫环(循环链表解决)
  10. Android开发之 Android 的基本组件的概述
  11. spark mysql 写_Spark-SQL从MySQL中加载数据以及将数据写入到mysql中(Spark Shell方式,Spark SQL程序)...
  12. alter table 加多个字段_多个单列索引和联合索引的区别详解
  13. 计算机指纹驱动程序,解决方法:联想笔记本指纹识别驱动程序安装教程[详细]...
  14. 计算机论文撰写周记,电子与计算机毕业设计周记
  15. 关于施耐德PLC下载程序错误出现“断言失败:‘Abort=Quit,Retry=Debug,lgnore=Continue’”
  16. python3执行js之pyexecjs
  17. 外卖点餐管理系统源码
  18. stm32复位引脚NRST
  19. 安卓学习专栏——安卓报错Version 28 (intended for Android Pie and below) is the last version of the legacy suppor
  20. Maven是主要干嘛的呢

热门文章

  1. Unity新手入门项目——AngryBird(愤怒的小鸟)
  2. 什么是工作流,flowable 与 Activiti对比
  3. 最大股票收益问题(数组最大差问题)
  4. 02.安装开发者工具
  5. 单片机-蓝桥杯 用光敏电阻测量光照强度并显示在数码管上。
  6. DAC8822QBDBTR
  7. VSTO 学习笔记(十二)自定义公式与Ribbon
  8. 教你按秒数简单删除全部视频的片头片尾
  9. language model with pointer network
  10. chrome网页调试工具的使用步骤