I need some help with a function that I'd like to implement in my app.
I have a view with an image view with content mode in Aspect Fit. When I get an image from my library I would like to crop an area with an adjustable rectangle creating a new image.
I've looked for some exemple or online tutorial but I did not succeed.
Can anyone help me with that?
Here are the images from my View.
.
The simple solution is to just render the image view within a particular CGRect
:
func snapshot(in imageView: UIImageView, rect: CGRect) -> UIImage {
return UIGraphicsImageRenderer(bounds: rect).image { _ in
imageView.drawHierarchy(in: imageView.bounds, afterScreenUpdates: true)
}
}
The limitation of that approach is that if the image is a considerably higher resolution than the image view could render (as is often the case when we use “aspect scale fit”), you’ll lose this additional precision.
If you want to preserve the resolution, you should convert the CGRect
to coordinates with the image, in this case, assuming “aspect scale fit” (namely, centered and scaled so the whole image is shown):
func snapshot(in imageView: UIImageView, rect: CGRect) -> UIImage {
assert(imageView.contentMode == .scaleAspectFit)
let image = imageView.image!
// figure out what the scale is
let imageRatio = imageView.bounds.width / imageView.bounds.height
let imageViewRatio = image.size.width / image.size.height
let scale: CGFloat
if imageRatio > imageViewRatio {
scale = image.size.height / imageView.bounds.height
} else {
scale = image.size.width / imageView.bounds.width
}
// convert the `rect` into coordinates within the image, itself
let size = rect.size * scale
let origin = CGPoint(x: image.size.width / 2 - (imageView.bounds.midX - rect.minX) * scale,
y: image.size.height / 2 - (imageView.bounds.midY - rect.minY) * scale)
let scaledRect = CGRect(origin: origin, size: size)
// now render the image and grab the appropriate rectangle within
// the image’s coordinate system
let format = UIGraphicsImageRendererFormat()
format.scale = image.scale
format.opaque = false
return UIGraphicsImageRenderer(bounds: scaledRect, format: format).image { _ in
image.draw(at: .zero)
}
}
Using this extension:
extension CGSize {
static func * (lhs: CGSize, rhs: CGFloat) -> CGSize {
return CGSize(width: lhs.width * rhs, height: lhs.height * rhs)
}
}
That yields:
If I understand your question correctly there are two parts to your question:
- An adjustable rectangle area over the image
- Crop an
UIImage
Break your google query and search for solution based on the above questions separately.
Or probably take help or use something like this:
iOS-Image-Crop-View