艺灵设计

全部文章
×

移动端H5页面拍照上传图片后图片被旋转的bug及修复方案

作者:艺灵设计 - 来源:http://www.yilingsj.com - 发布时间:2020-01-05 23:26:22 - 阅: - 评:0 - 积分:0

摘要:
由于之前艺灵基本没有完整的把图片上传流程跑一遍,所以也就不知道原来使用某些机型的手机拍照后会出现自动旋转图片的bug。这个问题是同事在测试时发现的,后由我来专门研究并通过查阅资料的方式进行了修复。下面来完整的复现下过程并提供可测试的demo供看官体验......

最后更新:2020-01-10 21:30说明:补充了图片、demo演示链接及demo源码

一、起因

因公司业务需要,移动端有一个上传图片的功能。其他同事开发完功能后在测试时意外发现一个有趣的现象:用苹果手机拍照(注:这里是正常的手势,也就是竖着拍照。)上传后缩略图会自动旋转90度。效果如图:部分手机拍照上传图片到服务器后出现了旋转

二、排查原因

虽然这块儿代码不是我写的,但解决bug这种事情,艺灵我是最喜欢的了。于是我就开始了长达几个小时的填坑之路......

在看了项目中上传图片这块的代码后,艺灵发现这里有几个步骤:本地选择图片 - 上传到公司服务器 - 同步到又拍云 - 返回图片地址 - 拼接图片链接并显示图片,大致代码长这个样子。如图:最终的代码逻辑片断最终的代码逻辑片断

由于不知道是哪个环节出了问题,所以艺灵我一开始采用了最笨的方法,即:一步步打印图片的地址。自以为这种方式最保险,岂料忽略了某些浏览器有一个自动纠正图片旋转的功能!所以,当时的结论自然就错了。初步结论:手机上拍照是正常的,一上传到又拍云上就发生了旋转。当时我还以为是在上传又拍云时少了参数。。。。。。

随即,我又开始把关键字放到又拍云上进行搜索,结果发现还真有类似的情况,然后又出现了新的关键字:exif.js

三、exif.js读取图像元数据

由于艺灵也不知道这个exif.js是个啥,所以只能继续搜索相关文章,最终发现是这样一回事:先用exif中的Orientation判断出图片的拍摄方向,如果发生了旋转,我们用canvas绘画图片并加以修正,最后再导出修正后的图片上传到服务器。

四、demo演示

说了这么多,来个可以体验的链接给各位看官体验下吧。扫码访问:移动端拍照上传图片后使用exif检测图片信息的demo
手机端点我访问

五、总结

1、强烈建议把new Image()放到EXIF.getData()的回调函数中;如图:建议在EXIF.getData的回调方法中写图片上传的逻辑
2、网上部分文章用navigator.userAgent.match(/iphone/i)判断苹果手机的方法并非万能,如图:网上部分文章用navigator判断苹果手机的方法存在误区因为公司有同事的小米手机拍照上传后图片也发生了旋转;
3、var encoder = new JPEGEncoder();这串代码在我的安卓手机上报错了,JPEGEncoder这个方法在部分安卓手机上会报错找不到出处,所以我把这段判断全干掉了,只要用exif检测出图片发生了旋转统统纠正。

如果看官在实际操作中遇到类似问题,可参考艺灵提供的demo源码进行解决。

六、源码下载

为了方便看官下载源码,目前源码已经上传到了github上,访问源码
虽然只是一个小小的demo,艺灵使用了@vue/cli脚手架配合创建了项目。使用typescript确实太浪费了,就当是自己巩固练手吧。最主要的两个文件是:
src/views/Home.vue:首页;
src/assets/js/fixPhotoRotation.ts:解决图片旋转的源码。
这两个文件里面都保留有注释,其他文件都是vue/cli脚手架相关的,不用看。如果在实际过程中还有问题,可通过右侧qq或下方二维码联系艺灵。

转载声明:
  若亲想转载本文到其它平台,请务必保留本文出处!
本文链接:http://www.yilingsj.com/xwzj/2020-01-05/exif-fix-upload-picture-rotated.html

若亲不想直保留地址,含蓄保留也行。艺灵不想再看到有人拿我的技术文章到他的地盘或者是其它平台做教(装)程(B)而不留下我的痕迹。文章你可以随便转载,随便修改,但请尊重艺灵的劳动成果!谢谢理解。

亲,扫个码支持一下艺灵呗~
如果您觉得本文的内容对您有所帮助,您可以用支付宝打赏下艺灵哦!

Tag: 移动端 H5 上传图片 图片旋转 bug ios exif.js @vue/cli typescript Orientation canvas 源码下载

上一篇: 我花了两个多小时重写代码,只因点了SourceTree中的丢弃   下一篇: 返回列表

评论区