开发过程中难免会遇到各种诡异的Bug。不知道大家有没有遇到这样的情况,在做一个社交类应用时,我们时常需要将我们手机上的照片上传到自己或者第三方的服务器上存储起来,当照片数据上传成功之后,我们再根据后台接口从服务器获取我们所上传的照片数据并在UI上显示出来(比如发表朋友圈和修改头像)。在经过这样一系列操作之后,我们神奇的发现,其中有一部分照片的方向变了,它们旋转了90°。
当然,程序员什么大风大浪没见过,遇到Bug我们并不慌张,于是本着存在即合理的原则,我开始检查出错原因:
首先我检查了代码,照片在上传和下载过程中并没有进行过任何压缩或其他处理(那肯定不是我的错,我这样想着)。
于是我开始在后台找原因,然后有了新的发现,我上传的照片在后台服务器中已经是旋转的了(难怪我下载的照片是旋转的,肯定是后台对我上传的照片做了处理,我这样想着)。
带着这样的疑问我去问后台,后台很无辜,他说天地良心他什么也没干(善良的我相信了)。
最后我只能去问安卓,然而他们一切正常,安卓的同事并没有遇到过我这样的Bug。
毫无办法的我只能对着照片冥思,改变了方向的照片都是iPhone设备上所拍的照片,网络上下载的和其他地方保存的照片方向并没有改变,问题应该出在照片本身上。
EXIF介绍
对于图像数据,其实并不是我们理解的那样,图像一般都由两大部分组成,一部分是数据本身,它记录了每个像素的颜色值,另外一部分是文件头,这里面记录着形如图像的宽度,高度等信息。我们所讨论的方向信息便是被存储于文件头中。更为具体一些:EXIF中。
可交换图像文件格式常被简称为Exif(Exchangeable image file format),是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据,同时Exif可以附加于JPEG、TIFF、RIFF等文件之中。
注意:PNG格式的图像中不包含。
解决方案
这样对于照片旋转问题就有了一个合理的解释,我们通过iPhone手机拍摄照片时,手机通过方向传感器记录了照片拍摄时的方向。这样我们在iPhone设备上查看照片时,设备会自动的将那些横七竖八的照片为我们进行旋转操作,因此我们在iPhone上看到的照片永远是正的,不管你拍摄的时候用了何等扭曲的姿势。
然而并不是所有的设备都能识别这样的信息,当我们将这些数据传到服务器上时,服务器也并不能识别照片的方向信息,它当然也不会依据照片的方向信息为我们进行旋转操作。因此展现在我们眼前的就是那些没有经过任何处理的横七竖八的图像。
服务器识别不了,并不代表开发者不能,这样就需要我们在上传照片之前,先将照片进行处理,通过方向信息摆正照片的方向。
代码实现如下:
/**
* 处理ios开发图片旋转的问题
*
* @param image 需要转换的image
*
* @return 转换完成的image
*/
+ (UIImage *)normalizedImage:(UIImage *)image {
if (image.imageOrientation == UIImageOrientationUp) return image;
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
[image drawInRect:(CGRect){0, 0, image.size}];
UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return normalizedImage;
}
这里是利用了UIImage中的drawInRect方法,它会将图像绘制到画布上,并且已经考虑好了图像的方向,使用时需要添加<UIKit/UIKit.h>
框架。
除了以上方式以外还有其他方式同样可以解决这个问题,只不过稍微有点复杂,网上有一篇很好的文章如何处理iOS中照片的方向,这里就不再赘述了。