<template>
|
<div class="upload">
|
<div class="IDcardbgDiv">
|
<x-img class="imgcontent" :default-src="defaultImg" :src="currentImg" alt=""></x-img>
|
</div>
|
<x-button class="IDCardUpLoadBut" v-text="butName"></x-button>
|
<input class="fileUploadInput" type="file" @change="handle($event)" capture="camera" accept="image/*">
|
</div>
|
</template>
|
<script>
|
import EXIF from 'exif-js';
|
import {XImg, XButton} from 'vux';
|
|
export default {
|
data () {
|
return {
|
imgSrc: ''
|
};
|
},
|
props: [
|
'butName',
|
'defaultImg',
|
'currentImg'
|
],
|
components: {
|
XImg, XButton
|
},
|
methods: {
|
handle (evt) { // 图片变化后的回调函数
|
const files = Array.prototype.slice.call(evt.target.files);
|
let that = this;
|
files.forEach(function (file, i) {
|
var orientation;
|
if (!/\/(?:jpeg|png|gif)/i.test(file.type)) return;
|
// 读取图片的元信息
|
EXIF.getData(file, function () {
|
orientation = EXIF.getTag(this, 'Orientation');
|
});
|
|
let reader = new FileReader();
|
reader.onload = function () {
|
let result = this.result;
|
// 使用exif
|
that.getImgData(this.result, orientation, function (data) {
|
// 这里可以使用校正后的图片data了
|
var img = new Image();
|
img.src = data;
|
// 图片加载完毕之后进行压缩,然后上传
|
if (img.complete) {
|
callback();
|
} else {
|
img.onload = callback;
|
}
|
function callback() {
|
|
var data = that.compress(img);
|
// that.imgSrc = data;
|
that.upload(data, file.type, file.name);
|
// 发送后台请求
|
}
|
});
|
};
|
reader.readAsDataURL(file);
|
});
|
},
|
// 压缩图片
|
compress (img) {
|
// 用于压缩图片的canvas
|
let canvas = document.createElement('canvas');
|
let ctx = canvas.getContext('2d');
|
|
// 瓦片canvas
|
var tCanvas = document.createElement('canvas');
|
var tctx = tCanvas.getContext('2d');
|
|
let width = img.width;
|
let height = img.height;
|
|
// 如果图片大于四百万像素,计算压缩比并将大小压至400万以下
|
var ratio;
|
if ((ratio = width * height / 4000000) > 1) {
|
ratio = Math.sqrt(ratio);
|
width /= ratio;
|
height /= ratio;
|
} else {
|
ratio = 1;
|
}
|
canvas.width = width * 2;
|
canvas.height = height * 2;
|
// 铺底色
|
ctx.fillStyle = '#fff';
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
// 如果图片像素大于100万则使用瓦片绘制
|
var count;
|
if ((count = width * height / 1000000) > 1) {
|
count = ~~(Math.sqrt(count) + 1); // 计算要分成多少块瓦片
|
// 计算每块瓦片的宽和高
|
var nw = ~~(width / count);
|
var nh = ~~(height / count);
|
tCanvas.width = nw;
|
tCanvas.height = nh;
|
for (var i = 0; i < count; i++) {
|
for (var j = 0; j < count; j++) {
|
tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio * 2, nh * ratio * 2, 0, 0, nw, nh);
|
ctx.drawImage(tCanvas, i * nw, j * nh, nw * 2, nh * 2);
|
}
|
}
|
} else {
|
ctx.drawImage(img, 0, 0, width * 2, height * 2);
|
}
|
|
|
// 进行最小压缩
|
let ndata = canvas.toDataURL('image/jpeg', 0.8);
|
return ndata;
|
},
|
// 上传图片
|
upload (basestr, type, name) {
|
let text = window.atob(basestr.split(',')[1]);
|
let buffer = new ArrayBuffer(text.length);
|
let ubuffer = new Uint8Array(buffer);
|
|
for (let i = 0; i < text.length; i++) {
|
ubuffer[i] = text.charCodeAt(i);
|
}
|
|
let Builder = window.WebKitBlobBuilder || window.MozBlobBuilder;
|
let blob;
|
|
if (Builder) {
|
let builder = new Builder();
|
builder.append(buffer);
|
blob = builder.getBlob(type);
|
} else {
|
blob = new window.Blob([buffer], {type: type});
|
}
|
|
var post = {
|
'file': basestr,
|
'extName': 'jpeg'
|
};
|
// 选择完毕触发事件
|
this.$emit('select-complete', post);
|
},
|
// 图片旋转处理
|
getImgData: function (img, dir, next) {
|
// @param {string} img 图片的base64
|
// @param {int} dir exif获取的方向信息
|
// @param {function} next 回调方法,返回校正方向后的base64
|
var image = new Image();
|
let canvas = document.createElement('canvas');
|
let ctx = canvas.getContext('2d');
|
image.onload = function () {
|
let resultWidth = 0;
|
let resultHeight = 0;
|
let maxWidthOrHeight = 1024;
|
let drawWidth = this.naturalWidth;
|
let drawHeight = this.naturalHeight;
|
|
// 以下改变图片大小,控制最大宽度为1024
|
var maxSide = Math.max(drawWidth, drawHeight);
|
if (maxSide > maxWidthOrHeight) {
|
let minSide = Math.min(drawWidth, drawHeight);
|
minSide = minSide / maxSide * maxWidthOrHeight;
|
maxSide = maxWidthOrHeight;
|
if (drawWidth > drawHeight) {
|
resultWidth = maxSide;
|
resultHeight = minSide;
|
} else {
|
resultWidth = minSide;
|
resultHeight = maxSide;
|
}
|
}
|
|
if (dir === 3) {
|
canvas.width = resultWidth;
|
canvas.height = resultHeight;
|
ctx.translate(resultWidth, resultHeight);
|
ctx.rotate(Math.PI);
|
} else if (dir === 6) {
|
canvas.width = resultHeight;
|
canvas.height = resultWidth;
|
ctx.translate(resultHeight, 0);
|
ctx.rotate(Math.PI / 2);
|
} else if (dir === 8) {
|
canvas.width = resultHeight;
|
canvas.height = resultWidth;
|
ctx.translate(0, resultWidth);
|
ctx.rotate(-Math.PI / 2);
|
} else {
|
canvas.width = resultWidth;
|
canvas.height = resultHeight;
|
}
|
ctx.drawImage(this, 0, 0, resultWidth, resultHeight)
|
// 返回校正图片
|
next(canvas.toDataURL('image/jpeg', 0.8));
|
}
|
image.src = img;
|
}
|
}
|
};
|
</script>
|
<style lang="less">
|
@import "../../style/mixin";
|
.IDcardbgDiv {
|
background-image: url('../../assets/img/IDcardbg.png');
|
background-size: 130px 80px;
|
}
|
|
.imgcontent {
|
width: auto;
|
height: 70px;
|
padding-top: 5px;
|
}
|
|
.fileUploadInput {
|
opacity: 0;
|
z-index: 99;
|
position: absolute;
|
top: 0;
|
left: 0;
|
width: 100%;
|
height: 100%;
|
}
|
|
.IDCardUpLoadBut {
|
margin-top: 20px;
|
width: 80%;
|
height: 30px;
|
color: @color-white;
|
border-radius: 15px;
|
border: none;
|
font-size: @font-size-small;
|
.color-linear-gradient(@color-primary-light, @color-primary, 90deg);
|
}
|
|
.upload {
|
position: relative;
|
width: 130px;
|
margin: 0 auto;
|
text-align: center;
|
}
|
</style>
|