在iOS开发中,当用户通过系统相机拍摄照片后,有时会出现照片自动旋转90度的问题。这主要与图片的`imageOrientation`属性有关,该属性描述了图片在内存中的方向,与实际显示的方向可能不一致。尤其是在图片进行裁剪、缩放等处理后,`imageOrientation`的设置可能导致图片显示异常。
问题的根本原因在于,当图片尺寸超过2MB时,iOS系统可能会对图片进行优化,导致图片元数据中的方向信息丢失或被忽视。在某些情况下,如使用`UIImagePickerControllerOriginalImage`获取图片时,即使原图拍摄时是正向的,但图片显示时可能会根据`imageOrientation`属性旋转。
解决此问题的方法主要有两种:
1. **允许编辑(Allows Editing)**:
设置相机控制器`UIImagePickerController`的`allowsEditing`属性为`YES`。这样用户在拍照后可以进行简单的裁剪。当使用`UIImagePickerControllerEditedImage`来获取照片时,系统会自动处理图片的旋转问题,返回的图片`imageOrientation`属性为`UIImageOrientationUp`,表示正常方向,因此后续处理不会导致旋转。
2. **手动修正图片方向(Fix Orientation)**:
如果需要对图片进行更复杂的处理,如裁剪或压缩,第一种方法可能不够用。这时可以使用如下的方法来手动修正图片的方向:
```swift
extension UIImage {
func fixOrientation() -> UIImage? {
if imageOrientation == .up {
return self
}
let cgImage = cgImage!
let orientation = imageOrientation
var transform = CGAffineTransform.identity
switch orientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: size.width, y: size.height)
transform = transform.rotated(by: .pi)
case .left, .leftMirrored:
transform = transform.translatedBy(x: size.width, y: 0)
transform = transform.rotated(by: .pi / 2)
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: size.height)
transform = transform.rotated(by: -.pi / 2)
default:
break
}
if orientation.isFlipped {
transform = transform.translatedBy(x: 0, y: size.height)
transform = transform.scaledBy(x: -1, y: 1)
}
let cgImageFixed = cgImage.transformed(by: transform)
let newImage = UIImage(cgImage: cgImageFixed)
return newImage
}
}
```
这个扩展方法会根据`imageOrientation`的值计算出正确的转换矩阵,然后应用到图片的`CGImage`上,从而得到一个修正方向后的新的`UIImage`对象。
在实际开发中,可以根据具体需求选择合适的方法。第一种方法简单且适用于大部分情况,而第二种方法更加灵活,能确保在任何情况下正确处理图片方向。无论哪种方式,都需要在处理图片前先检查`imageOrientation`,以确保图片在展示或上传时不发生旋转。