1. 安装jsqr
npm install jsqr --save
2. 导入jsqr
import jsQR from 'jsqr';
3. 添加组件
<template>
<view>
<canvas :style="{width: screenWidth+'px', height: screenHeight+'px',position: 'absolute', top: 999999, left: 999999, zIndex: -20, opacity: 0}" canvas-id="qrcodeCanvas" id="qrcodeCanvas"></canvas>
<u-upload class="uUpload" :file-list="fileList" :before-upload="beforeUpload" ></u-upload>
</view>
</template>
4. 完整代码
<script>
import jsQR from 'jsqr';
export default {
name: 'UploadFile',
data() {
return {
fileList: [], //图片列表
canvasContext: null, // Canvas 的上下文对象
screenWidth: 300,
screenHeight: 300,
};
},
mounted() {
this.screenWidth = uni.getSystemInfoSync().screenWidth
this.screenHeight = uni.getSystemInfoSync().screenHeight
},
methods: {
async beforeUpload(index, list) {
if (list.length > 0) {
uni.showLoading({
title: "识别二维码中...",
mask: true,
});
// 1. 获取图片本地路径
const file = list[index].file; // 获取图片路径
// 2. 解码
return this.decodeQrCode(file).then((result) => {
if (result.data) {
// 解码成功
// 其他操作
// ***********
return true;
} else {
return false;
}
uni.hideLoading()
}).catch((error) => {
// this.$toast.msg(error.msg || '二维码检查失败');
uni.hideLoading()
return false;
});
// #endif
}
},
resizeCanvas(canvas, imageWidth, imageHeight) {
// 计算缩放比例
let scale = Math.min(this.screenWidth / imageWidth, this.screenHeight / imageHeight);
return {
drawWidth: imageWidth * scale,
drawHeight: imageHeight * scale,
}
},
async decodeQrCode(myfile) {
try {
return new Promise((resolve, reject) => {
// 2.1 获取图片宽高
uni.getImageInfo({
src: myfile.path,
success: (image) => {
// console.log(image.width);
// console.log(image.height);
// console.log(myfile.path, 'file');
var context = uni.createCanvasContext('qrcodeCanvas')
const {drawWidth, drawHeight} = this.resizeCanvas(context, image.width, image.height)
// 2.2 canvas 绘制图片
// canvas宽高设置为 屏幕的宽高,二维码 按原图比例缩放为 屏幕的宽高
context.drawImage(myfile.path, 0, 0, drawWidth, drawHeight); // (图片源, x, y, 宽度, 高度)
context.draw(false, () => {
// 必须延迟绘制
setTimeout(() => {
console.log('绘制完成');
// 2.3 图片转 Uint8ClampedArray
uni.canvasGetImageData({
canvasId: 'qrcodeCanvas',
x: 0,
y: 0,
width: this.screenWidth, // 宽度为canvas的宽
height: this.screenHeight, // 高度为canvas的高
success: (res) => {
try{
// 2.4 解码二维码,解码图片的宽高为canvas宽高,保证 解码图像像素点数据完整,否则 识别二维码失败
this.detectQRCodeJSQR(res.data, this.screenWidth, this.screenHeight).then(res=> {
// console.log(res);
resolve({
data: true,
msg: res
})
}).catch(error => {
console.log(error);
reject({
data: false,
msg: error
})
})
}catch(e){
//TODO handle the exception
console.log(e, '捕获格式错误');
}
}
})
}, 0)
})
}
});
})
} catch (e) {
//TODO handle the exception
console.log(e, 'error');
}
},
// ************检查二维码************
async detectQRCodeJSQR(imageData, width, height) {
return new Promise((resolve, reject)=> {
if (!imageData instanceof Uint8ClampedArray) {
console.error('Invalid image data');
return;
}
console.log(imageData);
// 3. 调用jsQR 进行二维码识别
const code = jsQR(imageData, width, height, {
inversionAttempts: "attemptBoth"
});
if (code) {
console.log('识别到的二维码内容:', code.data);
resolve({
data: true,
msg: code.data
});
} else {
console.log('未识别到二维码');
reject({
data: false,
msg: '请上传有效二维码'
});
}
})
},
},
}
</script>