app_tree_planting/components/imageCompress/imageCompress.vue
itgaojian163 aae2813dd8 初始化
2023-01-11 19:31:59 +08:00

332 lines
9.6 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template xlang="wxml" minapp="mpvue">
<view class="_imageCompress">
<canvas id="_myCanvas" canvas-id="_myCanvas" :style="{width:cWidth+'px',height:cHeight+'px'}" />
</view>
</template>
<script>
let _rtArr = [], _cgFile = '', _index = 0;
export default {
name: "imageCompress",
props: {
maxWidth: {
type: Number,
default: 750
},
type: {
type: String,
default: 'url'
},
ql: {
type: Number,
default: 0.92
},
src: {
type: String,
default: ''
},
number: {
type: Number,
default: 1
},
fixOrientation: {
type: Boolean,
default: true
},
size: {
type: Number,
default: 500000
},
},
data() {
return {
cWidth: 750,
cHeight: 750,
}
},
onUnload: function () {
},
methods: {
// 选择照片
_changImg() {
let that = this;
if (that.src == '') {
uni.chooseImage({
count: that.number, //默认9
sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
// sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
success: function (res) {
_rtArr = [];
_cgFile = res.tempFilePaths;
_index = 0;
that._imageCompress()
},
fail: function (e) {
that._err(e)
// console.log(JSON.stringify(res.tempFilePaths));
}
});
} else {
_imageCompress(that.src)
}
},
// 压缩图片
_imageCompress() {
let that = this, resPath = _cgFile[_index];
// #ifdef APP-PLUS
uni.hideLoading();
// #endif
uni.showLoading({
title: `图片压缩中 ${_index + 1}/${_cgFile.length}`,
mask: true
});
// 获取图片信息
// #ifndef H5
uni.getImageInfo({
src: resPath,
success: function (image) {
// 如果图片的大小大于设定值才压缩
uni.getFileInfo({
filePath: resPath,
success: function (res) {
_imageCompress(image, res.size)
},
fail: function (e) {
that._err(e)
}
})
},
fail: function (e) {
that._err(e)
}
});
// #endif
// #ifdef H5
that._getH5ImageInfo(resPath, d => {
_imageCompress(d, d.size)
})
// #endif
// 处理图片
function _imageCompress(image, size) {
// #ifndef APP-PLUS
if (image.type.indexOf('png') >= 0) {
that._result(resPath)
return false
}
// #endif
let oW = image.width, oH = image.height, scaleWidth = 1, scaleHeight = 1, ctxWidth, ctxHeight;
if (size / 1024 >= that.size || image.width >= that.maxWidth) {
// 控制上传图片的宽高
if (image.width >= image.height && image.width >= that.maxWidth) {
image.height = that.maxWidth * image.height / image.width;
image.width = that.maxWidth;
} else if (image.width < image.height && image.height >= that.maxWidth) {
image.width = that.maxWidth * image.width / image.height;
image.height = that.maxWidth;
}
scaleWidth = image.width / oW
scaleHeight = image.height / oH
}
ctxWidth = oW * scaleWidth
ctxHeight = oH * scaleHeight
const ctx = uni.createCanvasContext('_myCanvas', that);
that.cWidth = image.width;
that.cHeight = image.height;
// 图片旋转修正只有H5有效
if (that.fixOrientation) {
// 旋转图片
let ot = image.orientation
if ([5, 6, 7, 8, 'right', 'left', 'right-mirrored', 'left-mirrored'].indexOf(ot) > -1) {
that.cWidth = image.height;
that.cHeight = image.width;
}
// 代码参考 https://stackoverflow.com/questions/19463126/how-to-draw-photo-with-correct-orientation-in-canvas-after-capture-photo-by-usin
if (ot == 2 || ot == "up-mirrored") {
ctx.translate(ctxWidth, 0);
ctx.scale(-1, 1);
} else if (ot == 3 || ot == "down") {
ctx.translate(ctxWidth, ctxHeight);
ctx.rotate(Math.PI);
} else if (ot == 4 || ot == "down-mirrored") {
ctx.translate(0, ctxHeight);
ctx.scale(1, -1);
} else if (ot == 5 || ot == "right-mirrored") {
ctx.rotate(0.5 * Math.PI);
ctx.scale(1, -1);
} else if (ot == 6 || ot == "right") {
ctx.rotate(0.5 * Math.PI);
ctx.translate(0, -ctxHeight);
} else if (ot == 7 || ot == "left-mirrored") {
ctx.rotate(0.5 * Math.PI);
ctx.translate(ctxWidth, -ctxHeight);
ctx.scale(-1, 1);
} else if (ot == 8 || ot == "left") {
ctx.rotate(-0.5 * Math.PI);
ctx.translate(-ctxWidth, 0);
} else {
ctx.translate(0, 0);
}
}
let ctxTime = 0;
// #ifndef H5
ctxTime = 10;
// #endif
// #ifdef H5
ctxTime = cTime();
// #endif
setTimeout(() => {
ctx.drawImage(resPath, 0, 0, ctxWidth, ctxHeight)
ctx.draw(false, () => {
let time = 0;
// #ifndef MP-WEIXIN
time = 10;
// #endif
// #ifdef MP-WEIXIN
time = cTime();
// #endif
setTimeout(() => {
uni.canvasToTempFilePath({
width: Number(that.cWidth),
height: Number(that.cHeight),
destWidth: Number(that.cWidth),
destHeight: Number(that.cHeight),
canvasId: '_myCanvas',
fileType: 'jpg',
quality: Number(that.ql),
success: function (res) {
if (that.type == 'base64') {
let img = '';
//#ifdef MP-WEIXIN
img = 'data:image/jpeg;base64,' + wx.getFileSystemManager().readFileSync(res.tempFilePath, "base64")
that._result(img)
//#endif
//#ifdef APP-PLUS
// console.log(JSON.stringify(res))
plus.io.resolveLocalFileSystemURL(res.tempFilePath, function (entry) {
entry.file(function (file) {
let fileReader = new plus.io.FileReader();
// console.log("getFile:" + JSON.stringify(file));
fileReader.readAsDataURL(file);
fileReader.onloadend = function (evt) {
// console.log(JSON.stringify(evt))
if (evt.target.readyState == 2) {
that._result(evt.target.result)
} else {
that._err(evt)
}
}
});
}, function (e) {
that._err(e)
});
//#endif
//#ifdef H5
that._result(res.tempFilePath)
//#endif
} else {
that._result(res.tempFilePath)
}
},
fail: function (e) {
that._err(e)
}
}, that)
}, time);
});
}, ctxTime);
function cTime() {
let time = that.maxWidth / 5
if (time >= 600) {
return 600
} else if (time <= 100) {
return 100
} else {
return time
}
}
}
},
// ios翻转图片
_reverseImgData(res) {
let w = res.width
let h = res.height
let con = 0
for (let i = 0; i < h / 2; i++) {
for (let j = 0; j < w * 4; j++) {
con = res.data[i * w * 4 + j]
res.data[i * w * 4 + j] = res.data[(h - i - 1) * w * 4 + j]
res.data[(h - i - 1) * w * 4 + j] = con
}
}
return res
},
_getH5ImageInfo(url, callback) {
let image = new Image()
image.src = url
image.onload = function (d) {
let imgSelf = this
let http = new XMLHttpRequest();
http.open("GET", url, true);
http.responseType = "blob";
http.onload = function (e) {
let httpSelf = this
if (httpSelf.status == 200 || httpSelf.status === 0) {
let reader = new FileReader();
reader.onload = function (e) {
// 代码参考 https://www.jianshu.com/p/eb855b580780
let view = new DataView(this.result);
if (view.getUint16(0, false) != 0xFFD8) return callback({ size: httpSelf.response.size, type: httpSelf.response.type, width: imgSelf.width, height: imgSelf.height, orientation: -1 });
let length = view.byteLength, offset = 2;
while (offset < length) {
let marker = view.getUint16(offset, false);
offset += 2;
if (marker == 0xFFE1) {
if (view.getUint32(offset += 2, false) != 0x45786966) return callback({ size: httpSelf.response.size, type: httpSelf.response.type, width: imgSelf.width, height: imgSelf.height, orientation: -1 });
let little = view.getUint16(offset += 6, false) == 0x4949;
offset += view.getUint32(offset + 4, little);
let tags = view.getUint16(offset, little);
offset += 2;
for (let i = 0; i < tags; i++)
if (view.getUint16(offset + (i * 12), little) == 0x0112)
return callback({ size: httpSelf.response.size, type: httpSelf.response.type, width: imgSelf.width, height: imgSelf.height, orientation: view.getUint16(offset + (i * 12) + 8, little) });
}
else if ((marker & 0xFF00) != 0xFF00) break;
else offset += view.getUint16(offset, false);
}
return callback({ size: httpSelf.response.size, type: httpSelf.response.type, width: imgSelf.width, height: imgSelf.height, orientation: -1 });
};
reader.readAsArrayBuffer(httpSelf.response);
}
};
http.send();
}
},
// 返回图片数据
_result(src, index) {
_rtArr.push(src)
_index = _index + 1;
if (_cgFile.length - 1 >= _index) {
this._imageCompress()
} else {
uni.hideLoading();
this.$emit("result", _rtArr);
}
},
_err(src) {
uni.hideLoading();
this.$emit("err", src);
}
}
}
</script>
<style>
._imageCompress {
position: fixed;
top: -99999upx;
left: -99999upx;
z-index: -99999;
}
</style>