import UIKit extension UIImage { func scaleAndCropImage(toExampleSize _: CGSize, completion: @escaping (UIImage?) -> Void) { DispatchQueue.global(qos: .background).async { guard let cgImage = self.cgImage else { DispatchQueue.main.async { completion(nil) } return } let contextImage: UIImage = .init(cgImage: cgImage) var contextSize: CGSize = contextImage.size var posX: CGFloat = 0.0 var posY: CGFloat = 0.0 let cgwidth: CGFloat = self.size.width let cgheight: CGFloat = self.size.height // Check and handle if the image is wider than the requested size if contextSize.width > contextSize.height { posX = ((contextSize.width - contextSize.height) / 2) contextSize.width = contextSize.height } else if contextSize.width < contextSize.height { // Check and handle if the image is taller than the requested size posY = ((contextSize.height - contextSize.width) / 2) contextSize.height = contextSize.width } let rect: CGRect = .init(x: posX, y: posY, width: cgwidth, height: cgheight) guard let contextCg = contextImage.cgImage, let imgRef = contextCg.cropping(to: rect) else { DispatchQueue.main.async { completion(nil) } return } let image: UIImage = .init(cgImage: imgRef, scale: self.scale, orientation: self.imageOrientation) DispatchQueue.main.async { completion(image) } } } }