I'm trying to allow the user to mark an area with her hand and then the image will be cropped to that particular area. The problem is that i've got everything wrong with the cropping sizing, positioning and scaling.
I'm definitely missing something but am not sure what is it that I'm doing wrong? Here is the original image along with the crop rectangle that the user can mark with his finger:
This is the broken outcome:
Here is my custom UIImageView where I intercept the touch events. This is just for the user to draw the rectangle...
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first?.preciseLocation(in: self){
self.newTouch = touch
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let currentPoint = touch.preciseLocation(in: self)
reDrawSelectionArea(fromPoint: newTouch, toPoint: currentPoint)
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.newBoxSelected?(box.frame)
box.frame = CGRect.zero //reset overlay for next tap
}
func reDrawSelectionArea(fromPoint: CGPoint, toPoint: CGPoint) {
//Calculate rect from the original point and last known point
let rect = CGRect(x: min(fromPoint.x, toPoint.x),
y: min(fromPoint.y, toPoint.y),
width: abs(fromPoint.x - toPoint.x),
height: abs(fromPoint.y - toPoint.y));
box.frame = rect
}
This is the actual cropping logic. What am I doing wrong here?
func cropToBounds(image: UIImage, newFrame: CGRect) -> UIImage {
let xScaleFactor = (imageView.image?.size.width)! / (self.imageView.bounds.size.width)
let yScaleFactor = (imageView.image?.size.height)! / (self.imageView.bounds.size.height)
let contextImage: UIImage = UIImage(cgImage: image.cgImage!)
print("NewFrame is: \(newFrame)")
let xPos = newFrame.minX * xScaleFactor
let yPos = newFrame.minY * yScaleFactor
let width = newFrame.size.width * xScaleFactor
let height = newFrame.size.height * xScaleFactor
print("xScaleFactor: \(xScaleFactor)")
print("yScaleFactor: \(yScaleFactor)")
print("xPos: \(xPos)")
print("yPos: \(yPos)")
print("width: \(width)")
print("height: \(height)")
// let rect: CGRect = CGRect(x: xPos, y: yPos , width: width, height: height)
let rect: CGRect = CGRect(x: xPos, y: yPos , width: width, height: height)
// Create bitmap image from context using the rect
let imageRef: CGImage = contextImage.cgImage!.cropping(to: rect)!
// Create a new image based on the imageRef and rotate back to the original orientation
let image: UIImage = UIImage(cgImage: imageRef, scale: image.scale, orientation: image.imageOrientation)
return image
}