How to load an image and rotate it according to it's orientation exif data and save it with UIImageOrientationUp exif data (or without any orientation exif data) so that software that don't handle exif orientation data will show correctly the image ?
How to load an image and rotate it according to it's orientation exif data and save it with UIImageOrientationUp exif data
1.7k Views Asked by zeus At
2
There are 2 best solutions below
5
On
Swift 4 equivalent of my previous objective-c method as an extension:
extension UIImage {
func byFixingOrientation(andResizingImageToNewSize newSize: CGSize? = nil) -> UIImage {
guard let cgImage = self.cgImage else { return self }
let orientation = self.imageOrientation
guard orientation != .up else { return UIImage(cgImage: cgImage, scale: 1, orientation: .up) }
var transform = CGAffineTransform.identity
let size = newSize ?? self.size
if (orientation == .down || orientation == .downMirrored) {
transform = transform.translatedBy(x: size.width, y: size.height)
transform = transform.rotated(by: .pi)
}
else if (orientation == .left || orientation == .leftMirrored) {
transform = transform.translatedBy(x: size.width, y: 0)
transform = transform.rotated(by: CGFloat.pi / 2)
}
else if (orientation == .right || orientation == .rightMirrored) {
transform = transform.translatedBy(x: 0, y: size.height)
transform = transform.rotated(by: -(CGFloat.pi / 2))
}
if (orientation == .upMirrored || orientation == .downMirrored) {
transform = transform.translatedBy(x: size.width, y: 0);
transform = transform.scaledBy(x: -1, y: 1)
}
else if (orientation == .leftMirrored || orientation == .rightMirrored) {
transform = transform.translatedBy(x: size.height, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
}
// Now we draw the underlying CGImage into a new context, applying the transform calculated above.
guard let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height),
bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0,
space: cgImage.colorSpace!, bitmapInfo: cgImage.bitmapInfo.rawValue)
else {
return UIImage(cgImage: cgImage, scale: 1, orientation: orientation)
}
ctx.concatenate(transform)
// Create a new UIImage from the drawing context
switch (orientation) {
case .left, .leftMirrored, .right, .rightMirrored:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))
default:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
}
return UIImage(cgImage: ctx.makeImage() ?? cgImage, scale: 1, orientation: .up)
}
}
Usage-1
let newImage = image.byFixingOrientation()
Usage-2 (Fix orientation and resize image to new size)
let newImage = image.byFixingOrientation(andResizingImageToNewSize: CGSize(width: 200, height: 200))
Loading an image is as simple as this line:
Or if you got image data:
And following method will help you to fix the orientation using exif data within
UIImage