-1

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?

Laur
  • 71
  • 1
  • 9
  • There's something else missing in this question, where's the code related to the cropping tool? And how are you doing the crop right now? – Jan Cássio Dec 14 '21 at 18:36
  • That crop tool comes on top of a Camera View - when I am doing the picture I want to save only the selected part. The selection tool (red square) is returning only the Height and Width variables which I suppose to use them in the crop function. Now I am doing the function like I said in the original question, using the cropImage function. – Laur Dec 14 '21 at 18:48
  • If the selection tool is only returning hight and width it won't really work. If you're selecting a rectangle, you need to return a rectangle. Without the origin height and width doesn't give you enough information to know what to crop. – Duncan C Dec 14 '21 at 18:59
  • 1
    Do you mean like https://stackoverflow.com/questions/43720720/how-to-crop-a-uiimageview-to-a-new-uiimage-in-aspect-fill-mode/43720791?r=SearchResults&s=5|34.9765#43720791 ? – matt Dec 14 '21 at 21:20
  • @matt yes, actually that is the case. Now, I have to adapt that solution to SwiftUI approach :) Until now I have the following info: The image, the rectangle thinghy which returns only the height and width and the crop function. – Laur Dec 15 '21 at 03:47

3 Answers3

0

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)
  • Basically, the crop tool comes on top of a full-screen Camera View. When I am doing the picture I want to save only the selected area. – Laur Dec 14 '21 at 18:44
  • ok, try this: let croppedImage = cropImage(image!, toRect: CGRect(x: rect.x , y: rect.y , width: rect.width, height: rect.heigh), viewWidth: UIScreen.main.bounds.width, viewHeight: UIScreen.main.bounds.height) – Alexander Naumenko Dec 14 '21 at 18:54
  • what is the point of the construct `toRect: CGRect(x: rect.x , y: rect.y , width: rect.width, height: rect.height)`? Why not just use `toRect: rect` since you're creating a new CGRect with all the same values as rect? – Duncan C Dec 14 '21 at 20:32
  • Ahah, really! I tried to answer quickly and just replaced the author's "??" in the question :-) – Alexander Naumenko Dec 14 '21 at 21:08
0

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.

Jan Cássio
  • 2,076
  • 29
  • 41
0

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
        
    } 
Laur
  • 71
  • 1
  • 9