Reputation: 376
I've been struggling with this for quite some time now. I'd like to make image cropper similar to the one included in iOS itself when you select your wallpaper. Basically I want the area that user selects cropped from the image with zoom and aspect ratio of the screen (so the user can use the image as a wallpaper later on). Like this:
https://gfycat.com/TornMaleAlligatorsnappingturtle
I've managed to create the interface with UIScrollView and UIImageView:
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
var scrollView: UIScrollView!
var imageView: UIImageView!
var croppedImage: UIImage?
@IBOutlet weak var cropButton: UIButton! {
didSet{
cropButton.backgroundColor = UIColor.gray
}
}
override func viewDidLoad() {
super.viewDidLoad()
let image = UIImage(named: "mountains")!
imageView = UIImageView(image: image)
imageView.frame = CGRect(origin: CGPoint(x: 0, y: 0), size:image.size)
imageView.contentMode = .scaleAspectFill
scrollView = UIScrollView(frame: view.bounds)
scrollView.backgroundColor = UIColor.black
scrollView.contentSize = imageView.bounds.size
scrollView.delegate = self
setZoomScale()
//centerScrollViewContents()
scrollView.addSubview(imageView)
view.addSubview(scrollView)
view.bringSubview(toFront: cropButton)
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
}
@IBAction func crop(_ sender: UIButton) {
let rect = CGRect(x: ?, y: ?, width: ?, height: ?)
let croppedCGImage = imageView.image?.cgImage?.cropping(to: rect)
self.croppedImage = UIImage(cgImage: croppedCGImage!)
}
func setZoomScale() {
let imageViewSize = imageView.bounds.size
let scrollViewSize = scrollView.bounds.size
//let widthScale = scrollViewSize.width / imageViewSize.width
let heightScale = scrollViewSize.height / imageViewSize.height
scrollView.minimumZoomScale = heightScale //min(widthScale, heightScale)
scrollView.maximumZoomScale = 3
scrollView.zoomScale = heightScale
print(heightScale)
}
}.
I can zoom and pan around the image no problem. The problem is I don't know how to create the CGRect rectangle that represents the area that is displayed to the user, which is also the area I want to crop from the original image. Any ideas that will put me out of my misery are greatly appreciated!
Upvotes: 1
Views: 832
Reputation: 904
snapshotImageFromMyView is the output image
self.btn.isHidden = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
UIGraphicsBeginImageContextWithOptions(self.YourView.bounds.size, self.YourView.isOpaque, 0.0)
self.YourView.drawHierarchy(in: self.YourView.bounds, afterScreenUpdates: false)
let snapshotImageFromMyView = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
}
Upvotes: 1