vue项目图片裁剪上传——vue-cropper的使用,裁剪后上传头像
npm地址:https://www.npmjs.com/package/vue-cropper
github地址:https://github.com/xyxiao001/vue-cropper
在线demo:http://github.xyxiao.cn/vue-cropper/example/
vue2-demo:https://codepen.io/xyxiao001/pen/wxwKGz
vue3-demo:https://codepen.io/xyxiao001/pen/yLooYKg
1、基本使用
1、安装
npm install vue-cropper
npm install vue-cropper --save-dev
yarn add vue-cropper
实例1
封装upload-cropper组件
<template>
<div class="cropper-content">
<div class="cropper-box">
<div class="cropper">
<vue-cropper
ref="cropper"
:img="option.img"
:outputSize="option.outputSize"
: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"
:fixedBox="option.fixedBox"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:centerBox="option.centerBox"
:height="option.height"
:infoTrue="option.infoTrue"
:maxImgSize="option.maxImgSize"
:enlarge="option.enlarge"
:mode="option.mode"
@realTime="realTime"
@imgLoad="imgLoad">
</vue-cropper>
</div>
<!--底部操作工具按钮-->
<div class="footer-btn">
<div class="scope-btn">
<label class="btn" for="uploads">选择封面</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="selectImg($event)">
<el-button size="mini" type="danger" plain icon="el-icon-zoom-in" @click="changeScale(1)">放大</el-button>
<el-button size="mini" type="danger" plain icon="el-icon-zoom-out" @click="changeScale(-1)">缩小</el-button>
<el-button size="mini" type="danger" plain @click="rotateLeft">↺ 左旋转</el-button>
<el-button size="mini" type="danger" plain @click="rotateRight">↻ 右旋转</el-button>
</div>
<div class="upload-btn">
<el-button size="mini" type="success" @click="uploadImg('blob')">上传封面 <i class="el-icon-upload"></i></el-button>
</div>
</div>
</div>
<!--预览效果图-->
<div class="show-preview">
<div :style="previews.div" class="preview">
<img :src="previews.url" :style="previews.img">
</div>
</div>
</div>
</template>
<script>
import { VueCropper } from 'vue-cropper'
export default {
name: "CropperImage",
components: {
VueCropper
},
props:['Name'],
data() {
return {
name:this.Name,
previews: {},
option:{
img: '', //裁剪图片的地址
outputSize: 1, //裁剪生成图片的质量(可选0.1 - 1)
outputType: 'jpeg', //裁剪生成图片的格式(jpeg || png || webp)
info: true, //图片大小信息
canScale: true, //图片是否允许滚轮缩放
autoCrop: true, //是否默认生成截图框
autoCropWidth: 230, //默认生成截图框宽度
autoCropHeight: 150, //默认生成截图框高度
fixed: true, //是否开启截图框宽高固定比例
fixedNumber: [1.53, 1], //截图框的宽高比例
full: false, //false按原比例裁切图片,不失真
fixedBox: true, //固定截图框大小,不允许改变
canMove: false, //上传图片是否可以移动
canMoveBox: true, //截图框能否拖动
original: false, //上传图片按照原始比例渲染
centerBox: false, //截图框是否被限制在图片里面
height: true, //是否按照设备的dpr 输出等比例图片
infoTrue: false, //true为展示真实输出图片宽高,false展示看到的截图框宽高
maxImgSize: 3000, //限制图片最大宽度和高度
enlarge: 1, //图片根据截图框输出比例倍数
mode: '230px 150px' //图片默认渲染方式
}
};
},
methods: {
//初始化函数
imgLoad (msg) {
console.log("工具初始化函数====="+msg)
},
//图片缩放
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
},
//选择图片
selectImg (e) {
let file = e.target.files[0]
if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) {
this.$message({
message: '图片类型要求:jpeg、jpg、png',
type: "error"
});
return false
}
//转化为blob
let reader = new FileReader()
reader.onload = (e) => {
let data
if (typeof e.target.result === 'object') {
data = window.URL.createObjectURL(new Blob([e.target.result]))
} else {
data = e.target.result
}
this.option.img = data
}
//转化为base64
reader.readAsDataURL(file)
},
//上传图片
uploadImg (type) {
let _this = this;
if (type === 'blob') {
//获取截图的blob数据
this.$refs.cropper.getCropBlob(async (data) => {
let formData = new FormData();
formData.append('file',data,"DX.jpg")
//调用axios上传
let {data: res} = await _this.$http.post('/api/file/imgUpload', formData)
if(res.code === 200){
_this.$message({
message: res.msg,
type: "success"
});
let data = res.data.replace('[','').replace(']','').split(',');
let imgInfo = {
name : _this.Name,
url : data[0]
};
_this.$emit('uploadImgSuccess',imgInfo);
}else {
_this.$message({
message: '文件服务异常,请联系管理员!',
type: "error"
});
}
})
}
},
},
}
</script>
<style scoped>
.cropper-content{
display: flex;
display: -webkit-flex;
justify-content: flex-end;
}
.cropper-box{
flex: 1;
width: 100%;
}
.cropper{
width: auto;
height: 300px;
}
.show-preview{
flex: 1;
-webkit-flex: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
}
.preview{
overflow: hidden;
border:1px solid #67c23a;
background: #cccccc;
}
.footer-btn{
margin-top: 30px;
display: flex;
display: -webkit-flex;
justify-content: flex-end;
}
.upload-btn{
flex: 1;
-webkit-flex: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
}
.scope-btn{
display: flex;
display: -webkit-flex;
justify-content: space-between;
padding-right: 10px;
}
.btn {
outline: none;
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
-webkit-appearance: none;
text-align: center;
-webkit-box-sizing: border-box;
box-sizing: border-box;
outline: 0;
-webkit-transition: .1s;
transition: .1s;
font-weight: 500;
padding: 8px 15px;
font-size: 12px;
border-radius: 3px;
color: #fff;
background-color: #409EFF;
border-color: #409EFF;
margin-right: 10px;
}
</style>
新建upload-cropper
<template>
<div class="cropper-app">
<el-form :model="formValidate" :rules="ruleValidate" ref="formValidate" label-width="100px" class="demo-ruleForm">
<el-form-item label="封面上传" prop="mainImage">
<div class="list-img-box">
<div v-if="formValidate.mainImage !== ''">
<img :src="formValidate.mainImage" style='width:300px;height:150px' alt="自定义封面">
</div>
<div v-else class="upload-btn" style="height: 120px;" @click="uploadPicture('flagImg')">
<i class="el-icon-plus" style="font-size: 30px;"></i>
<span>封面设置</span>
</div>
</div>
<input type="hidden" v-model="formValidate.mainImage" placeholder="请添加封面">
</el-form-item>
</el-form>
<!-- 剪裁组件弹窗 -->
<el-dialog
title="裁切封面"
:visible.sync="cropperModel"
width="950px"
center
>
<upload-cropper
:Name="cropperName"
@uploadImgSuccess = "handleUploadSuccess"
ref="child">
</upload-cropper>
</el-dialog>
<!--查看大封面-->
<el-dialog
title="查看大封面"
:visible.sync="imgVisible"
center>
<img :src="imgName" v-if="imgVisible" style="width: 100%" alt="查看">
</el-dialog>
</div>
</template>
<script>
import uploadCropper from "@/components/upload-cropper";
export default {
name: "Tailoring",
components: {uploadCropper},
data () {
return {
formValidate: {
mainImage: '',
},
ruleValidate: {
mainImage: [
{required: true, message: '请上传封面', trigger: 'blur'}
],
},
//裁切图片参数
cropperModel:false,
cropperName:'',
imgName: '',
imgVisible: false
}
},
methods: {
middleAdFinish(){
},
//封面设置
uploadPicture(name){
this.cropperName = name;
this.cropperModel = true;
},
//图片上传成功后
handleUploadSuccess (data){
console.log(data)
switch(data.name){
case 'flagImg':
this.formValidate.mainImage = 'http://ydfblog.cn/dfs/'+data.url;
console.log('最终输出'+data.name)
break;
}
this.cropperModel = false;
}
}
}
</script>
<style scoped>
.upload-list-cover{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0 40px;
align-items: center;
background: rgba(0,0,0,.6);
opacity: 0;
transition: opacity 1s;
}
.cover_icon {
font-size: 30px;
}
.upload-btn{
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border: 1px solid #cccccc;
border-radius: 5px;
overflow: hidden;
box-shadow: 0 0 1px #cccccc;
}
.upload-btn:hover {
border: 1px solid #69b7ed;
}
.upload-btn i{
margin: 5px;
}
</style>
实例2
test.vue:
<template>
<div style="display:flex;">
<div class="info-item" style="flex:1;">
<div style="width:120px;height:120px;border-radius:50%;overflow:hidden;margin-left:123px;border:1px solid #ddd">
<img style="width:120px;height:120px;" :src="headImg" alt="头像">
</div>
</div>
<div class="info-item" style="flex:1;margin-left:-160px;margin-top:30px;">
<label class="btn btn-orange" for="uploads" style="display:inline-block;width: 70px;padding: 0;text-align: center;line-height: 28px;">选择图片</label>
<input type="file" id="uploads" :value="imgFile" style="position:absolute; clip:rect(0 0 0 0);" accept="image/png, image/jpeg, image/gif, image/jpg" @change="uploadImg($event, 1)">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="+" title="放大" @click="changeScale(1)">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="-" title="缩小" @click="changeScale(-1)">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="↺" title="左旋转" @click="rotateLeft">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="↻" title="右旋转" @click="rotateRight">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="↓" title="下载" @click="down('blob')">
<input type="button" class="btn btn-blue" value="上传头像" @click="finish('blob')">
<div class="line" style="margin-left: -280px;margin-top: 85px;">
<div class="cropper-content" style="margin-top:-60px;margin-left:260px;">
<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"
@imgLoad="imgLoad"
></vueCropper>
</div>
<div style="margin-left:20px;">
<div class="show-preview" :style="{'width': '150px', 'height':'155px', 'overflow': 'hidden', 'margin': '5px'}">
<div :style="previews.div" class="preview">
<img :src="previews.url" :style="previews.img">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import VueCropper from 'vue-cropper'
import Api from '@/js/api.js' //接口url配置文件
export default {
data() {
return {
headImg:'',
//剪切图片上传
crap: false,
previews: {},
option: {
img: '',
outputSize:1, //剪切后的图片质量(0.1-1)
full: false,//输出原图比例截图 props名full
outputType: 'png',
canMove: true,
original: false,
canMoveBox: true,
autoCrop: true,
autoCropWidth: 150,
autoCropHeight: 150,
fixedBox: true
},
fileName:'', //本机文件地址
downImg: '#',
imgFile:'',
uploadImgRelaPath:'', //上传后的图片的地址(不带服务器域名)
}
},
components: {
VueCropper
},
methods: {
//放大/缩小
changeScale(num) {
console.log('changeScale')
num = num || 1;
this.$refs.cropper.changeScale(num);
},
//坐旋转
rotateLeft() {
console.log('rotateLeft')
this.$refs.cropper.rotateLeft();
},
//右旋转
rotateRight() {
console.log('rotateRight')
this.$refs.cropper.rotateRight();
},
//上传图片(点击上传按钮)
finish(type) {
console.log('finish')
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);
this.$http.post(Api.uploadSysHeadImg.url, formData, {contentType: false, processData: false, headers:{'Content-Type': 'application/x-www-form-urlencoded'}})
.then((response)=>{
var res = response.data;
if(res.success == 1){
$('#btn1').val('');
_this.imgFile = '';
_this.headImg = res.realPathList[0]; //完整路径
_this.uploadImgRelaPath = res.relaPathList[0]; //非完整路径
_this.$message({ //element-ui的消息Message消息提示组件
type: 'success',
message: '上传成功'
});
}
})
})
} else {
this.$refs.cropper.getCropData((data) => {
this.model = true;
this.modelSrc = data;
})
}
},
// 实时预览函数
realTime(data) {
console.log('realTime')
this.previews = data
},
//下载图片
down(type) {
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) {
console.log('uploadImg');
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)) {
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
}
if (num === 1) {
_this.option.img = data
} else if (num === 2) {
_this.example2.img = data
}
}
// 转化为base64
// reader.readAsDataURL(file)
// 转化为blob
reader.readAsArrayBuffer(file);
},
imgLoad (msg) {
console.log('imgLoad')
console.log(msg)
}
},
}
</script>
<style lang="less">
.info {
width: 720px;
margin: 0 auto;
.oper-dv {
height:20px;
text-align:right;
margin-right:100px;
a {
font-weight: 500;
&:last-child {
margin-left: 30px;
}
}
}
.info-item {
margin-top: 15px;
label {
display: inline-block;
width: 100px;
text-align: right;
}
.sel-img-dv {
position: relative;
.sel-file {
position: absolute;
width: 90px;
height: 30px;
opacity: 0;
cursor: pointer;
z-index: 2;
}
.sel-btn {
position: absolute;
cursor: pointer;
z-index: 1;
}
}
}
}
.cropper-content{
display: flex;
display: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
.cropper{
width: 260px;
height: 260px;
}
.show-preview{
flex: 1;
-webkit-flex: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
.preview{
overflow: hidden;
border-radius: 50%;
border:1px solid #cccccc;
background: #cccccc;
margin-left: 40px;
}
}
}
.cropper-content .show-preview .preview {margin-left: 0;}
</style>
其中,js/api.js文件是配置的接口地址
1、打开页面效果
2、点击选择图片按钮,选择完本地图片后的效果
选择完图片后,就可以对图片进行放大,缩小以及旋转等,并且可以移动选中框,选择上传图片的任意部分
3、点击上传头像按钮,即可调用上传头像的接口,把头像上传到文件服务器;
4、此时,图片便已上传成功了,查看图片服务器指定的目录,即可查看到图片已经在服务器上了
实例3-完整版
1、安装
npm install vue-cropper --save
2、页面引入
import { VueCropper } from 'vue-cropper'
3、申明组件
components: {
VueCropper,
},
4、完整代码
<!-- 裁剪图片 -->
<template>
<div class="wrapper">
<div class="model" v-show="model" @click="model = false">
<div class="model-show">
<img :src="modelSrc" alt="">
</div>
</div>
<div class="content">
<div class="show-info">
<h2>自动生成截图框 固定比例 w : h => 4 : 3</h2>
<div class="test">
<vueCropper ref="cropper2"
:img="example2.img"
:outputSize="example2.size"
:outputType="example2.outputType"
:info="example2.info"
:canScale="example2.canScale"
:autoCrop="example2.autoCrop"
:autoCropWidth="example2.autoCropWidth"
:autoCropHeight="example2.autoCropHeight"
:fixed="example2.fixed"
:fixedNumber="example2.fixedNumber"
:enlarge="4"></vueCropper>
</div>
<label class="btn" for="upload2">上传</label>
<input type="file" id="upload2" style="position:absolute; clip:rect(0 0 0 0);"
accept="image/png, image/jpeg, image/gif, image/jpg" @change="uploadImg($event,2)">
<button @click="finish2()" class="btn">裁剪</button>
</div>
</div>
</div>
</template>
<script>
import { VueCropper } from 'vue-cropper'
// import * as OSS from 'ali-oss';
export default {
components: {
VueCropper,
},
data() {
return {
model: false,
modelSrc: '',
crap: false,
previews: {},
form: {
head: ''
},
example2: {
//img的路径自行修改
img: '$oss.url + \'/\' + form.head ',
info: true,
size: 1,
outputType: 'jpeg',
canScale: true,
autoCrop: true,
// 只有自动截图开启 宽度高度才生效
autoCropWidth: 300,
autoCropHeight: 250,
fixed: true,
// 真实的输出宽高
infoTrue: true,
fixedNumber: [4, 3]
},
downImg: '#'
}
},
methods: {
//点击裁剪,这一步是可以拿到处理后的地址
finish2() {
this.$refs.cropper2.getCropData((data) => {
this.modelSrc = data
this.model = false;
//裁剪后的图片显示
this.example2.img = this.modelSrc;
// this.toBlob(data)
// console.log(data)
// console.log(this.toBlob(data))
//将图片上传服务器中
})
},
uploadImg(e, num) {
//上传图片
this.example2.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
data = e.target.result
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
} else if (num === 2) {
this.example2.img = data
}
}
// 转化为base64
// reader.readAsDataURL(file)
// 转化为blobcs
reader.readAsArrayBuffer(file)
},
// base64转blob
toBlob(ndata) {
//ndata为base64格式地址
console.log(ndata)
let arr = ndata.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {
type: mime
})
}
},
}
</script>
<style>
* {
margin: 0;
padding: 0;
}
.content {
margin: auto;
max-width: 585px;
margin-bottom: 100px;
}
.test-button {
display: flex;
flex-wrap: wrap;
}
.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 .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: 50px;
}
.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: 285px;
}
.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;
padding: 10px 0;
user-select: none;
}
@keyframes slide {
0% {
background-position: 0 0;
}
100% {
background-position: -100% 0;
}
}
@media screen and (max-width: 1000px) {
.content {
max-width: 90%;
margin: auto;
}
.test {
height: 400px;
}
}
</style>
实例4
1、安装
npm install vue-cropper
2、使用
1.main.js文件引入
import VueCropper from 'vue-cropper'
Vue.use(VueCropper)
2.封装
<template>
<div>
<el-dialog
title="图片剪裁"
:visible.sync="dialogVisiblex"
:close-on-press-escape="false"
:close-on-click-modal="false"
append-to-body
width="1000px"
>
<div class="cropper-content">
<div class="cropper" style="text-align:center">
<vueCropper
ref="cropper"
:img="option.img"
:outputSize="option.outputSize"
:outputType="option.outputType"
:info="option.info"
:canScale="option.canScale"
:autoCrop="option.autoCrop"
:autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight"
:fixedBox="option.fixedBox"
:fixed="option.fixed"
:fixedNumber="option.fixedNumber"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:centerBox="option.centerBox"
:infoTrue="option.infoTrue"
:full="option.full"
:enlarge="option.enlarge"
:mode="option.mode"
>
</vueCropper>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisiblex = false">取消</el-button>
<el-button type="primary" @click="finish" :loading="loading"
>确认</el-button
>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
components: {},
props: {},
data() {
return {
dialogVisiblex: false,
loading: false,
option: {
img: '', // 裁剪图片的地址 url 地址, base64, blob
outputSize: 1, // 裁剪生成图片的质量
outputType: 'jpeg', // 裁剪生成图片的格式 jpeg, png, webp
info: true, // 裁剪框的大小信息
canScale: false, // 图片是否允许滚轮缩放
autoCrop: true, // 是否默认生成截图框
autoCropWidth: 345, // 默认生成截图框宽度
autoCropHeight: 245, // 默认生成截图框高度
fixedBox: false, // 固定截图框大小 不允许改变
fixed: true, // 是否开启截图框宽高固定比例
fixedNumber: [1, 1], // 截图框的宽高比例 [ 宽度 , 高度 ]
canMove: true, // 上传图片是否可以移动
canMoveBox: true, // 截图框能否拖动
original: false, // 上传图片按照原始比例渲染
centerBox: true, // 截图框是否被限制在图片里面
infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
full: true, // 是否输出原图比例的截图
enlarge: '1', // 图片根据截图框输出比例倍数
mode: 'contain' // 图片默认渲染方式 contain , cover, 100px, 100% auto
},
unimgurl: '',
success: () => {} // 回调方法
}
},
computed: {},
watch: {},
created() {
},
mounted() {},
activated() {},
methods: {
showModal(obj) {
if (obj.img) {
this.option.img = obj.img
}
//裁剪生成图片的质量
if (obj.outputSize) {
this.option.outputSize = obj.outputSize
} else {
this.option.outputSize = 1
}
//裁剪生成图片的格式
if (obj.outputType) {
this.option.outputType = obj.outputType
} else {
this.option.outputType = 'jpeg'
}
//裁剪框的大小信息
if (obj.info) {
this.option.info = obj.info
} else {
this.option.info = true
}
//图片是否允许滚轮缩放
if (obj.canScale) {
this.option.canScale = obj.canScale
} else {
this.option.canScale = false
}
//是否默认生成截图框
if (obj.autoCrop) {
this.option.autoCrop = obj.autoCrop
} else {
this.option.autoCrop = true
}
//默认生成截图框宽度
if (obj.autoCropWidth) {
this.option.autoCropWidth = obj.autoCropWidth
} else {
this.option.autoCropWidth = 375
}
//默认生成截图框高度
if (obj.autoCropHeight) {
this.option.autoCropHeight = obj.autoCropHeight
} else {
this.option.autoCropHeight = 245
}
//固定截图框大小 不允许改变
if (obj.fixedBox) {
this.option.fixedBox = obj.fixedBox
} else {
this.option.fixedBox = false
}
//是否开启截图框宽高固定比例
if (obj.fixed) {
this.option.fixed = obj.fixed
} else {
this.option.fixed = true
}
//截图框的宽高比例
if (obj.fixedNumber) {
this.option.fixedNumber = obj.fixedNumber
} else {
this.option.fixedNumber = [this.option.autoCropWidth, this.option.autoCropHeight]
}
//上传图片是否可以移动
if (obj.canMove) {
this.option.canMove = obj.canMove
} else {
this.option.canMove = true
}
//截图框能否拖动
if (obj.canMoveBox) {
this.option.canMoveBox = obj.canMoveBox
} else {
this.option.canMoveBox = true
}
//上传图片按照原始比例渲染
if (obj.original) {
this.option.original = obj.original
} else {
this.option.original = false
}
//截图框是否被限制在图片里面
if (obj.centerBox) {
this.option.centerBox = obj.centerBox
} else {
this.option.centerBox = true
}
//true 为展示真实输出图片宽高 false 展示看到的截图框宽高
if (obj.infoTrue) {
this.option.infoTrue = obj.infoTrue
} else {
this.option.infoTrue = true
}
//是否输出原图比例的截图
if (obj.full) {
this.option.full = obj.full
} else {
this.option.full = true
}
//图片根据截图框输出比例倍数
if (obj.enlarge) {
this.option.enlarge = obj.enlarge
} else {
this.option.enlarge = '1'
}
//图片默认渲染方式
if (obj.mode) {
this.option.mode = obj.mode
} else {
this.option.mode = 'contain'
}
if (obj.success) {
this.success = obj.success
} else {
this.success = () => {}
}
this.dialogVisiblex = true
},
finish() {
// 获取截图的数据
let that = this
this.$refs.cropper.getCropBlob(data => {
that.unimgurl = data
that.confirm()
})
},
confirm() {
this.success({
img: this.unimgurl
})
this.dialogVisiblex = false
},
cancel() {
this.dialogVisiblex = false
}
}
}
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.real_info_class {
.el-checkbox__input .el-checkbox__inner {
border-radius: 0;
}
}
.file-image {
width: 320px;
height: 320px;
font-size: 14px;
border: 1px solid #cccccc;
margin: 15px 0;
}
/* 截图 */
/* .cropper-content {} */
.cropper {
width: 960px;
height: 606px;
}
</style>
3.组件调用
<x-cropper ref="iscropper"></x-cropper>
this.$refs.iscropper.showModal({
img: img, // 裁剪图片的地址
outputSize: 0.8, // 裁剪生成图片的质量
outputType: 'jpeg', // 裁剪生成图片的格式
info: true, // 裁剪框的大小信息
canScale: false, // 图片是否允许滚轮缩放
autoCrop: true, // 是否默认生成截图框
autoCropWidth: 375, // 默认生成截图框宽度
autoCropHeight: 245, // 默认生成截图框高度
fixedNumber: [1, 1], // 截图框的宽高比例
fixedBox: false, // 固定截图框大小 不允许改变
fixed: false, // 是否开启截图框宽高固定比例
canMove: true, // 上传图片是否可以移动
canMoveBox: true, // 截图框能否拖动
original: false, // 上传图片按照原始比例渲染
centerBox: true, // 截图框是否被限制在图片里面
infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
full: true, // 是否输出原图比例的截图
enlarge: '1', // 图片根据截图框输出比例倍数
mode: 'contain', // 图片默认渲染方式
success: res => {
this.unimgurl = res.img
this.imageUrl = URL.createObjectURL(res.img)
}
})
省略
this.$refs.iscropper.showModal({
img: img, // 裁剪图片的地址
autoCropWidth: 375, // 默认生成截图框宽度
autoCropHeight: 245, // 默认生成截图框高度
success: res => {
this.unimgurl = res.img
this.imageUrl = URL.createObjectURL(res.img)
}
})