Core Image: Correcting Orientation

UIImage and UIImageView work together to ensure that photos are displayed in the correct orientation, based on the EXIF metadata for the image. However, Core Image does not respect orientation by default and this can cause Core Image backed rendering tasks (thumbnails, effects, etc.) to produce output with an unexpected results.

Lots of the correction techniques available in answers on Stack Overflow and other programming forums are wildly inefficient, producing a second full-resolution copy of the source image. Other techniques are based on the UIKit coordinate system (origin in upper-left corner, positive y pointing down) rather than the Core Image coordinate system (origin in lower-left corner, positive y pointing up).

Fortunately, there is a simple solution built into Core Image as of iOS 11: orientationTransform(for:). When invoked on a CIImage instance, it returns a CGAffineTransform which will convert the image from its current orientation to the .up orientation. This transform can be combined with any other transformed being performed or applied via the CIImage.transformed(by:) instance method. There is another form of the call which calculates and applies the transform, returning the resulting CIImage. See the documentation here.

Trying to correct orientation yourself is tedious and error-prone, using these methods will make it a snap and save you many hours of work.

Note: The enum cases used by the method are NOT the same as the UIImage.Orientation enum values. I’ve made a helper extension for UIImage.Orientation to convert it into the appropriate enum case for the orientation transform method.