Image Cropping in Swift

Ashok
3 min readJan 1, 2018

--

Feeling weird while picking an image and cropping in Swift?

Keep reading, and you will find a nice solution to the question above. And if you know a better way, please write your thoughts in comments.

Initial steps —

Step 1: Create your Xcode project.

Step 2: Design storyboard and create outlets and properties in ViewController class.

let picker = UIImagePickerController()
var circlePath = UIBezierPath()
@IBOutlet weak var crop: CropView!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var scroll: UIScrollView!

The property crop has a custom UIView class. Add the below delegate function in it.

func point(inside point: CGPoint, with event:   UIEvent?) -> Bool{
return false
}

Step 3: Create an extension for UIImage and UIImageView — refer. For zooming image, use delegate function viewForZooming, then add UIScrollViewDelegate to class as the subtype and return imageView.

Pick an image from the gallery —

Step 4: Create IBAction, to pick an image from Album and set the picker source type as photo library use the code below:

picker.sourceType = .photoLibrary
present(picker, animated: true, completion: nil)

and add UIImagePickerControllerDelegate to class as sub type. In viewDidLoad:

picker.delegate = self

Use didFinishPickingMediaWithInfo —UIImagePickerControllerDelegate function to set the image to the view after picking image from the album.

let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
imageView.image = chosenImage.resizeImage()
dismiss(animated:true, completion: nil)

To dismiss the photo album when you did cancel, use imagePickerControllerDidCancel delegate.

Shoot a picture from the camera —

Create IBAction to shoot an image from the camera. First, check whether SourceTypeAvailable in the device. If it is set picker camera capture mode as a photo. Else handle the action. Then set source type as camera and camera capture mode as the photo.

if UIImagePickerController.isSourceTypeAvailable(.camera){  
picker.sourceType = UIImagePickerControllerSourceType.camera
picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureMode.photo
picker.modalPresentationStyle = .custom
present(picker,animated: true,completion: nil)
}else{
//action performed if there is no camera in device.
}

That’s it!
Now you can pick an image from the album, as well as from the camera to display in your app for further action.

Cropping —

Add sublayer:

Add subLayer to the picked image — this layer provides an area to fix crop frame.

let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height), cornerRadius: 0)

Assign the path to the circle path property as of type UIBezierPath. Using BezierPath, you can change the crop frame into different shapes.

circlePath = UIBezierPath(roundedRect: CGRect(x: (self.view.frame.size.width / 2) - (size/2), y: (self.view.frame.size.height / 2) - (size / 2), width: size, height: size, cornerRadius: 0)
path.append(circlePath)

The CAShapeLayer that draws a cubic Bezier spline in its coordinate space.

let fillLayer = CAShapeLayer()
fillLayer.path = path.cgPath

Finally, add the layer to view:

view.layer.addSublayer(fillLayer)

Add crop area:

Create a crop area. For that we need to set factor, dividing the imageView image width by view frame width set scale:

let factor = imageView.image!.size.width/view.frame.width

for zooming as scroll zoomScale:

let scale = 1/scroll.zoomScale

Then set crop area frame(x, y, width, height).

let x = (scroll.contentOffset.x + circlePath.bounds.origin.x - imageFrame.origin.x) * scale * factor
let y = (scroll.contentOffset.y + circlePath.bounds.origin.y - imageFrame.origin.y) * scale * factor
let width = circlePath.bounds.width * scale * factor
let height = circlePath.bounds.height * scale * factor

Finally, create a IBAction to crop the image.

let croppedCGImage = imageView.image?.cgImage?.cropping(to: croparea)
let croppedImage = UIImage(cgImage: croppedCGImage!)

Screenshot:

That’s all!!!
Check out the sample project on my Github repo:

“We tend to steer our lives in the direction of the lessons we need to learn.”
- Don Campbell

--

--

Ashok
Ashok

Written by Ashok

 iOS and Flutter developer @TCS, Chennai. Here to share best practices learned through my experience. Reach me on www.linkedin.com/in/ashok1208

Responses (2)