批量处理图片压缩用到这个接口,新的canvas 2D接口。
先选择多张图片,然后一个for循环,drawImage,接一个canvasToTempFilePath。
为了支持并发,我也在wxml放了对应个数的canvas标签。
偶现第一张或第二张空白图,图大小2k左右。(正常图20K以上)。
亮代码:
let photos = this.data.photos
let l = photos.length
for (let i = 0; i < l; i++) {
let photo = photos[i]
let canvasId = '#compress' + i
wx.createSelectorQuery()
.select(canvasId)
.fields({
node: true,
size: true,
})
.exec(res => {
const canvas = res[0].node
const ctx = canvas.getContext('2d')
canvas.width = 540
canvas.height = 540
const image = canvas.createImage()
image.src = photo.path
image.onload = () => {
const width = image.width
const height = image.height
const sizeRatio = width > height ? width / height : height / width
let sWidth, sHeight, sX, sY, dWidth, dHeight
//这里一些处理图片尺寸的逻辑,省略...
ctx.drawImage(image, sX, sY, sWidth, sHeight)
wx.canvasToTempFilePath({
canvas,
fileType: 'jpg',
quality: 0.8,
width: dWidth,
height: dHeight,
success: res => {
photo.pathCompressed = res.tempFilePath
}
})
photo.k = photo.size //restore the bytes size
photo.sizeOriginal = [width, height]
photo.size = [dWidth, dHeight]
}
})
}
不知道去掉并发会不会解决问题,这种偶现的问题真难排查。
安卓机下碰到过多次
需要setTimeOut
根据图片大小定时间,一般setTime(xxx,2000)2秒钟够了
把并发去掉了,改为递归函数一张一张压缩,初步试下来问题没再出现。
回想问题的细节,往往第一张和第二张空白,所以,可以想象前面的图片开始canvasToTempFilePath时,后面的图片还在drawImage,资源比较吃紧,导致执行异常。一张一张搞就避免的这个问题。
Admin提供的方案我也试了,也能解决问题,但是在我的场景下等待2秒钟比较浪费时间,影响客户体验。