Created
August 2, 2019 07:15
-
-
Save yhirano/83c5f709b71559e37de0a051040245b9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import UIKit | |
| extension UIImage { | |
| func fixedOrientation() -> UIImage? { | |
| guard imageOrientation != UIImage.Orientation.up else { | |
| return self | |
| } | |
| guard let cgImage = self.cgImage else { | |
| return nil | |
| } | |
| guard let colorSpace = cgImage.colorSpace, | |
| let ctx = CGContext(data: nil, | |
| width: Int(size.width), | |
| height: Int(size.height), | |
| bitsPerComponent: cgImage.bitsPerComponent, | |
| bytesPerRow: 0, | |
| space: colorSpace, | |
| bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else { | |
| return nil | |
| } | |
| var transform: CGAffineTransform = CGAffineTransform.identity | |
| switch imageOrientation { | |
| case .down, .downMirrored: | |
| transform = transform.translatedBy(x: size.width, y: size.height) | |
| transform = transform.rotated(by: CGFloat.pi) | |
| case .left, .leftMirrored: | |
| transform = transform.translatedBy(x: size.width, y: 0) | |
| transform = transform.rotated(by: CGFloat.pi / 2.0) | |
| case .right, .rightMirrored: | |
| transform = transform.translatedBy(x: 0, y: size.height) | |
| transform = transform.rotated(by: CGFloat.pi / -2.0) | |
| case .up, .upMirrored: | |
| break | |
| } | |
| switch imageOrientation { | |
| case .upMirrored, .downMirrored: | |
| transform = transform.translatedBy(x: size.width, y: 0) | |
| transform = transform.scaledBy(x: -1, y: 1) | |
| case .leftMirrored, .rightMirrored: | |
| transform = transform.translatedBy(x: size.height, y: 0) | |
| transform = transform.scaledBy(x: -1, y: 1) | |
| case .up, .down, .left, .right: | |
| break | |
| } | |
| ctx.concatenate(transform) | |
| switch imageOrientation { | |
| case .left, .leftMirrored, .right, .rightMirrored: | |
| ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.height, height: size.width)) | |
| default: | |
| ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) | |
| } | |
| guard let newCGImage = ctx.makeImage() else { return nil } | |
| return UIImage.init(cgImage: newCGImage, scale: 1, orientation: .up) | |
| } | |
| func crop(to size: CGSize) -> UIImage? { | |
| guard let image = fixedOrientation() else { return nil } | |
| guard let cgImage = image.cgImage else { return nil } | |
| let contextImage = UIImage(cgImage: cgImage) | |
| let contextSize = contextImage.size | |
| var positionX: CGFloat = 0.0 | |
| var positionY: CGFloat = 0.0 | |
| let cropAspect: CGFloat = size.width / size.height | |
| var cropWidth: CGFloat = size.width | |
| var cropHeight: CGFloat = size.height | |
| if size.width > size.height { // Landscape | |
| cropWidth = contextSize.width | |
| cropHeight = contextSize.width / cropAspect | |
| positionY = (contextSize.height - cropHeight) / 2 | |
| } else if size.width < size.height { // Portrait | |
| cropHeight = contextSize.height | |
| cropWidth = contextSize.height * cropAspect | |
| positionX = (contextSize.width - cropWidth) / 2 | |
| } else { // Square | |
| if contextSize.width >= contextSize.height { // Square on landscape (or square) | |
| cropHeight = contextSize.height | |
| cropWidth = contextSize.height * cropAspect | |
| positionX = (contextSize.width - cropWidth) / 2 | |
| } else { // Square on portrait | |
| cropWidth = contextSize.width | |
| cropHeight = contextSize.width / cropAspect | |
| positionY = (contextSize.height - cropHeight) / 2 | |
| } | |
| } | |
| let rect = CGRect(x: positionX, y: positionY, width: cropWidth, height: cropHeight) | |
| // Create bitmap image from context using the rect | |
| let imageRef = contextImage.cgImage!.cropping(to: rect)! | |
| // Create a new image based on the imageRef and rotate back to the original orientation | |
| let cropped = UIImage(cgImage: imageRef, scale: image.scale, orientation: image.imageOrientation) | |
| cropped.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) | |
| return cropped | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment