微信小程序开发上传图片后缀名为unknow和getImageInfo的orientation不准的问题

问题1:在云开发的存储中发现一些文件名为unknow,打开开发调试发现小程序chooseMedia拍摄图片后后缀名为unknow。
在微信社群里搜索了相关信息官方表示这确实是一个bug。

微信小程序开发上传图片后缀名为unknow和getImageInfo的orientation不准的问题_第1张图片

但是官方没有说明下次更新时间,而且这个bug前端也可以稍加修复。只需要判断后缀名是不是自己规定的并且设置一个默认的后缀名即可。

  getExt: function (filename,defaultExt) {
    if(filename && filename.length > 3) {
      const r = filename.split('').reverse().join(''); // 反转
      const p = r.search(/\./)
      if(p > 2) {
        // .unknown
        const ext = r.substring(0,p).split('').reverse().join('');
        if(['jpg','jpeg','png','mp4'].includes(ext)) {
          return ext
        }else{
          return defaultExt
        }
      }else{
        return defaultExt
      }
    }else{
      return defaultExt
    }
  },

问题2:getImageInfo的orientation不准
一开始发现上传的图片很多方向都不对。就想到用canvas旋转一下图片。

// 非要和国际标准不一样 不知道怎么想的
const orientations = {
  up: 1,
  'up-mirrored': 2,
  down: 3,
  'down-mirrored': 4,
  'left-mirrored': 5,
  right: 6,
  'right-mirrored': 7,
  left: 8
}


module.exports = async function (canvas,ctx,imgs) {
  if(Array.isArray(imgs) && imgs.length) {

    const tasks = []
    for(const o of imgs) {
      const promise = rotate(canvas,ctx,o).then(res=>{
        return {...o,...res}
      })
      tasks.push(promise)
    }
    return await Promise.all(tasks)

  }else{
    return null
  }
}

async function rotate (canvas,ctx,o) {
  console.log('rotate',canvas,ctx,o)


  if(o.orientation === 'up') {
    return {}
  }

  return await new Promise((resolve)=>{
    const imgObj = canvas.createImage()
    imgObj.src = o.tempFilePath
    //imgObj.width = o.width
    //imgObj.height = o.height
    imgObj.onload = function (e) {
      console.log('imgObj.onload')
      let width = 0;
      let height = 0;
      let deg = 0;
      const orientation = orientations[o.orientation]
      console.log('orientation',orientation)
      // 开始旋转逻辑
      if ([2, 3, 6, 8, 4, 5, 7].includes(orientation)) {
        if (orientation === 3 || orientation === 4) {
          width = o.width;
          height = o.height;
          deg = 180;
        } else if (orientation === 6 || orientation === 5) {
          width = o.height;
          height = o.width;
          deg = 90;
        } else if (orientation === 8 || orientation === 7) {
          width = o.height;
          height = o.width;
          deg = -90;
        }
        // 利用canvas 进行旋转
        canvas.width = width
        canvas.height = height

        console.log('reset canvas',canvas)

        // 旋转canvas 并且 把图片放入canvas
        ctx.translate(parseInt(width / 2, 10), parseInt(height / 2, 10));
        if ([2, 4, 5, 7].includes(orientation)) {
          ctx.scale(-1, 1);
        }
        ctx.rotate((deg * Math.PI) / 180);
        ctx.drawImage(
          imgObj,
          0,
          0,
          o.width,
          o.height,
          0 - o.width / 2,
          0 - o.height / 2,
          o.width,
          o.height
        );

        console.log('drawImage',imgObj)

        wx.canvasToTempFilePath({
          canvas,
          fileType:'jpg',
          quality: 0.5,
          x: 0,
          y: 0,
          width,
          height,
          destWidth: width,
          destHeight: height,
          success(res) {
            console.log('canvasToTempFilePath',res,width,height)
            resolve({
              width,
              height,
              tempFilePath: res.tempFilePath
            })
          },
          fail(err) {
            console.log('fail err',err)
          },
          complete(res){
            console.log('com res',res)
          },
        })
      }

    }

  }).then(res=>{
    console.log('res2',res)
    return res
  })

}

以上是旋转并保持图片为本地临时文件的方法,由于微信开始自己出了一套canvas规则后来又废弃采用web标准版本的canvas,导致API文档新旧规则你中有我,我只有你。看完文档后通常就拿不定用哪一个方法如何开始了。微信自己实现的canvas drawImage 是支持临时文件的,而web标准版本的drawImage支持的是image对象的,在这个地方很多人都被官方带沟里了。

当我实现canvas旋转图片后发现getImageInfo的orientation不准,让我无法判断用户选择的图片的orientation,从而导致了无法正确的旋转图片。

后来经过各种资料查找发现getImageInfo只能判断原图的方向,知道这个问题就好办了,修改chooseImage文件类型为原图即可。

你可能感兴趣的:(前端,小程序,javascript)