Drawing UIImage mask with GestureRecognizer

2019-04-15 16:09发布

问题:

I'm trying to combine 2 mechanisms and I'm not getting very far on finding a solution. This is what I want to be able to do :-

I have a routine that allows me to draw a mask on a UIImage layer which has a 2nd UIImage below which contains the image I am drawing the mask on top of. This seems to work fine and when I'm fininihed I just combine to 2 layers which then apply the mask and the image looks 'cut-out'.

The problem is I want to be able to zoom, pan the mask and the image to be able to apply a more accurate mask in the zoomed mode. Part of the app uses GestureRecognizers to move an image for taking screenshots so thought I could just combine the mask drawing with the Gesture routine. This is where I get lost and it doesn't work.

Mask drawing routine

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    swiped = false
    if let touch = touches.first as? UITouch {
        lastPoint = touch.locationInView(self.view)
    }
}

func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) {

    UIGraphicsBeginImageContext(tempImageView.frame.size)
    let context = UIGraphicsGetCurrentContext()
    tempImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height))

    CGContextMoveToPoint(context, fromPoint.x, fromPoint.y)
    CGContextAddLineToPoint(context, toPoint.x, toPoint.y)


    CGContextSetLineCap(context, kCGLineCapRound)
    CGContextSetLineWidth(context, brushWidth)
    CGContextSetRGBStrokeColor(context, 1.0, 0.0, 1.0, opacity)

    if maskSwitch == 1 {
        CGContextSetBlendMode(context, kCGBlendModeClear)
    } else {
        CGContextSetBlendMode(context, kCGBlendModeNormal)
    }

    CGContextStrokePath(context)

    tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
    tempImageView.alpha = opacity
    UIGraphicsEndImageContext()
}

override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
    swiped = true
    if let touch = touches.first as? UITouch {
        let currentPoint = touch.locationInView(self.view)
        drawLineFrom(lastPoint, toPoint: currentPoint)
        lastPoint = currentPoint
    }
}


override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
    if !swiped {
        // draw a single point
        drawLineFrom(lastPoint, toPoint: lastPoint)
    }
}

Gesture recognizer routine

@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
    let translation = recognizer.translationInView(self.view)
    recognizer.view!.center = CGPoint(x:recognizer.view!.center.x + translation.x,
        y:recognizer.view!.center.y + translation.y)
    recognizer.setTranslation(CGPointZero, inView: self.view)
}

func gestureRecognizer(UIGestureRecognizer,
    shouldRecognizeSimultaneouslyWithGestureRecognizer:UIGestureRecognizer) -> Bool {
        return true
}

@IBAction func handlePinch(recognizer : UIPinchGestureRecognizer) {
    recognizer.view!.transform = CGAffineTransformScale(recognizer.view!.transform,
        recognizer.scale, recognizer.scale)
    recognizer.scale = 1
}

@IBAction func handleRotate(recognizer : UIRotationGestureRecognizer) {
    recognizer.view!.transform = CGAffineTransformRotate(recognizer.view!.transform, recognizer.rotation)
    recognizer.rotation = 0
}

Not sure if this is relevant but here's the routine for applying the mask

 func maskImage(image:UIImage,maskImage:UIImage)-> UIImage{

        var maskRef:CGImageRef = maskImage.CGImage
        var mask:CGImageRef = CGImageMaskCreate(CGImageGetWidth(maskRef), CGImageGetHeight(maskRef), CGImageGetBitsPerComponent(maskRef), CGImageGetBitsPerPixel(maskRef), CGImageGetBytesPerRow(maskRef), CGImageGetDataProvider(maskRef), nil, true)
        var masked:CGImageRef = CGImageCreateWithMask(image.CGImage, mask)

        return UIImage(CGImage: masked)!
    }

Any help on this would be great.

Thanks, Anthony