问题 1: 在云开发的存储中发现一些文件名为 unknow,打开开发调试发现小程序 chooseMedia 拍摄图片后后缀名为 unknow。
在微信社群里搜索了相关信息官方表示这确实是一个 bug。
但是官方没有说明下次更新时间,而且这个 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 文件类型为原图即可。