1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- //
- // UIImage+Orientation.swift
- // WeScan
- //
- // Created by Boris Emorine on 2/16/18.
- // Copyright © 2018 WeTransfer. All rights reserved.
- //
- import Foundation
- @available(iOS 10, *)
- extension UIImage {
-
- /// Returns the same image with a portrait orientation.
- func applyingPortraitOrientation() -> UIImage {
- switch imageOrientation {
- case .up:
- return rotated(by: Measurement(value: Double.pi, unit: .radians), options: []) ?? self
- case .down:
- return rotated(by: Measurement(value: Double.pi, unit: .radians), options: [.flipOnVerticalAxis, .flipOnHorizontalAxis]) ?? self
- case .left:
- return self
- case .right:
- return rotated(by: Measurement(value: Double.pi / 2.0, unit: .radians), options: []) ?? self
- default:
- return self
- }
- }
-
- /// Data structure to easily express rotation options.
- struct RotationOptions: OptionSet {
- let rawValue: Int
-
- static let flipOnVerticalAxis = RotationOptions(rawValue: 1)
- static let flipOnHorizontalAxis = RotationOptions(rawValue: 2)
- }
-
- /// Rotate the image by the given angle, and perform other transformations based on the passed in options.
- ///
- /// - Parameters:
- /// - rotationAngle: The angle to rotate the image by.
- /// - options: Options to apply to the image.
- /// - Returns: The new image rotated and optentially flipped (@see options).
- func rotated(by rotationAngle: Measurement<UnitAngle>, options: RotationOptions = []) -> UIImage? {
- guard let cgImage = self.cgImage else { return nil }
-
- let rotationInRadians = CGFloat(rotationAngle.converted(to: .radians).value)
- let transform = CGAffineTransform(rotationAngle: rotationInRadians)
- let cgImageSize = CGSize(width: cgImage.width, height: cgImage.height)
- var rect = CGRect(origin: .zero, size: cgImageSize).applying(transform)
- rect.origin = .zero
-
- let format = UIGraphicsImageRendererFormat()
- format.scale = 1
-
- let renderer = UIGraphicsImageRenderer(size: rect.size, format: format)
-
- let image = renderer.image { renderContext in
- renderContext.cgContext.translateBy(x: rect.midX, y: rect.midY)
- renderContext.cgContext.rotate(by: rotationInRadians)
-
- let x = options.contains(.flipOnVerticalAxis) ? -1.0 : 1.0
- let y = options.contains(.flipOnHorizontalAxis) ? 1.0 : -1.0
- renderContext.cgContext.scaleBy(x: CGFloat(x), y: CGFloat(y))
-
- let drawRect = CGRect(origin: CGPoint(x: -cgImageSize.width / 2.0, y: -cgImageSize.height / 2.0), size: cgImageSize)
- renderContext.cgContext.draw(cgImage, in: drawRect)
- }
-
- return image
- }
-
- }
|