// usage: class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() if let img = UIImage(named: "bkg") { if let centerImg = img.clipFromCenter(clipSize: CGSize(width: 250, height: 200)) // do what you want with the new UIImage } } } } // extension - see DonMag added: // func clipFromCenter(clipSize: CGSize) -> UIImage? // at end // // from: https://stackoverflow.com/a/28513086/6257435 extension UIImage { /// Resize the image to be the required size, stretching it as needed. /// /// - parameter newSize: The new size of the image. /// - parameter contentMode: The `UIView.ContentMode` to be applied when resizing image. /// Either `.scaleToFill`, `.scaleAspectFill`, or `.scaleAspectFit`. /// /// - returns: Return `UIImage` of resized image. func scaled(to newSize: CGSize, contentMode: UIView.ContentMode = .scaleToFill) -> UIImage? { switch contentMode { case .scaleToFill: return filled(to: newSize) case .scaleAspectFill, .scaleAspectFit: let horizontalRatio = size.width / newSize.width let verticalRatio = size.height / newSize.height let ratio: CGFloat! if contentMode == .scaleAspectFill { ratio = min(horizontalRatio, verticalRatio) } else { ratio = max(horizontalRatio, verticalRatio) } let sizeForAspectScale = CGSize(width: size.width / ratio, height: size.height / ratio) let image = filled(to: sizeForAspectScale) let doesAspectFitNeedCropping = contentMode == .scaleAspectFit && (newSize.width > sizeForAspectScale.width || newSize.height > sizeForAspectScale.height) if contentMode == .scaleAspectFill || doesAspectFitNeedCropping { let subRect = CGRect( x: floor((sizeForAspectScale.width - newSize.width) / 2.0), y: floor((sizeForAspectScale.height - newSize.height) / 2.0), width: newSize.width, height: newSize.height) return image?.cropped(to: subRect) } return image default: return nil } } /// Resize the image to be the required size, stretching it as needed. /// /// - parameter newSize: The new size of the image. /// /// - returns: Resized `UIImage` of resized image. func filled(to newSize: CGSize) -> UIImage? { let format = UIGraphicsImageRendererFormat() format.opaque = false format.scale = scale return UIGraphicsImageRenderer(size: newSize, format: format).image { _ in draw(in: CGRect(origin: .zero, size: newSize)) } } /// Crop the image to be the required size. /// /// - parameter bounds: The bounds to which the new image should be cropped. /// /// - returns: Cropped `UIImage`. func cropped(to bounds: CGRect) -> UIImage? { // if bounds is entirely within image, do simple CGImage `cropping` ... if CGRect(origin: .zero, size: size).contains(bounds), imageOrientation == .up, let cgImage = cgImage { return cgImage.cropping(to: bounds * scale).flatMap { UIImage(cgImage: $0, scale: scale, orientation: imageOrientation) } } // ... otherwise, manually render whole image, only drawing what we need let format = UIGraphicsImageRendererFormat() format.opaque = false format.scale = scale return UIGraphicsImageRenderer(size: bounds.size, format: format).image { _ in let origin = CGPoint(x: -bounds.minX, y: -bounds.minY) draw(in: CGRect(origin: origin, size: size)) } } /// Resize the image to fill the rectange of the specified size, preserving the aspect ratio, trimming if needed. /// /// - parameter newSize: The new size of the image. /// /// - returns: Return `UIImage` of resized image. func scaledAspectFill(to newSize: CGSize) -> UIImage? { return scaled(to: newSize, contentMode: .scaleAspectFill) } /// Resize the image to fit within the required size, preserving the aspect ratio, with no trimming taking place. /// /// - parameter newSize: The new size of the image. /// /// - returns: Return `UIImage` of resized image. func scaledAspectFit(to newSize: CGSize) -> UIImage? { return scaled(to: newSize, contentMode: .scaleAspectFit) } // MARK: DonMag added func clipFromCenter(clipSize: CGSize) -> UIImage? { var r: CGRect = CGRect(origin: .zero, size: clipSize) r.origin.x = (size.width - clipSize.width) * 0.5 r.origin.y = (size.height - clipSize.height) * 0.5 return cropped(to: r) } } extension CGSize { static func * (lhs: CGSize, rhs: CGFloat) -> CGSize { return CGSize(width: lhs.width * rhs, height: lhs.height * rhs) } } extension CGPoint { static func * (lhs: CGPoint, rhs: CGFloat) -> CGPoint { return CGPoint(x: lhs.x * rhs, y: lhs.y * rhs) } } extension CGRect { static func * (lhs: CGRect, rhs: CGFloat) -> CGRect { return CGRect(origin: lhs.origin * rhs, size: lhs.size * rhs) } }