Q:

Crop UIImage to square portion

I have a UIScrollView which contains a UIImage. On top of that is a box that the user can move the image, so that that portion is cropped.
This screenshot explains it better:

So they can scroll the image around until the portion they want is inside that box.
I then want to be able to crop the scrollView/UIImage to exactly that size and store the cropped image.
It shouldn't be very hard but I've spent ages trying screenshots, UIGraphicsContext, etc. and cant seem to get anything to work.
Thanks for the help.

A:

I finally figured out how to get it to work. Here is the code:
func croppedImage() -> UIImage {

    let cropSize = CGSize(width: 280, height: 280)
    let scale = (imageView.image?.size.height)! / imageView.frame.height
    let cropSizeScaled = CGSize(width: cropSize.width * scale, height: cropSize.height * scale)

    if #available(iOS 10.0, *) {
        let r = UIGraphicsImageRenderer(size: cropSizeScaled)
        let x = -scrollView.contentOffset.x * scale
        let y = -scrollView.contentOffset.y * scale
        return r.image { _ in
            imageView.image!.draw(at: CGPoint(x: x, y: y))
        }
    } else {
        return UIImage()
    }

}

So it first calculates the scale of the imageView and the actual image.
Then it creates a CGSize of that crop box as shown in the photo. However, the width and height must be scaled by the scale factor. (e.g. 280 * 6.5)
You must check if the phone is running iOS 10.0 for UIGraphicsImageRender - if not, it won't work.
Initialise this with the crop box size.
The image must then be offset, and this is calculated by getting the scrollView's content offset, negating it, and multiplying by the scale factor.
Then return the image drawn at that point!

