0

I need to crop the centre portion of an image to a rectangle of height 200 and width 250. There is no scroll view.

In all the solutions I found, there is a calculation like,

let scale = image.size.width / imageView.frame.width

and then multiplying x, y, height and width of the rect with the scale, before passing it to the cropping(to:) method, which will convert the rect from UIKit coordinates to core graphics coordinates.

My problem is, after doing these conversions and converting it to a UIImage, the cropped area is not the expected one.

I also tried,

let scale = max(image.size.width / imageView.frame.width, image.size.height / imageView.frame.height)

Still the resulting cropped area is off by around 100 points in the x and y axes. What am I missing here? Is there any additional calculation required?

sanjay
  • 31
  • 5
  • Do you want to **scale** the image? Or just clip out a 250x200 rectangle from the center of the image? – DonMag Sep 10 '20 at 19:00
  • Yeah just need to clip the rect from the centre, while keeping the scale and orientation of the image same. – sanjay Sep 10 '20 at 19:11

1 Answers1

0

There are a good set of UIImage extension funcs here: https://stackoverflow.com/a/28513086/6257435

Add this to that extension to clip a rect of clipSize from the center:

func clipFromCenter(clipSize: CGSize) -> UIImage? {
    var r: CGRect = CGRect(origin: .zero, size: clipSize)
    r.origin.x = (size.width - clipSize.width) * 0.5
    r.origin.y = (size.height - clipSize.height) * 0.5
    return cropped(to: r)
}

So...

if let img = UIImage(named: "bkg") {
    if let centerImg = img.clipFromCenter(clipSize: CGSize(width: 250, height: 200))
        // do what you want with the new UIImage
    }
}
DonMag
  • 69,424
  • 5
  • 50
  • 86
  • @sanjay - no... if you review the answer I linked to you'll see it is using `UIGraphicsImageRenderer` – DonMag Sep 10 '20 at 19:42
  • It seems the linked answer expects the bounds to be converted to core graphics coordinates, which is actually the trouble I'm facing. If I pass in the rect.frame, its cropping some other part of the image. – sanjay Sep 10 '20 at 20:02
  • @sanjay - that's confusing... Why would you be passing `rect.frame` anywhere? You have a `UIImage`, and you want the center `250x200` portion of it. What `frame` are you talking about? – DonMag Sep 10 '20 at 20:25
  • I was referring to the linked answer. The method requires a CGRect as parameter. With the answer you posted, I'm assuming the clipFromCenter function is supposed to be an extension for UIImage. But, cropped(to:) is a CIImage method. I tried converting to both CGImage and CIImage before cropping, but both are not giving the correct cropped image. – sanjay Sep 10 '20 at 20:34
  • @sanjay - here is a complete implementation: https://pastebin.com/wi4qymkz .. I'm not posting all of the code in my answer, as it's not my code and already exists as an answer here on Stack Overflow. – DonMag Sep 10 '20 at 20:46