收藏
回答

canvasToTempFilePath并发调用,偶现空白图片,各位有遇到吗?

批量处理图片压缩用到这个接口,新的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]
      }
    })
}


不知道去掉并发会不会解决问题,这种偶现的问题真难排查。

最后一次编辑于  2020-04-19
回答关注问题邀请回答
收藏

2 个回答

  • Admin ²º²⁴
    Admin ²º²⁴
    2020-04-19

    安卓机下碰到过多次

    需要setTimeOut

    根据图片大小定时间,一般setTime(xxx,2000)2秒钟够了

    2020-04-19
    有用 2
    回复 2
    • 郑旭东
      郑旭东
      2020-04-20
      感谢回复!
      2020-04-20
      回复
    • 郑旭东
      郑旭东
      2020-04-21
      刚用了一台中端Android机测试了下,确实一张图片要搞2秒钟左右,这玩意儿太耗性能了。小程序端压缩看来不是一个好方案,还是得放服务端去...
      2020-04-21
      回复
  • 郑旭东
    郑旭东
    2020-04-20

    把并发去掉了,改为递归函数一张一张压缩,初步试下来问题没再出现。

    回想问题的细节,往往第一张和第二张空白,所以,可以想象前面的图片开始canvasToTempFilePath时,后面的图片还在drawImage,资源比较吃紧,导致执行异常。一张一张搞就避免的这个问题。

    Admin提供的方案我也试了,也能解决问题,但是在我的场景下等待2秒钟比较浪费时间,影响客户体验。

    2020-04-20
    有用 1
    回复 7
    • Admin ²º²⁴
      Admin ²º²⁴
      2020-04-20
      谢谢啊,我不知道你还并发调用了,这个我也碰到过。并发首先得去掉。我是并发去掉然后加上seteTimeOut才解决的,低端机,速度慢的时候必须setTimeOut,这个是异步的,不用setTimeOut就用阻塞方式也可以解决,根本问题就是要解决不能同时有2个canvasToTempFilePath在执行。否则就出问题。
      2020-04-20
      回复
    • 郑旭东
      郑旭东
      2020-04-20回复Admin ²º²⁴
      你是用的新版的2D接口吗?老的接口draw是异步回调的。新版的是标准web接口,我查了下web参考文档里倒没有说起异步的特性。按理异步的话我的同步逻辑代码执行会很大概率出问题。我怀疑低端机可能也还是性能问题引起的异常。
      2020-04-20
      回复
    • Admin ²º²⁴
      Admin ²º²⁴
      2020-04-20回复郑旭东
      draw没问题,canvasToTempFilePath是异步的~~~看canvasToTempFilePath的回调就知道了。
      2020-04-20
      回复
    • 郑旭东
      郑旭东
      2020-04-20回复Admin ²º²⁴
      那问题不大,我改完的代码是异步回调里面再接一个递归函数执行下一张图片的。
      2020-04-20
      回复
    • Admin ²º²⁴
      Admin ²º²⁴
      2020-04-20回复郑旭东
      如果你是在canvasToTempFilePath回调里递归下一个的那100%没问题了。~
      2020-04-20
      回复
    查看更多(2)
登录 后发表内容
问题标签