肇鑫的技术博客

业精于勤,荒于嬉

CGImageSource对照片自动旋转问题的解决

前两天用咕唧分享照片的时候,我发现分享出去的照片,与我查看时的角度不一致,被转了90°。这是一个需要解决的问题。

分析问题1

一开始,我以为是咕唧的隐私保护功能导致的。为了保护隐私,咕唧默认会移除照片中的GPS信息和Exif信息。此外,用户可以在设置中,选择分享这些信息。

我们知道,平常拍照片,你的手机可能是横着拍,也可能是竖着拍,偶尔可能倒过来拍。但是不管你拍照时,手机处于何种角度,系统在显示该照片的时候,都会正确的显示该照片为当时你在屏幕上见到的样子。因为系统会读取照片属性中的方向信息,从而知道你拍照时手机的状态,这样就能正确的显示。

我首先就是认为Exif信息被咕唧删除了,系统没有了参照,只能按照默认的方式处理,因而与实际的方式造成了偏差。

解决问题1

我创建了一个测试项目,然后将那张出问题的照片作为资源,做同样的缩小操作,之后查看照片属性。结果我发现其实方向Orientation属性并没有保存在Exif信息,而是在图片的属性中。也就是说,事实上,咕唧缩小的图片是包含这个信息的。之前的分析是错误的。

那么是什么原因导致了包含了正确方向信息的照片,实际显示的反而是错误的呢?

分析问题2

排除了一切不可能,剩下的就是唯一的可能。

我们知道,系统在读取照片的时候,会根据方向Orientation做正确的处理。也就是说,CGImageSourceCreateImageAtIndex(_:_:_:)获得的照片本身就是正确方向的。那么这个方向正确的照片。在通过CGImageDestination重新保存时,就应该改变Orientation值为默认值,而不是继续保存原始值。

解决问题2

如果上面的分析正确,思路就很简单了。保存之前,检查方向Orientation是否为默认值,如果不是,则修改为默认值。

注意:是只要CGImageSource加载了图片,就会造成这个问题。因此,不仅缩小照片有这个问题,仅仅是去除Exif或者GPS信息,都会存在这个问题,同样需要修改方向Orientation为默认值。

思考

我在想要不要把这个问题,作为bug报告给苹果。思考的结果是不要。因为如果苹果修复了这个问题,将新照片变成与原始照片的方向一致。那么之前有做过特殊处理的应用,照片的方向就又都会从正确变成错误。这相当于是API不延续了。

为了保证之前的兼容性,好多时候,只能遗留不正确的代码。这个就是API设计出问题的代价。

参考资料