最近在处置惩罚挪动端挑选图片及时预览并上传时碰到一个题目:上传前图片预览寻常,但上传到服务器上的图片展现到页面上时,有时会涌现图片翻转的题目,寻常是翻转 90 度。后经一翻研讨找到了题目所在,特在此纪录一下。
题目形貌
接上面提到的题目,经由一些测试,发明:假如拔取的图片是在横屏状况下拍摄的,则上传后不会涌现图片翻转的题目;反之,假如是在竖屏状况下拍摄的,上传后就会涌现图片翻转的题目。
题目剖析
起首,图片在当地预览时寻常,而且前端末了提交到后端的数据是用 FormData
来封装处置惩罚的,用 FormData
能够保证提交的数据和一般的表单提交没有什么区别,对后端来讲是通明的,后端的处置惩罚逻辑不必修正就能够处置惩罚带文件的 Ajax 提交。因而,我猜测题目能够出在了后端。
然则后端也没有做什么特别的处置惩罚,怎样展现的时刻图片就翻转了呢?
OK,前面提到过这个题目和手机的照相形式有关,竖屏下拍的照片会重现这个题目,横屏下的则不会。岂非这两种形式下拍摄的照片不一样?照片中保留的数据不一样?,这不由的使我想到了 [Exif][] 这个名词,虽然我对它不是非常相识,然则印象中它是用来保留照片的一些元数据信息的,或许和它有关。
简朴的一搜刮发明:Exif[orientation]有一篇关于它的细致的引见,此处不睁开细讲。简朴来讲就是它有 8 个值,用来示意照片拍摄时相机扭转的状况,而且我们能够经由过程编程的体式格局读取它。我们寻常用电脑来检察手机拍摄的照片时也会偶然涌现图片翻转的状况,其缘由也是照片检察软件没有根据这个值将照片自动翻转。
经由搜刮,在 SO 上找到了相干的题目。其思绪就是读取照片的 Exif 信息,推断 Orientation 的值,然后将图片举行响应的扭转。题目已一定,后端同砚很快就将这个题目给修复了,而且增加到了他们的大众模块中。
你以为题目就如许处理了,当时并没有。
后续
过了几天,公司置办了几台全新的测试机,测试同砚将体系在一台三星的机子上一测,又发明新题目了:挑选完图片举行当地预览时,发明图片翻转了!但上传后再展现又是寻常的。WTF!
此次没得说了,题目一定出在了前端预览上。然则之前在安卓和 iOS 的装备上测试都是寻常的呀,岂非和机型有关?问了一下测试,得知这台三星用的是 Android 5.0 的体系,好先进有木有!这岂非是 5.0 中引入的一个题目?别想这些了,横竖我们也不能够在体系层面去修复这个题目,照样想一想怎样去兼容 5.0 吧。
当时想到了两种要领,一种是挑选图片后先上传到服务器,再展现上传的图片举行预览。这类要领的长处是兼容性好,前端处置惩罚相对简朴;瑕玷是后端要供应图片上传的接口,而且假如用户在保留之前替换图片并不会删除之前上传的图片。挪动端的微博配图就是用的这类要领。
另一种要领是在当地举行图片翻转。我们能够运用 FileReader
API 来读取图片,以后像后端那样剖析 Exif 信息,扭转图片。这类做法的长处是,预览操纵完整在当地完成,不会发生不必要的文件上传。瑕玷是 FileReader
在 Android 4.1 及以上的机型才能够运用,加上前端处置惩罚文件数据能够稍显庞杂,别的机能也是个题目。
然则终究我们挑选了第二种计划。缘由是我们之前的照片预览就是用的 FileReader
API,不需要斟酌低版本安卓的兼容性,这和项目的实际状况有关。另一个缘由是我们以为或许有前人已碰到过这类题目,或许已有了比较好的处置惩罚这个题目的功能模块。后经搜刮,找到了一个 fix-orientation
模块,能够经由过程 npm i fix-orientation --save
运用,详细的用法能够参考项目的文档。厥后,扫了一眼它的代码,发明它是用 canvas 来完成图片的扭转,并不会对寻常的图片进操纵,机能题目不大,iOS 上秒开,安卓装备上稍长,能够增加 loading 结果减缓一下。
至此,题目圆满处理。
别的,像 fix-orientation
如许小而美的模块有许多,人人日常平凡能够多关注一下。