项目:taro3 + vue3
描述:
- 上传图片,证件的地方需要识别
- 微信和h5端是用的base64方式传参 -> taro兼容微信小程序和h5 - 上传图片及转换base64
本文是在以上的基础上兼容支付宝小程序
方法一
这个是官方文档的方法,效果如何没有试…
my.chooseImage({
success: res => {
const path = res.apFilePaths[0];
console.log(path);
my.uploadFile({
url: 'https://...', // 请替换成有效的服务端 url
fileType: 'image',
fileName: 'userfile',
filePath: path,
formData: { extra: '其他信息' },
success: res => {
my.alert({ title: '上传成功' });
},
fail: err => {
my.alert({ title: '上传失败', content: JSON.stringify(err) });
},
});
},
});
方法二
用base64的方法
1、用官方的方法转,真机报错
my.chooseImage({
success: res => {
const fs = my.getFileSystemManager();
fs.readFile({
filePath: `${res.apFilePaths[0]}`,
// readFile 不传入 encodding 参数,则以 ArrayBuffer 方式读取
success:({ data }) => {
const base64 = my.arrayBufferToBase64(data);
//
},
});
}
});
2、用canvas转
页面中放一个canvas, 通过toDataURL转base64
<canvas
id="upload-canvas"
:width="canvasWidth"
:height="canvasHeight"
style="display: none;">
</canvas>
canvasWidth = ref(160)
canvasHeight = ref(160)
events.on(PAGE_EVENTS.SET_CANVAS_SIZE, data => {
const { width, height } = data
this.canvasWidth.value = width
this.canvasHeight.value = height
})
/**
* 支付宝转base64
* @param id canvasId
* @param path 路径
*/
export async function useGetBase64InAlipay({ id, path }) {
const { width, height } = await useGetImageInfo(path)
let newWidth = width
let newHeight = height
let scale = 1
if (width > height) {
newWidth = width > 750 ? 750 : width
scale = newWidth / width
newHeight = parseInt(height * scale)
} else {
newHeight = height > 750 ? 750 : height
scale = newHeight / height
newWidth = parseInt(width * scale)
}
if (!ctx || (ctx && (newWidth !== canvasWidth || newHeight !== canvasHeight))) {
ctx = Taro.createCanvasContext(id)
canvasWidth = newWidth
canvasHeight = newHeight
events.trigger(PAGE_EVENTS.SET_CANVAS_SIZE, { width: newWidth, height: newHeight })
}
return new Promise(resolve => {
ctx.drawImage(path, 0, 0, newWidth, newHeight)
ctx.draw(false, () => {
ctx.toDataURL().then(async dataURL => {
resolve(dataURL)
})
})
})
}
/**
* 获取图片信息
* @param path
*/
export function useGetImageInfo(path) {
return new Promise(resolve => {
my.getImageInfo({
src: path,
success: res => {
resolve(res)
}
})
})
}
这里面的遇到的坑:
1、得到的图片不完整
解决:画的时候图片宽高和画布的宽高保持一致
ctx.drawImage(path, 0, 0, width, height)
width, height必须和canvas的一样
2、在1的基础上出现另一个问题:如果证件尺寸很大,比如 1200 * 1500,得到的图片会比例不对,就没有办法识别
解决:在chooseImage的临时图片用getImageInfo()去获取图片的宽高,然后等比例缩放后再转base64
**!!注意:**等比例缩放后的宽高要同步到canvas上,否则得到的图片还是不完整的
3、最后后端返回的证件识别的时候报错
解决:后端小伙伴做了一个重绘