需求很简单:h5拍照上传照片,然后显示出来
问题在:上传之后的图片在PC,IOS端均能正常显示,Android端显示的则是被旋转90度的。
直接上代码
下面这个方法传入file对象,然后会去除掉照片中的exIf信息,之后返回。用这个方法,就可以保证PC,IOS,Android端都显示正常的图片。
function removePicExif(file){ return new Promise((reslove) => { if (file) { let reader = new FileReader(); let image = new Image(); reader.onload = function (ev){ image.src = ev.target.result; image.onload = function (){ const ctxWidth = this.width; const ctxHeight = this.height; const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); canvas.width = ctxWidth; canvas.height = ctxHeight; ctx.drawImage(this, 0, 0, ctxWidth, ctxHeight); canvas.toBlob((blob) => { const newFile = new File([blob], file.name, { type: "image/jpeg", lastModified: Date.now(), }); reslove(newFile) }); }; }; reader.readAsDataURL(file); } }) }
下面我来说下我的研究
发现在手机垂直拍摄上传的图片会在Android中被旋转后,查了很多资料,大同小异,就是获取到图片的EXIF信息,然后利用canvas旋转到正确的方向。
但是,但是实际测试中,我发现并不需要利用canvas再做旋转。
大家可以拿出手机来拍摄一下,在垂直竖拍情况下,拍摄的图片正常。在垂直横拍的情况下,其实拍摄的图片也是和垂直竖拍的方向一样的。
在垂直的情况下,你无论横排,竖拍,倒着拍,拍出来的图片,方向都是以竖拍方向来的,并不会因为你是倒着拿手机,手机拍出来的照片就是倒的
这是垂直竖拍
这是垂直横拍
垂直情况下,你怎么拿手机,拍出来的方向都是一个
所以,其实手机端在拍摄的时候已经帮我们旋转到了合适的方向,不需要我们再进行旋转了。但是,照片信息依然保留了该照片的拍摄方向,所以,在Android上,Android再一次根据拍摄方向自动做了旋转,结果就是转过了,导致Android的图片显示不对。
所以,我们要做的,仅仅应该是取消EXIF信息,而不是旋转。
小彩蛋,到这其实基本就结束了,但是,水平情况下呢,手机拍照又是什么情况呢
当你手机和地面平行,拍摄地面,你会发现,拍出来的照片就是最初的样子,横着拍,照片就是横的,竖着拍。照片就是竖的,手机这是没有做处理,你觉得是为什么呢
文章来源: segmentfault.com,作者:barry,版权归原作者所有,如需转载,请联系作者。
原文链接:segmentfault.com/a/1190000038283517