最近项目有一个需求,需要上传图片,但是客户上传的图片大小不一,所以我们需要规定客户的图片比例,但又需要是客户所需的,所以就想到了截图
实现效果
我们的架构是vue,所以用的是一个vue的截图插件
安装插件:npm install vue-cropper --save-dev
引入组件
import Vue from 'vue';
import { VueCropper } from "vue-cropper";
Vue.use(VueCropper)
核心代码
<div>
<span class="spanStyle">产品图片:span>
<div style="display:flex;padding-left: 300px;">
<div class="info-item" style="flex:1;margin-left:-160px;margin-top: -25px">
<label class="btn btn-orange theme-bg-gray theme-white w90" 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)">
<div class="line" style="margin-left: -280px;margin-top: 85px;">
<div class="cropper-content" style="margin-top:-60px;margin-left:160px;">
<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 style="margin-left:700px;">
<div class="show-preview" :style="{'width': '300px', 'height':'150px', 'overflow': 'hidden', 'margin-left': '-650px'}">
<div :style="previews.div" >
<img :src="previews.url" :style="previews.img">
div>
div>
div>
div>
div>
div>
div>
div>
预览的方法
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: 300,
autoCropHeight: 150,
fixedBox: true
},
fileName:'', //本机文件地址
downImg: '#',
imgFile:'',
uploadImgRelaPath:'', //上传后的图片的地址(不带服务器域名)
}
},
methods:{
// 实时预览函数
realTime(data) {
console.log('realTime')
this.previews = data
},
//选择本地图片
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
}
}
// // 转化为blob
reader.readAsArrayBuffer(file);
}
}
然后我们要获取截取完之后的图片,是通过Cropper的回调函数来获取它的图片,这里我们获取的是我们转为blob格式的图片(不转显示不了)
这边是因为后台就是用file类型接收的,所以我需要再把blob转为file,然后才用formData上传文件
productAdd(){
this.$refs.cropper.getCropBlob((data) => {
//这个data就是我们截取后的blob图片
let formData = new FormData();
//获取文件名,因为在转成file里面不能用this.所以需要用一个变量来赋值
var name=this.fileName
var file = new File([data], name, {type: data.type, lastModified: Date.now()});
formData.append("files",file)
new Promise((resolve, reject) => {
productAdd(formData).then(response => {
if (response.code == 20000) {
Dialog.alert({
title: '提示',
message: '保存成功!'
}).then(() => {
this.back('/productInfo')
});
}
}).catch(error => {
reject(error)
})
})
})
}
实际运用到自己的项目中还需改动,比如编辑图片还需回显,上传多张剪切的图片等等…
end…