Overview Of Cropping Image :-
In this blog, we are going to implement of “Cropping Image”
Crop an image Using specific aspect ratio
This tutorial on following steps so that it will be easy for you to understand.
- A Image Zoom and Scrolling.
- Calculate the frame of image inside the image view (UIImageView).
- Calculate the frame of crop area with respect ratio of the actual image size.
- Image to Cropping.
Create a Image Zoom and Scroll
First start, creating a ViewController. Go to your storyboard file and drag a new UIViewController from the Object Library on the top right corner of XCode.
Now drag a ScrollView on ViewController and adjust the frames of ScrollView to the edge of ViewController and drag a ImageView under the ScrollView and adjust the frame of ImageView to the edge of ScrollView.
To add all the missing constraints, simply go the bottom right corner of the storyboard and click on Add Missing Constraints to All Views.

You can set an image on ImageView from ImageAsset. However, in the future, you may want to retrieve an image from the camera, photo library, or another source and set it to ImageView instead. Additionally, make sure to set the content mode to Aspect Fit for proper display.

Begin by creating outlets for ScrollView and ImageView, and then set the delegate, minimum zoom scale, and maximum zoom scale of the ScrollView.
class ImageCropperViewController: UIViewController,UIScrollViewDelegate {
@IBOutlet var scrollView: UIScrollView!{
didSet{
scrollView.delegate = self
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 10.0
}
}
@IBOutlet var imageView: UIImageView!
}
Finally, it’s necessary to implement a UIScrollViewDelegate function that will return the view to be scaled. In this case, we should return the ImageView.
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
}
Calculate the frame of image inside the image view (UIImageView).
If the content mode of the ImageView is set to Aspect Fit, the image may not fill all the available space of the ImageView, resulting in the frame of the image being unequal to its bounds. To address this issue, we can create an extension of the UIImageView class and write a function that calculates the frame of the image within the ImageView.
extension UIImageView{
func imageFrame()->CGRect{
let imageViewSize = self.frame.size
guard let imageSize = self.image?.size else{return CGRect.zero}
let imageRatio = imageSize.width / imageSize.height
let imageViewRatio = imageViewSize.width / imageViewSize.height
if imageRatio < imageViewRatio {
let scaleFactor = imageViewSize.height / imageSize.height
let width = imageSize.width * scaleFactor
let topLeftX = (imageViewSize.width - width) * 0.5
return CGRect(x: topLeftX, y: 0, width: width, height: imageViewSize.height)
}else{
let scalFactor = imageViewSize.width / imageSize.width
let height = imageSize.height * scalFactor
let topLeftY = (imageViewSize.height - height) * 0.5
return CGRect(x: 0, y: topLeftY, width: imageViewSize.width, height: height)
}
}
}
Calculate the frame of crop area with respect ratio of the actual image size.
To define a cropping area, we can create another view in our ViewController and place it on the same hierarchy level as ScrollView. You can choose to make the whole screen or a specific area the cropping area.
To define the cropping area, add constraints such as Leading, Trailing, Vertically Center, and Aspect Ratio to the View. The constraints can be adjusted based on your specific requirements. In this case, we have set the Leading, Trailing, and Vertically Center constants to 0 and the aspect ratio constant to 16:9. Additionally, decrease the alpha value of the View so that the user can see through it.

If you run the application and check, you will notice that you cannot zoom through the View we just placed to define the crop area. To overcome this issue, we can create a custom UIView that will pass the touch to the view underneath.
class CropAreaView: UIView {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return false
}
}
To use the custom UIView we just created, set the class of the View in the Storyboard to the custom class.
Once we have successfully defined the crop area on the screen, we need to map that area to the actual image.
First, create a outlet of the View.
@IBOutlet var cropAreaView: CropAreaView!
To accomplish this, we need to define a computed variable that returns the frame of the cropping area with respect to the actual image.
var cropArea:CGRect{
get{
let factor = imageView.image!.size.width/view.frame.width
let scale = 1/scrollView.zoomScale
let imageFrame = imageView.imageFrame()
let x = (scrollView.contentOffset.x + cropAreaView.frame.origin.x - imageFrame.origin.x) * scale * factor
let y = (scrollView.contentOffset.y + cropAreaView.frame.origin.y - imageFrame.origin.y) * scale * factor
let width = cropAreaView.frame.size.width * scale * factor
let height = cropAreaView.frame.size.height * scale * factor
return CGRect(x: x, y: y, width: width, height: height)
}
}
Image to Cropping
Adding a button to trigger the cropping process is the easiest task among all the tasks we have accomplished so far. Simply drag a button onto the ViewController and ensure that the button is placed on the same hierarchy level as ScrollView and CropView. Additionally, add the Bottom Space and Horizontally Center constraints to the button.

finally create action of the button and crop the image.
@IBAction func crop(_ sender: UIButton) {
let croppedCGImage = imageView.image?.cgImage?.cropping(to: cropArea)
let croppedImage = UIImage(cgImage: croppedCGImage!)
imageView.image = croppedImage
}
If you run the application and crop the image, the image will be cropped successfully. However, there is one issue: the cropped image will be displayed with the previous zoom level. To fix this issue, we need to reset the zoom level of the ScrollView.
scrollView.zoomScale = 1