How can I use CGRect() dynamically?

650 Views Asked by At

I have the following scene example where I can crop an image based on the selection (red square).

That square has dynamic Height and Width - base on this fact I want to use the selected Height and Width to crop what is inside of the Red square.

The function that I am using for cropping is from Apple developer and looks like this:

func cropImage(_ inputImage: UIImage, toRect cropRect: CGRect, viewWidth: CGFloat, viewHeight: CGFloat) -> UIImage? 
{    
    let imageViewScale = max(inputImage.size.width / viewWidth,
                             inputImage.size.height / viewHeight)

    // Scale cropRect to handle images larger than shown-on-screen size
    let cropZone = CGRect(x:cropRect.origin.x * imageViewScale,
                          y:cropRect.origin.y * imageViewScale,
                          width:cropRect.size.width * imageViewScale,
                          height:cropRect.size.height * imageViewScale)

    // Perform cropping in Core Graphics
    guard let cutImageRef: CGImage = inputImage.cgImage?.cropping(to:cropZone)
    else {
        return nil
    }

    // Return image to UIImage
    let croppedImage: UIImage = UIImage(cgImage: cutImageRef)
    return croppedImage
}

Now. I want to use the given Height and Width to crop that selection.

 let croppedImage =  cropImage(image!, toRect: CGRect(x:?? , y:?? , width: ??, height: ??), viewWidth: ??, viewHeight: ??) 

What should I fill in these parameters in order to crop the image based on the above dynamic selection?

3

There are 3 best solutions below

0
Laur On BEST ANSWER

I've used the info from all of your answers and especially @matt's comment and this is the final solution.

Using the input values that my red square returned, I've adapted the original Crop function to this one:

    func cropImage(_ inputImage: UIImage, width: Double, height: Double) -> UIImage?
    {

        let imsize = inputImage.size
        let ivsize = UIScreen.main.bounds.size
        
        var scale : CGFloat = ivsize.width / imsize.width
        if imsize.height * scale < ivsize.height {
            scale = ivsize.height / imsize.height
        }

        let croppedImsize = CGSize(width:height/scale, height:width/scale)

        
        let croppedImrect =
            CGRect(origin: CGPoint(x: (imsize.width-croppedImsize.width)/2.0,
                                   y: (imsize.height-croppedImsize.height)/2.4),
                   size: croppedImsize)
        
        let r = UIGraphicsImageRenderer(size:croppedImsize)
        let croppedIm = r.image { _ in
            inputImage.draw(at: CGPoint(x:-croppedImrect.origin.x, y:-croppedImrect.origin.y))
        }
        
        return croppedIm
        
    } 
4
Alexander Naumenko On

Ok, let's assume that your image is in imageView, wich is located somewhere in your screen. The rect is a variable where your selected frame (related to the imageView.frame) is stored. So the result is:

let croppedImage =  cropImage(image!, toRect: rect, viewWidth: imageView.width, viewHeight: imageView.height)
0
Jan Cássio On

Ok, since you just have info of width and height of the cropping shape. You'll need to calculate the x and y by yourself.

First, let's consider these information:

// let's pretend this is a sample of size that your crop tool provides to you
let cropSize = CGSize(width: 120, height: 260)

Next, you'll need to obtain the display size (width and height) of your image. Display size here is the frame's size of your image, not the size of the image itself.

// again, lets pretend it's just a frame size of your image
let imageSize = CGSize(width: 320, height: 480)

With this info, you can obtain the x and y necessary to compose a CGRect and then, provide to a cropping function you desire.

let x = (imageSize.width - cropSize.width) / 2
let y = (imageSize.height - cropSize.height) / 2

So now, you can create a rectangle to crop your image like this:

let cropRect = CGRect(x: x, y: y, width: cropSize.width, height: cropSize.height)

With cropRect you can use on both cropping or cropImage functions mentioned in your question.