I am first drawing a rectangle on the screen with "UITouch". Afterwards i am taking a screenshot of the whole screen and attempting to crop the image with the positioning of the drawn rectangle.
All my attempts crop the image in an incorrect position. What am i missing? How can this be achieved?
1: Drawing a rectangle and storing the drawn position as global variables.
func drawSelectionArea(fromPoint: CGPoint, toPoint: CGPoint) {
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));
overlay.frame = rect
xCurrent = min(fromPoint.x, toPoint.x)
yCurrent = min(fromPoint.y, toPoint.y)
widthCurrent = abs(fromPoint.x - toPoint.x)
heightCurrent = abs(fromPoint.y - toPoint.y)
}
2: Taking a screenshot of the whole screen.
@IBAction func createScreenshot(_ sender: Any) {
let imageSize = UIScreen.main.bounds.size as CGSize;
UIGraphicsBeginImageContextWithOptions(imageSize, false, 0)
let context = UIGraphicsGetCurrentContext()
for obj : AnyObject in UIApplication.shared.windows {
if let window = obj as? UIWindow {
if window.responds(to: #selector(getter: UIWindow.screen)) || window.screen == UIScreen.main {
context!.saveGState();
context!.translateBy(x: window.center.x, y: window.center.y);
context!.concatenate(window.transform);
context!.translateBy(x: -window.bounds.size.width * window.layer.anchorPoint.x,
y: -window.bounds.size.height * window.layer.anchorPoint.y);
window.layer.render(in: context!)
context!.restoreGState();
}
}
}
let imageContext = UIGraphicsGetImageFromCurrentImageContext();
let image = self.cropImage(screenshot: imageContext!)
}
3: Attempting to crop the screenshot with the same positioning as the drawn rectangle.
func cropImage(screenshot: UIImage) -> UIImage {
let crop = CGRectMake(self.xCurrent, self.yCurrent,
self.widthCurrent,
self.heightCurrent)
let cgImage = screenshot.cgImage!.cropping(to: crop)
let image: UIImage = UIImage(cgImage: cgImage!)
return image
}
You should be able to get rid of almost all of that code...
Try replacing your func with this:
Edit - based on comments...
OK, as I understand your goal now, you want to
presenta view controller (over current context) with a clear background. That controller will have the "drawable" overlay view to define the area to capture ... along with, I'm assuming, a "Capture" button.You can still use the above code - but you'll want to get a reference to the
viewfrom the controller thatpresentedthe overlay-view controller:Here's a quick example...
We'll start with a view controller containing a button and a "grid" of labels:
This is the controller we will present, where the user can define the capture area (for this example, not "sizable" ... just a draggable view):
and a view controller to display the resulting
UIImage:It will look like this on launch:
Tapping "Present Capture VC" will look like this (capture area starts centered):
Here I've dragged the rect to the lower-right:
and tapping "Capture" will display the captured
UIImage: