环境准备
- 网址: https://www.npmjs.com/package/vue-cropper.
- npm install vue-cropper 安装
- Vue.prototype.$http =service; 全局挂载
思路
1,从elementui的上传组件拿到file对象
2,解析file对象拿到blob对象
参数列表
用法
<cropper :pic.sync="item.url" ></cropper>
cropper组件
<template>
<div>
<div class="el-upload el-upload--picture-card">
<el-upload class="upload-body" accept="image/*" ref="eupload" :multiple="false" :on-change="handleCrop"
:http-request="uploadImg" :show-file-list="false" action="string">
<img v-if="imageUrl" :src="imageUrl|formatUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</div>
<cropper-img @upload="handleUpload" :file.sync='file'></cropper-img>
</div>
</template>
<script>
import CropperImg from './cropper-img.vue'
import uploadUrl from '../../config/globe.js'
export default {
name: 'cropper',
data() {
return {
file: {},
imageUrlVisible: false,
dialogImageUrl: '',
imageUrl: '',
}
},
filters: {
formatUrl(url) {
if (url) {
return `${uploadUrl}/${url}`;
}
}
},
components: {
CropperImg,
},
props: {
pic: {
type: String,
default: ''
}
},
methods: {
uploadImg(data) {
},
handleUpload(data) {
//上传到服务器
var that = this;
let formData = new FormData();
formData.append("file", data, this.file.name);
this.$http
.upload(`后台上传接口地址`, formData)
.then(res => {
that.imageUrl = res.body.data;
that.updateData();
});
},
updateData() {
this.$emit("update:pic", this.imageUrl);
},
handleCrop(file) {
this.file = file;
}
}
}
</script>
<style>
.avatar {
width: 146px;
height: 146px;
display: block;
}
</style>
裁剪处理(CropperImg )
<template>
<el-dialog title="裁剪图片" :visible.sync="cropperVisible" width="1000px" height="700px" :close-on-click-modal="false"
:append-to-body="true">
<div class="cropper-content">
<div class="cropper-box">
<div class="cropper">
<vueCropper 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"></vueCropper>
</div>
</div>
<div class="show-preview" :style="{'width':previews.w + 'px', 'height': previews.h + 'px', 'overflow': 'hidden', 'margin': '5px'}">
<div :style="previews.div" class="cr-preview">
<img :src="previews.url" :style="previews.img" />
</div>
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" icon="el-icon-zoom-in" @click="changeScale(1)"></el-button>
<el-button type="primary" icon="el-icon-zoom-out" @click="changeScale(-1)"></el-button>
<el-button type="primary" @click="rotateLeft">逆时针旋转</el-button>
<el-button type="primary" @click="rotateRight">顺时针旋转</el-button>
<el-button type="primary" @click="uploadImg">上传</el-button>
<el-button @click="cropperVisible = false">取 消</el-button>
</span>
</el-dialog>
</template>
<script>
import {
VueCropper
} from 'vue-cropper'
export default {
props: ['file'],
data() {
return {
option: {
img: "", // 裁剪图片的地址 (默认:空)
outputSize: 1, // 裁剪生成图片的质量 (默认:1)
full: false, // 是否输出原图比例的截图 选true生成的图片会非常大 (默认:false)
outputType: "png", // 裁剪生成图片的格式 (默认:jpg)
canMove: true, // 上传图片是否可以移动 (默认:true)
original: false, // 上传图片按照原始比例渲染 (默认:false)
canMoveBox: true, // 截图框能否拖动 (默认:true)
autoCrop: true, // 是否默认生成截图框 (默认:false)
fixedBox: false, // 固定截图框大小 不允许改变 (默认:false)
enlarge: 1,
fixedNumber: [1, 1]
},
cropperVisible: false,
previews: {}, // 预览数据
};
},
components: {
VueCropper,
},
watch: {
file(val, oldVal) {
this.init();
},
},
methods: {
realTime(data) {
// 实时预览
this.previews = data;
},
imgLoad(msg) {
console.log(msg)
},
//调整裁切图片大小
changeCropImg(w, h) {
// this.option.fixedNumber = [w,h];
this.$refs.cropper.changeCrop(1, 1);
},
//图片缩放
changeScale(num) {
num = num || 1
this.$refs.cropper.changeScale(num)
},
//向左旋转
rotateLeft() {
this.$refs.cropper.rotateLeft()
},
//向右旋转
rotateRight() {
this.$refs.cropper.rotateRight()
},
// 实时预览函数
realTime(data) {
this.previews = data
},
uploadImg() {
var that = this;
this.$refs.cropper.getCropBlob(data => {
that.$emit("upload", data);
that.cropperVisible = false;
});
},
init() {
var test = this.file;
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.cropperVisible = true;
}
reader.readAsArrayBuffer(this.file.raw);
}
}
}
</script>
<style>
.cropper-content {
display: flex;
display: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
}
.cropper-content .cropper {
width: 500px;
height: 400px;
}
.cropper-content .show-preview {
flex: 1;
-webkit-flex: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
overflow: hidden;
border: 1px solid #cccccc;
background: #cccccc;
margin-left: 40px;
}
.cr-preview {
overflow: hidden;
border: 1px solid #cccccc;
background: #cccccc;
}
</style>
截图效果
上传按钮
裁剪框
裁剪效果