上传图片之前,按照一定比例进行剪裁,剪裁后上传到服务器
官方地址
安装
npm install vue-cropper
<template><div class="show-info"><div class="test test1"><vueCropperref="cropper":img="option.img":outputSize="option.size":outputType="option.outputType":info="true":full="option.full":canMove="option.canMove":canMoveBox="option.canMoveBox":fixedBox="option.fixedBox":original="option.original":autoCrop="option.autoCrop":autoCropWidth="option.autoCropWidth":autoCropHeight="option.autoCropHeight":centerBox="option.centerBox":high="option.high":infoTrue="option.infoTrue"@realTime="realTime"@imgLoad="imgLoad"@cropMoving="cropMoving":enlarge="option.enlarge"></vueCropper></div><div class="test-button"><button @click="changeImg" class="btn">随机图片</button><label class="btn" for="uploads">上传图片</label><inputtype="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)"/><button @click="startCrop" v-if="!crap" class="btn">开始裁剪</button><button @click="stopCrop" v-else class="btn">停止裁剪</button><button @click="clearCrop" class="btn">清除</button><button @click="refreshCrop" class="btn">刷新</button><button @click="changeScale(1)" class="btn">放大</button><button @click="changeScale(-1)" class="btn">缩小</button><button @click="rotateLeft" class="btn">左旋转</button><button @click="rotateRight" class="btn">右旋转</button><button @click="finish('base64')" class="btn">生成图片base64</button><button @click="finish('blob')" class="btn">生成图片blob</button><a @click="down('base64')" class="btn">base64下载</a><a @click="down('blob')" class="btn">blob下载</a><a :href="downImg" download="demo.png" ref="downloadDom">{{ downImg }}</a></div><!-- --><div class="box"><div class="input"><h3>输出图片</h3><divclass="show-preview":style="{ width: previews.w + 'px', height: previews.h + 'px', overflow: 'hidden', margin: '5px' }"><div :style="previews.div"><img :src="previews.url" :style="previews.img" /></div></div></div><el-row ><el-col :span="12" class="c-item"><span>上传图片是否显示原始宽高 (针对大图 可以铺满)</span><input type="checkbox" v-model="option.original" /><span>original: {{ option.original }}</span></el-col><el-col :span="12" class="c-item"><span>是否根据dpr生成适合屏幕的高清图片</span><input type="checkbox" v-model="option.high" /><span>high: {{ option.high }}</span></el-col><el-col :span="12" class="c-item"><span>是否输出原图比例的截图</span><input type="checkbox" v-model="option.full" /><span>full: {{ option.full }}</span></el-col><el-col :span="12" class="c-item"><span>截图信息展示是否是真实的输出宽高</span><input type="checkbox" v-model="option.infoTrue" /><span>infoTrue: {{ option.infoTrue }}</span></el-col><el-col :span="12" class="c-item"><span>能否拖动图片</span><input type="checkbox" v-model="option.canMove" /><span>canMove: {{ option.canMove }}</span></el-col><el-col :span="12" class="c-item"><span>能否拖动截图框</span><input type="checkbox" v-model="option.canMoveBox" /><span>canMoveBox: {{ option.canMoveBox }}</span></el-col><el-col :span="12" class="c-item"><span>截图框固定大小</span><input type="checkbox" v-model="option.fixedBox" /><span>fixedBox: {{ option.fixedBox }}</span></el-col><el-col :span="12" class="c-item"><span>是否自动生成截图框</span><input type="checkbox" v-model="option.autoCrop" /><span>autoCrop: {{ option.autoCrop }}</span></el-col><el-col :span="12" class="c-item"><span>截图框是否限制在图片里(只有在自动生成截图框时才能生效)</span><input type="checkbox" v-model="option.centerBox" /><span>centerBox: {{ option.centerBox }}</span></el-col><el-col :span="12" class="c-item"><span>是否按照截图框比例输出 默认为1 </span><input type="number" v-model="option.enlarge" /></el-col><el-col :span="12" class="c-item"><span>输出图片格式 </span><label><input type="radio" name="type" value="jpeg" v-model="option.outputType" />jpeg </label><label><input type="radio" name="type" value="jpg" v-model="option.outputType" />jpg </label><label> <input type="radio" name="type" value="png" v-model="option.outputType" />png</label><label> <input type="radio" name="type" value="webp" v-model="option.outputType" />webp</label></el-col></el-row></div><div slot="body">{{ code1 }}</div></div></template><script>import { VueCropper } from 'vue-cropper'export default {components: {VueCropper,},data() {return {// 初始化值option: {size: 1,full: true, // 是否输出原图比例的截图canMove: true, // 上传图片是否可以移动fixedBox: false, // 固定截图框大小 不允许改变original: false, // 上传图片按照原始比例渲染canMoveBox: true, // 截图框能否拖动img: 'https://avatars3.githubusercontent.com/u/15681693', // url 地址 || base64 || blob nulloutputSize: 1, // 裁剪生成图片的质量 1 (0-1)outputType: 'jpg', // 裁剪生成图片的格式 jpg (jpg 需要传入jpeg)info: '', // 裁剪框的大小信息 truecanScale: true, // 图片是否允许滚轮缩放 trueautoCrop: true, // 是否默认生成截图框 falsefixed: true, // 是否开启截图框宽高固定比例 true// 只有自动截图开启 宽度高度才生效autoCropWidth: 200, // 默认生成截图框宽度autoCropHeight: 150, // 默认生成截图框高度centerBox: true, // 截图框是否被限制在图片里面high: true, // 是否按照设备的dpr 输出等比例图片infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高w: 200,h: 200,maxImgSize: 1200, // 限制图片最大宽度和高度// enlarge:1, //图片根据截图框输出比例倍数// fixedNumber:[1,1] // 截图框的宽高比例// mode: 'contain',},// 截图后值previews: {},crap: false,previewStyle1: {},previewStyle2: {},code1: '',lists: [{img: 'https://img2.baidu.com/it/u=2102736929,2417598652&fm=26&fmt=auto&gp=0.jpg',},{img: 'https://img0.baidu.com/it/u=1330784235,4146572500&fm=26&fmt=auto&gp=0.jpg',},{img: 'https://img0.baidu.com/it/u=4015235454,569502415&fm=26&fmt=auto&gp=0.jpg',},{img: 'https://img2.baidu.com/it/u=3566088443,3713209594&fm=26&fmt=auto&gp=0.jpg',},{img: 'https://img0.baidu.com/it/u=3870964477,3746012709&fm=26&fmt=auto&gp=0.jpg',},{img: 'https://img2.baidu.com/it/u=360400461,2955275651&fm=26&fmt=auto&gp=0.jpg',},],index: 0,downImg: '',}},mounted() {console.log(window['vue-cropper'])},methods: {// 上传图片uploadImg(val, num) {console.log(val, num)const file = val.target.files[0]if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(val.target.value)) {console.log('图片类型必须是.gif,jpeg,jpg,png,bmp中的一种')return false}const reader = new FileReader()reader.onload = e => {let dataif (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} else if (num === 2) {this.example2.img = data}this.previews = this.optionconsole.log(this.option.img)}// 转化为base64// reader.readAsDataURL(file)// 转化为blobreader.readAsArrayBuffer(file)},imgLoad(val) {console.log(val)},// 截图框移动回调函数cropMoving(val) {console.log(val)},changeImg(val) {const num = Math.ceil(Math.random() * this.lists.length)console.log(val, num, this.lists[num].img)this.option.img = this.lists[num].img},// 开始截图startCrop() {this.crap = truethis.$refs.cropper.startCrop()},// 停止截图stopCrop() {this.crap = falsethis.$refs.cropper.stopCrop()},// 清除截图clearCrop() {this.$refs.cropper.clearCrop()},// 刷新refreshCrop(val) {console.log(val)this.$refs.cropper.refresh()},// 修改图片大小 正数为变大 负数变小changeScale(val) {console.log(val)const num = val || 1this.$refs.cropper.changeScale(num)},// 向右边旋转90度rotateLeft(val) {console.log(val)this.$refs.cropper.rotateRight()},// 向左边旋转90度rotateRight(val) {console.log(val)this.$refs.cropper.rotateLeft()},// 获取截图信息getInfo() {const W = this.$refs.cropper.cropW // 截图框宽度const H = this.$refs.cropper.cropH // 截图框高度console.log(W, H)},// down 下载down(val) {console.log(val)const aLink = document.createElement('a')aLink.download = 'demo'// 输出if (val === 'blob') {// 获取截图的blob数据this.$refs.cropper.getCropBlob(data => {this.downImg = window.URL.createObjectURL(data)aLink.href = window.URL.createObjectURL(data)aLink.click()})} else {// 获取截图的base64 数据this.$refs.cropper.getCropData(data => {this.downImg = dataaLink.href = dataaLink.click()})}},// 输出finish(val) {console.log(val)// const test = window.open('about:blank')// test.document.body.innerHTML = '图片生成中..'if (val === 'blob') {this.$refs.cropper.getCropBlob(data => {const img = window.URL.createObjectURL(data)this.model = truethis.modelSrc = img})} else {this.$refs.cropper.getCropData(data => {this.model = truethis.modelSrc = data})}},// 添加预览realTime(data) {console.log(data)this.previews = data},// 获取图片基于容器的坐标点getImgAxis(val) {console.log(val)this.$refs.cropper.getImgAxis()},// 获取截图框基于容器的坐标点getCropAxis(val) {console.log(val)this.$refs.cropper.getCropAxis()},// 自动生成截图框函数goAutoCrop(val) {const go = this.$refs.cropper.goAutoCropconsole.log(val, go)},finish2(type) {console.log(type)this.$refs.cropper2.getCropData(data => {this.model = truethis.modelSrc = data})},finish3(type) {console.log(type)this.$refs.cropper3.getCropData(data => {this.model = truethis.modelSrc = data})},},}</script><style lang="scss" scoped>.box {display: flex;}.cut {width: 500px;height: 500px;margin: 30px auto;}.c-item {max-width: 500px;margin: 10px auto;margin-top: 12px;}.content {margin: auto;max-width: 1200px;margin-bottom: 100px;}.test-button {display: flex;flex-wrap: wrap;align-content: center;justify-content: center;}.set{display: flex;}.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;}.des {line-height: 30px;}code.language-html {padding: 10px 20px;margin: 10px 0px;display: block;background-color: #333;color: #fff;overflow-x: auto;font-family: Consolas, Monaco, Droid, Sans, Mono, Source, Code, Pro, Menlo, Lucida, Sans, Type, Writer, Ubuntu, Mono;border-radius: 5px;white-space: pre;}.show-info {margin-bottom: 10px;margin-top: 10px;}.show-info h2 {line-height: 50px;}/*.title, .title:hover, .title-focus, .title:visited {color: black;}*/.title {display: block;text-decoration: none;text-align: center;line-height: 1.5;margin: 20px 0px;background-image: -webkit-linear-gradient(left,#3498db,#f47920 10%,#d71345 20%,#f7acbc 30%,#ffd400 40%,#3498db 50%,#f47920 60%,#d71345 70%,#f7acbc 80%,#ffd400 90%,#3498db);color: transparent;-webkit-background-clip: text;background-size: 200% 100%;animation: slide 5s infinite linear;font-size: 40px;}.test {height: 500px;}.model {position: fixed;z-index: 10;width: 100vw;height: 100vh;overflow: auto;top: 0;left: 0;background: rgba(0, 0, 0, 0.8);}.model-show {display: flex;justify-content: center;align-items: center;width: 100vw;height: 100vh;}.model img {display: block;margin: auto;max-width: 80%;user-select: none;background-position: 0px 0px, 10px 10px;background-size: 20px 20px;background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%),linear-gradient(45deg, #eee 25%, white 25%, white 75%, #eee 75%, #eee 100%);}.c-item {display: block;user-select: none;}@keyframes slide {0% {background-position: 0 0;}100% {background-position: -100% 0;}}</style>
