前言
在我们的 H5 页面中,有人脸上传的功能, 在旧版的 iphone
上, 竖屏拍照之后照片自动旋转 90, 因此前端使用了exif.js
来根据照片的 orientation 信息来判断照片是否需要旋转. 但最近出现用户使用 iphoneX
拍照之后相片出现了横屏的情况
探索
一开始以为是 orientation 的问题,但是发现在 iphonex 上 alert 出来的 orientation 还是6
, 也就是 orientation 参数是正确的, 注释掉旋转相关的代码, 直接 canvas 绘图发现, iphonex 上竖屏拍照默认没有横屏!
方案
经过一番搜索, 发现是新版的 webkit 改变了image-orientation
这个 css 属性值, 在旧版是none
, 而在新版之中是’from-image’, 也就是默认会忽略 exif 数据, 新版会自动修正, 导致了我们之前使用的exifjs
(或者其他基于类似 exif 元数据来处理图片的库)
所以可以通过检测 image-orientaion 来判断是不是新版的 webkit 内核
var styles = getComputedStyle(document.querySelector("#some-image"));
if (styles.getPropertyValue("image-orientation") === "from-image") {// 图片已经被修正
}
参考代码
getOriginOrientationImage (imagePath) {return new Promise((resolve, reject) => {const image = new Image()image.src = imagePathuni.showLoading({title: '处理中...'})image.onload = function () {EXIF.getData(image, function () {const orientation = EXIF.getTag(this, 'Orientation')// 旋转图片为1方向if (orientation > 1 && orientation <= 8) {// https://github.com/mattiasw/ExifReader/issues/99#issuecomment-640217716let newWebkitHasFixedProtraitOrientaion = falseconst styles = getComputedStyle(document.querySelector('#face-image'))if (styles.getPropertyValue('image-orientation') === 'from-image') {newWebkitHasFixedProtraitOrientaion = true}const canvas = document.createElement('canvas')const ctx = canvas.getContext('2d')const imageWidth = image.widthconst imageHeight = image.heightconst canvasWidth = (orientation >= 5 && !newWebkitHasFixedProtraitOrientaion) ? imageHeight : imageWidthconst canvasHeight = (orientation >= 5 && !newWebkitHasFixedProtraitOrientaion) ? imageWidth : imageHeightcanvas.width = canvasWidthcanvas.height = canvasHeightctx.clearRect(0, 0, canvasWidth, canvasHeight)switch (orientation) {case 6:ctx.translate(imageHeight / 2, imageHeight / 2)if (!newWebkitHasFixedProtraitOrientaion) {ctx.rotate(90 * Math.PI / 180)}ctx.translate(-imageHeight / 2, -imageHeight / 2)breakdefault: break}ctx.drawImage(image, 0, 0)canvas.toBlob((blob) => {uni.hideLoading()const url = getObjectURL(blob)resolve(url)}, '2019/jpeg', 1)} else {uni.hideLoading()resolve(imagePath)}})}})
}
},
参考
EXIF Orientation Issue in Safari Mobile
Reports “right-top” for portrait photos