1、安装
npm install vue-cropper
2、使用
在main.js文件中引入和使用
import VueCropper from 'vue-cropper'
Vue.use(VueCropper)
3、上传函数的触发,‘<el-upload>标签为element的标签,如果不知道请直接了解https://element.eleme.cn/#/zh-CN/component/upload’
<el-upload id="uploadClick" action="" name="file" :beforeUpload="beforeUpload">
<div class="el_upload_l flex_justify_center flex_align_center" v-if="uploadImgShow">
<div>+
<div style="height: 10.5rem;width: 7.5rem;" v-else>
<img class="height_100 width_100" :src="uploadImg"/>
</el-upload>
4、弹出图片裁剪的组件‘<el-dialog>标签为element的对话框组件https://element.eleme.cn/#/zh-CN/component/dialog’
<el-dialog title="图片剪裁" :visible.sync="dialogVisible" append-to-body fullscreen>
<div class="cropper-content">
<div class="cropper" style="text-align:center">
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"
>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible= false">取 消
<el-button type="primary" @click="finish" :loading="loading">确认
</el-dialog>
5、css样式*‘以下样式一定要写,不然会显示不出截图的背景最终显示为NAN’*
.cropper-content .cropper {
width:auto;
height:300px;
}
6、组件内data的数据配置
data(){
return{
uploadImgShow:true,//控制显示上传了的图片还是未上传的+号
uploadImg:null,//上传后接口返回的图片链接
dialogVisible:false,//图片截图的对话框是否显示控制
option: {
img:'', // 裁剪图片的地址
info:true, // 裁剪框的大小信息
outputSize:0.8, // 裁剪生成图片的质量
outputType:'jpeg', // 裁剪生成图片的格式
canScale:false, // 图片是否允许滚轮缩放
autoCrop:true, // 是否默认生成截图框
fixedBox:true, // 固定截图框大小 不允许改变
fixed:true, // 是否开启截图框宽高固定比例
fixedNumber: [5, 7], // 截图框的宽高比例
full:true, // 是否输出原图比例的截图
canMoveBox:false, // 截图框能否拖动
original:false, // 上传图片按照原始比例渲染
centerBox:false, // 截图框是否被限制在图片里面
infoTrue:true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
},
// 防止重复提交
loading:false,
}
}
7、封装压缩和base64转成bolb对象的函数再public.js文件中
// 压缩图片
export function compress(img) {
let canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d"),
initSize = img.src.length;
let width = img.width
let height = img.height;
canvas.width = width
canvas.height = height
// 铺底色
ctx.fillStyle ="#fff"
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(img, 0, 0, width, height)
//进行压缩
let ndata = canvas.toDataURL("image/jpeg", 0.5)
//console.log("压缩后的图片大小:" + ndata.length)
return ndata
}
// base64转成bolb对象
export function dataURItoBlob(base64Data) {
let byteString
if (base64Data.split(",")[0].indexOf("base64") >=0)
byteString =atob(base64Data.split(",")[1])
else
byteString =unescape(base64Data.split(",")[1])
let mimeString = base64Data .split(",")[0] .split(":")[1] .split(";")[0];
let ia =new Uint8Array(byteString.length);
for (let i =0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type: mimeString })
}
8、在组件中引入上面两个封装函数
import {compress,dataURItoBlob}from '@/assets/js/public.js';
import axios from 'axios';
9、函数的封装
//上传图片
beforeUpload(file){
const reader =new FileReader()
this.fileinfo = file;
reader.readAsDataURL(file)
reader.onload = () => {
this.option.img = reader.result;
this.dialogVisible =true
}
return false
},
//点击图片上传函数
finish() {
this.$refs.cropper.getCropData((data) => {
const that =this
let img =new Image()
img.src = data
img.onload =function() {
let _data = compress(img);
let blob = dataURItoBlob(_data)
let formData =new FormData()
formData.append('file', blob, Math.floor(Math.random() *1000000000000))
this.loading =true
axios.post('/*上传的图片服务器路径*/', formData, {contentType:false, processData:false, headers: {'Content-Type':'application/x-www-form-urlencoded' } }).then((res) => {
that.loading =false;
that.uploadImgShow =false;
that.dialogVisible =false;
that.uploadImg = res.data.qiniuUrl;
that.$toast.success({message:'上传成功!', duration:1000});
})
}
})
},
10、效果显示