1、安装:npm install vue-cropper
2、引入:import VueCropper from 'vue-cropper'
Vue.use(VueCropper)
<template> <div class='box'> <el-button @click='dialogImg=true'>截图</el-button> <div class="img"> <img style=" 100%; height: 100%;" v-if="option.img" :src="option.img" alt="" /> </div> <el-dialog class="dialogImgClass" title="" :visible.sync="dialogImg" size="middle" :before-close="handleClose1"> <div class="dialogBox"> <el-row> <span style="margin-right:20px;">切图工具比例</span> <el-radio-group v-model="pictureRatio" @change="changePicRatio"> <el-radio class="radio" label="1">16:9</el-radio> <el-radio class="radio" label="2">1:1</el-radio> <el-radio class="radio" label="3">无</el-radio> </el-radio-group> </el-row> <div class="wrapper"> <vueCropper style="border: 1px solid;" ref="cropper" :img="option.img" :outputSize="option.size" :outputType="option.outputType" :info="option.info" :canScale="option.canScale" :autoCrop="option.autoCrop" :autoCropWidth="option.autoCropWidth" :autoCropHeight="option.autoCropHeight" :fixed="option.fixed" :fixedNumber="option.fixedNumber" :full="option.full" :centerBox="option.centerBox" :original="option.original" @realTime="realTime"> </vueCropper> </div> <div class="btn-box"> <label class="btn" for="upload">选择照片</label> <input name="file" type="file" id="upload" style="position:absolute; clip:rect(0 0 0 0);" accept="image/png, image/jpeg, image/gif, image/jpg" @change="uploadImg($event)"> <el-button :plain="true" type="danger" style="background: #e03434;color: #fff;" @click="finishUpdate('base64')">上传照片</el-button> </div> </div> </el-dialog> </div> </template> <script> import {VueCropper} from 'vue-cropper' import api from '../fetch/api' export default { data () { return { dialogImg:false, pictureRatio:"2",//根据选项修改图片比例 exam:null, option:{ img: '', info: true, size: 1, outputType: 'png', canScale:true, autoCrop: true, // 只有自动截图开启 宽度高度才生效 autoCropWidth: 540, autoCropHeight: 540, // 开启宽度和高度比例 fixed: true, fixedNumber: [16, 16], fileaa:null, full:true,//输出原图比例的截图 centerBox:true,//截图框是否限制在图片里(只有自动截图开启才生效) original:false,//上传图片是否显示原始宽高(针对大图,可以铺满) }, qiniu:{ key:'', token:'', file:'' },//七牛云数据 } }, components: { 'vueCropper': VueCropper }, created(){ }, methods: { changePicRatio(val){//切换图片比例 // console.log(val); if(val==="1"){ this.option.fixedNumber = [16, 9]; this.option.autoCrop = true; this.option.fixed = true; if(this.exam != null){ this.$refs.cropper.clearCrop(); this.$refs.cropper.startCrop(); this.uploadImg (this.exam); console.log("改成16:9"); }else if(this.option.img != ''){ this.$refs.cropper.clearCrop(); this.$refs.cropper.startCrop(); } }else if(val==="2"){ this.option.fixedNumber = [16, 16]; this.option.autoCrop = true; this.option.fixed = true; if(this.exam != null){ this.$refs.cropper.clearCrop(); this.$refs.cropper.startCrop(); this.uploadImg (this.exam); console.log("改成1:1"); }else if(this.option.img != ''){ this.$refs.cropper.clearCrop(); this.$refs.cropper.startCrop(); } }else if(val==="3"){ this.option.autoCrop = false; this.option.fixed = false; this.$refs.cropper.clearCrop(); this.$refs.cropper.startCrop(); } }, uploadImg (e) { this.exam=e; //上传图片 // this.option.img var file = e.target.files[0] 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 } this.option.img = data } this.fileaa = e.target.files[0]; console.log(this.fileaa); // 转化为base64 reader.readAsDataURL(file) // 转化为blob // reader.readAsArrayBuffer(file) }, finishUpdate(type){ this.$refs.cropper.getCropData((data)=>{ this.option.img = data; let pic = data.replace(/^.*?,/, ''); let size = this.fileSize(pic); let data1 = {}; api.get(api.config.getUploadVoucher,data1).then(res=>{ if(res.code==1){ console.log(res); this.qiniu.key = res.data.mediaKey; this.qiniu.token = res.data.token; let id = res.data.mediaId; this.fileId = res.data.mediaId; let url = "http://up-z2.qiniu.com/putb64/"+size+"/key/"+this.baseCode64(this.qiniu.key); var xhr = new XMLHttpRequest(); xhr.onreadystatechange=function(){ if (xhr.readyState==4){ console.log(xhr.responseText) } } xhr.open("POST", url, true); xhr.setRequestHeader("Content-Type", "application/octet-stream"); xhr.setRequestHeader("Authorization", "UpToken "+this.qiniu.token); xhr.send(pic); this.dialogImg = false; } }) }) }, fileSize(base64){ let fileSize; //找到等号,把等号也去掉 if (base64.indexOf('=') > 0) { var indexOf = base64.indexOf('='); base64 = base64.substring(0, indexOf);//把末尾的’=‘号去掉 } fileSize = parseInt(base64.length - (base64.length / 8) * 2); return fileSize; }, baseCode64(input){ var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = this._utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); } return output; }, _utf8_encode(string) { string = string.replace(/ /g," "); var utftext = ""; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; }, handleClose1(){ this.dialogImg = false; }, realTime (data) { this.previews = data }, } } </script> <style lang='stylus' scoped> .img{ width 500px } .dialogBox{ position:relative height:640px } .dialogBox .wrapper{ 540px height:540px } .dialogBox .btn-box{ position:absolute 200px right:0 bottom:0 } .dialogBox .btn{ background:#e03434 color:#fff font-size:14px line-height:1 cursor:pointer margin:0 white-space:nowrap border:1px solid #ddd border-radius:4px padding:9px 15px box-sizing: border-box } </style>