使用vue-cropper (https://github.com/xyxiao001/vue-cropper)移动端情况下裁剪的时候 会出现部分机型图片翻转以及拖动卡顿问题,直接改源码, 图片翻转问题可以解决在checkOrientationImage方法中注释掉h.rotate(90 * Math.PI / 180) 即可。卡拖动顿问题 在 moveImg 和startMove 方法中加上 t.stopImmediatePropagation() 本地调试二次打开的时候出现卡死现象,lssues中也未能解决,谷歌百度了一天也没找到方法。。
最后更换了插件:https://github.com/fengyuanchen/cropperjs
中文文档说明 :cropperjs实践及中文文档(自译) - 灭灭 - 博客园
中间也踩了坑,但是都解决啦
业务中需要上传裁剪后的图片识别身份证上的信息,这里必须这样写,不然得到的64格式图片会模糊不清导致识别不了。
_this.url = _this.cropper.getCroppedCanvas({
imageSmoothingQuality: 'high'
}).toDataURL('image/jpeg')
mounted中先实例化裁剪框:
var self = this;
var image = document.getElementById("image");
self.cropper = new Cropper(image, {
aspectRatio: 304/190,
viewMode: 1,
dragMode :"move",
zoomable: false,
ready: function () {
self.croppable = true;
},
});
直接上代码
<template>
<div id="scan_idcard">
<van-nav-bar title="扫描身份证" left-arrow @click-left="onClickLeft"></van-nav-bar>
<div class="container">
<div style="padding: 0 12px">
<label for="uploads" class="base_content">
<van-uploader v-model="frontImg1" :after-read="uploadFront" deletable @delete="delImg('frontImg1')" :max-count="1">
<van-button>
<img v-show="frontImg1.length == 0" src="_pic_03.png">
</van-button>
</van-uploader>
<!-- <img v-tap="[uploadImg,'frontImg1']" v-show="!frontImg1" src="pic_03.png">
<img v-tap="[uploadImg,'frontImg1']" v-show="frontImg1" :src="frontImg1"> -->
</label>
<label for="upload" class="base_content">
<van-uploader v-model="frontImg2" :after-read="uploadBack" deletable @delete="delImg('frontImg2')" :max-count="1">
<van-button>
<img v-show="frontImg2.length == 0" src="e/yancheng_pic_04.png">
</van-button>
</van-uploader>
<!-- <img v-tap="[uploadImg,'frontImg2']" v-show="!frontImg2" src="ancheng_pic_04.png">
<img v-tap="[uploadImg,'frontImg2']" v-show="frontImg2" :src="frontImg2"> -->
</label>
<div class="btn" v-tap="[submit]">提交</div>
</div>
<div class="dialog"
v-show="showCropperDialog"
>
<div>
<img style="max-width: 100%;" id= "image" :src="url" alt="Picture" >
</div>
<div class="upload-btn">
<!-- <van-button type="default" @click="changeScale(-1)">缩小</van-button>
<van-button type="info" @click="changeScale(1)">放大</van-button> -->
<van-button class="btn1" type="default" @click="cancleUpload">取消</van-button>
<van-button class="btn2" type="info" @click="uploadCropImg">确认</van-button>
</div>
</div>
</div>
</div>
</template>
<script>
import Util from "../../assets/js/util";
import wx from 'weixin-js-sdk';
import Cropper from "cropperjs";
import "cropperjs/dist/cropper.css";
export default {
inject: ['reload'],
data() {
return {
frontImg1:[], //身份证正面照
frontImg2:[], //身份证反面照
//剪切图片上传
crap: false,
previews: {},
imgFile:"",
fileName:'', // 本机文件地址
showCropperDialog:false,
user_name:"", //姓名
user_nation:"", //民族
user_idcard_no:"", //身份证号
user_sex:"", //性别
user_birthday:"", //生日
user_idcard_address:"" , //身份证地址
headerImage: "",
picValue: "",
cropper: "",
croppable: false,
panel: false,
url: "",
};
},
mounted() {
this.imgOnload()
var self = this;
var image = document.getElementById("image");
self.cropper = new Cropper(image, {
aspectRatio: 304/190,
viewMode: 1,
dragMode :"move",
zoomable: false,
ready: function () {
self.croppable = true;
},
});
},
created() {
},
methods: {
getObjectURL(file) {
var url = null;
if (window.createObjectURL != undefined) {
// basic
url = window.createObjectURL(file);
} else if (window.URL != undefined) {
// mozilla(firefox)
url = window.URL.createObjectURL(file);
} else if (window.webkitURL != undefined) {
// webkit or chrome
url = window.webkitURL.createObjectURL(file);
}
return url;
},
onClickLeft(){
this.$router.go(-1);
window.localStorage.removeItem('imageinfo1')
window.localStorage.removeItem('imageinfo2')
},
// 提交
submit(){
let _this = this;
let data = {
frontImg1 : _this.frontImg1[0].url,
frontImg2 : _this.frontImg2[0].url,
user_name : _this.user_name,
user_nation : _this.user_nation,
user_idcard_no : _this.user_idcard_no,
user_sex : _this.user_sex,
user_birthday : _this.user_birthday,
user_idcard_address : _this.user_idcard_address,
};
console.log('555',data);
Util.$emit("idCardInfo", data);
_this.$router.go(-1);
window.localStorage.removeItem('imageinfo1')
window.localStorage.removeItem('imageinfo2')
},
// 放大/缩小
changeScale(num) {
num = num || 1;
this.$refs.cropper.changeScale(num);
},
cancleUpload(){ //取消裁剪
let that = this
that.url = ""
that.showCropperDialog = false
},
imgOnload(){
let _this = this
let res1 = JSON.parse(window.localStorage.getItem("imageinfo1"))
let res2 = JSON.parse(window.localStorage.getItem("imageinfo2"))
if(res1){
if(res1.info == "success"){
let img = {
url:res1.data.dir
}
_this.frontImg1.push(img); //身份证正面照
_this.user_name = res1.data.idcard.name; 姓名
_this.user_nation = res1.data.idcard.nation; 民族
_this.user_idcard_no = res1.data.idcard.id; //身份证号
_this.user_sex = res1.data.idcard.sex; //性别
_this.user_birthday = res1.data.idcard.birth; //生日
_this.user_idcard_address = res1.data.idcard.address; //身份证地址
}}
if(res2){
if (res2.info == "success"){
let img = {
url:res2.data.dir
}
_this.frontImg2.push(img); //身份证正面照
}}
},
getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
var ext = img.src.substring(img.src.lastIndexOf(".")+1).toLowerCase();
var dataURL = canvas.toDataURL("image/"+ext);
return dataURL;
} ,
// 上传剪切后图片
uploadCropImg () {
let _this = this;
if(this.upload_type === 'frontImg1') {
// 隐藏裁剪图片弹窗
_this.url = _this.cropper.getCroppedCanvas({
imageSmoothingQuality: 'high'
}).toDataURL('image/jpeg')
_this.showCropperDialog = false;
_this.Toast.loading({
duration: 0, // 持续展示 toast
forbidClick: true,
message: '上传中...',
});
_this.$ajax()
.post("/wechat/auth/base64Upload",{
card_type: 0,
file:_this.url,
})
.then(function(response){
let res = response.data;
console.log('res',res);
_this.Toast.clear();
if(res.status == 1){
let img = {
url:res.data.dir
}
_this.url = ""
_this.frontImg1.push(img); //身份证正面照
if(!res.data.idcard.name){
_this.Toast("识别失败,请重新扫描!")
return false
}
_this.user_name = res.data.idcard.name; 姓名
if(!res.data.idcard.name){
_this.Toast("识别失败,请重新扫描!")
return false
}
_this.user_nation = res.data.idcard.nation; 民族
if(!res.data.idcard.nation){
_this.Toast("识别失败,请重新扫描!")
return false
}
_this.user_idcard_no = res.data.idcard.id; //身份证号
if(!res.data.idcard.id){
_this.Toast("识别失败,请重新扫描")
return false
}
_this.user_sex = res.data.idcard.sex; //性别
if(!res.data.idcard.sex){
_this.Toast("识别失败,请重新扫描!")
return false
}
_this.user_birthday = res.data.idcard.birth; //生日
if(!res.data.idcard.birth){
_this.Toast("识别失败,请重新扫描!")
return false
}
_this.user_idcard_address = res.data.idcard.address; //身份证地址
if(!res.data.idcard.address){
_this.Toast("识别失败,请重新扫描!")
return false
}
window.localStorage.setItem("imageinfo1",JSON.stringify(res))
}else{
_this.url = ""
_this.Toast(res.info)
}
})
// })
}else if(this.upload_type === 'frontImg2') {
// 隐藏裁剪图片弹窗
_this.url = _this.cropper.getCroppedCanvas({
imageSmoothingQuality: 'high'
}).toDataURL('image/jpeg')
_this.showCropperDialog = false;
_this.Toast.loading({
duration: 0, // 持续展示 toast
forbidClick: true,
message: '上传中...',
});
_this
.$ajax()
.post("/wechat/auth/base64Upload",{
card_type: 1,
file:_this.url,
})
.then(function(response){
let res = response.data;
_this.Toast.clear();
if(res.status == 1){
let img = {
url:res.data.dir
}
_this.frontImg2.push(img); //身份证反面照
window.localStorage.setItem("imageinfo2",JSON.stringify(res))
_this.url = ""
}else{
_this.url = ""
_this.Toast(res.info)
}
})
}
},
uploadFront(file){ //上传身份证正面照片
let _this = this;
_this.url = file.content;
_this.frontImg1 = [];
_this.upload_type = 'frontImg1'; //当前上传的是身份证正面还是反面
_this.showCropperDialog = true; //显示裁剪框
//每次替换图片要重新得到新的url
// if (_this.cropper) {
_this.cropper.replace(_this.url);
// }
},
uploadBack(file){ //上传身份证反面照片
let _this = this;
_this.url = file.content;
_this.frontImg2 = [];
_this.upload_type = 'frontImg2'; //当前上传的是身份证正面还是反面
_this.showCropperDialog = true; //显示裁剪框
//每次替换图片要重新得到新的url
_this.cropper.replace(_this.url);
},
delImg(item){ //删除图片
this[item] = [];
window.localStorage.removeItem('imageinfo1')
window.localStorage.removeItem('imageinfo2')
},
},
components: {
},
};
</script>
<style lang="less" type="text/less">
.dialog{
z-index: 99;
position: fixed;
padding-top: 60px;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 1);
}
.btn1{
margin-left: 6%;
margin-top: 10px;
}
.btn2{
margin-left: 52%;
}
#scan_idcard {
background-color:#FFFFFF;
overflow: scroll;
.van-uploader{
.van-button--default{
padding: 0;
border: none;
height: 100%;
}
}
.van-uploader,.van-uploader__wrapper{
width: 100%;
}
.van-uploader__preview{
width: 100%;
margin: 0;
}
.van-uploader__preview-image{
width: 100%;
height: auto;
}
.van-dialog{
display: flex;
align-items: center;
top:0;
left: 0;
width: 100%;
bottom: 0;
transform: none;
background-color: inherit;
.van-dialog__content{
width: 100%;
height: 400px;
.cropper-view-box{
outline: 1px solid #FFFFFF;
}
.crop-info{
display: none;
}
}
.upload-btn{
display: flex;
padding: 30px 30px 0;
justify-content: space-between;
}
}
.base_content{
img{
display: block;
width: 100%;
height: 221px;
overflow: hidden;
margin-bottom: 10px;
}
}
.btn{
margin-top:30px;
border-radius: 20px;
}
}
</style>