<template> <el-dialog title="图片剪裁" :visible.sync="dialogVisible" v-if="dialogVisible" append-to-body :width='diawidth' :show-close="false" @close="closeupimg"> <el-row type="flex" justify="" > <label class="el-button el-button--primary" for="uploads" style="margin-right:20px">选择图片</label> <input type="file" id="uploads" style="position:absolute; clip:rect(0 0 0 0);" accept="image/png, image/jpeg, image/gif, image/jpg" @change="uploadImg($event, 1)"> <el-button type="success" icon="el-icon-zoom-in" @click="changeScale(1)"></el-button> <el-button type="success" icon="el-icon-zoom-out" @click="changeScale(-1)"></el-button> <el-button type="success" icon="el-icon-refresh-left" @click="rotateLeft"></el-button> <el-button type="success" icon="el-icon-refresh-right" @click="rotateRight"></el-button> <!-- <el-button type="success" icon="el-icon-download" @click="down('blob')">下载</el-button> --> </el-row> <el-row> <div class="cropper-content"> <div class="cropper" :style="{'width':`${width+50}px`,'height':`${height+50}px`}"> <vue-cropper 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" ></vue-cropper> </div> <!-- 预览框 --> <div v-show='false' class="show-preview" :style="{ 'overflow': 'hidden'}"> <div :style="previews.div" class="preview"> <img :src="previews.url" :style="previews.img"> </div> </div> </div> </el-row> <div slot="footer"> <el-button @click="closeupimg" >取 消</el-button> <el-button type="primary" @click="finish('blob')">确认上传</el-button> </div> </el-dialog> </template> <script> export default { props: ['width', 'height'], data () { return { dialogVisible: false, headImg: '', //剪切图片上传 crap: false, previews: {}, option: { img: '', // 裁剪图片的地址 // info: true, // 裁剪框的大小信息 outputSize: 1, // 裁剪生成图片的质量 outputType: 'png', // 裁剪生成图片的格式 canScale: false, // 图片是否允许滚轮缩放 full: false, //输出原图比例截图 props名full canMove: true, original: false, // 上传图片按照原始比例渲染 canMoveBox: true, // 截图框能否拖动 autoCrop: true, // 是否默认生成截图框 autoCropWidth: this.width || 200, // 默认生成截图框宽度 autoCropHeight: this.height || 200, // 默认生成截图框高度 fixedBox: true, // 固定截图框大小 不允许改变 fixed: true, // 是否开启截图框宽高固定比例 fixedNumber: [2, 1], // 截图框的宽高比例 centerBox: false, // 截图框是否被限制在图片里面 infoTrue: true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高 }, fileName: '', //本机文件地址 downImg: '#', imgFile: '', uploadImgRelaPath: '', //上传后的图片的地址(不带服务器域名) imgType: '' } }, computed: { diawidth () { if (this.width > 700) { return `${this.width + 150}px` } else { return '50%' } } }, methods: { init (type) { this.imgType = type || '' this.dialogVisible = true }, //放大/缩小 changeScale (num) { this.$forceUpdate() if (this.option.img == '') { return this.$message.error('请选择图片后操作!') } else { num = num || 1 this.$refs.cropper.changeScale(num) } }, //坐旋转 rotateLeft () { // console.log('rotateLeft') this.$forceUpdate() if (this.option.img == '') { return this.$message.error('请选择图片后操作!') } else { this.$refs.cropper.rotateLeft() } }, //右旋转 rotateRight () { this.$forceUpdate() // console.log('rotateRight') if (this.option.img == '') { return this.$message.error('请选择图片后操作!') } else { this.$refs.cropper.rotateRight() } }, //上传图片(点击上传按钮) finish (type) { // console.log('finish') this.$showLoading() let _this = this let formData = new FormData() // 输出 if (type === 'blob') { this.$refs.cropper.getCropBlob((data) => { let img = window.URL.createObjectURL(data) this.model = true this.modelSrc = img // formData.append("file", data, this.fileName); formData.append('type', _this.imgType) formData.append('file', data) this.$http({ url: this.$http.adornUrl(`/upload/uploadFile`), method: 'post', data: formData }).then((data) => { if (data && data.code === 0) { this.headImg = data.bean.id this.$emit('uploadSuccess', this.headImg, this.modelSrc) this.$showLoading('close') this.$message.success('上传成功!') this.dialogVisible = false } else { this.$message.error('上传失败!') } }) }) } else { this.$refs.cropper.getCropData((data) => { this.model = true this.modelSrc = data }) } }, // 实时预览函数 realTime (data) { // console.log('realTime') // this.previews = data }, //下载图片 down (type) { this.error_cc() // console.log('down') var aLink = document.createElement('a') aLink.download = 'author-img' if (type === 'blob') { this.$refs.cropper.getCropBlob((data) => { this.downImg = window.URL.createObjectURL(data) aLink.href = window.URL.createObjectURL(data) aLink.click() }) } else { this.$refs.cropper.getCropData((data) => { this.downImg = data aLink.href = data aLink.click() }) } }, //选择本地图片 uploadImg (e, num) { var _this = this //上传图片 var file = e.target.files[0] _this.fileName = file.name if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) { this.$message.error('图片类型必须是.gif,jpeg,jpg,png,bmp中的一种') return false } else if (file.size > 1048576) { this.$message.error('图片大小必须小于1M!') return false } var reader = new FileReader() // reader.readAsDataURL(file); 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) { _this.option.img = data _this.headImg = data _this.$forceUpdate() } else if (num === 2) { _this.$forceUpdate() _this.example2.img = data } } _this.$forceUpdate() // 转化为base64 reader.readAsDataURL(file) // 转化为blob // reader.readAsArrayBuffer(file); }, imgLoad (msg) { // console.log('imgLoad') // console.log(msg) }, closeupimg () { this.dialogVisible = false // this.$refs.cropper.clearCrop() //清除截图 } } } </script> <style > .info { width: 720px; margin: 0 auto; } .info .oper-dv { height: 20px; text-align: right; margin-right: 100px; } .info .oper-dv a { font-weight: 500; } .info .oper-dv a:last-child { margin-left: 30px; } .info .info-item { margin-top: 15px; } .info .info-item label { display: inline-block; width: 100px; text-align: right; } .info .info-item .sel-img-dv { position: relative; } .info .info-item .sel-img-dv .sel-file { position: absolute; width: 90px; height: 30px; opacity: 0; cursor: pointer; z-index: 2; } .info .info-item .sel-img-dv .sel-btn { position: absolute; cursor: pointer; z-index: 1; } .cropper-content { width: 100%; margin:50px auto; display: flex; flex-wrap: wrap; flex-direction: column; align-items: center; display: -webkit-flex; justify-content: space-around; -webkit-justify-content: space-around; } .cropper-content .show-preview { margin-top: 50px; flex: 1; -webkit-flex: 1; display: flex; display: -webkit-flex; justify-content: center; -webkit-justify-content: center; } .cropper-content .show-preview .preview { overflow: hidden; /* border-radius: 50%; */ border: 1px solid #666; background: #ccc; } </style>