Clipping the current context so that it's masked by a path
core-graphics, ios, objective-c, quartz-graphics
Solution
I might be inclined to build a path as touches come in (I use `UIBezierPath`), and then your custom view can use that path for both clipping the image, as well as for stroking the path around that clipped image:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
if (self.isClipped) {
CGContextAddPath(context, [self.path CGPath]);
CGContextClip(context);
}
[self.image drawInRect:self.bounds];
CGContextRestoreGState(context);
[[UIColor blackColor] setStroke];
self.path.lineWidth = 4.0;
[self.path stroke];
}
If you want to draw the path as touches come in, I personally would render that via a separate `CAShapeLayer` (to avoid the unnecessary redrawing of the image).
Problem
Given a path which is drawn to the context and then converted to a CGImageRef, how would I clip the context (which has a supplied foreground image drawn) to it so that the said context is masked by the CGImage (that previously was a path)? The code in question below should better illustrate my point if it's not totally clear. Note that all of this is called in a UIView's drawRect: method and that the scaledImageRectangle(UIImage *image, CGRect rect) function merely returns a rectangle. ``` // Close the path CGContextClosePath(context); CGContextDrawPath(context, kCGPathFillStroke); // Mask the image CGImageRef mask = CGBitmapContextCreateImage(context); [foregroundImage drawInRect:scaledImageRectangle(foregroundImage, rect)]; CGContextClipToMask(context, scaledImageRectangle(foregroundImage, rect), mask); // Finally draw the masked image UIImage *maskedImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)]; [maskedImage drawInRect:scaledImageRectangle(foregroundImage, rect)]; ``` For example, here is an image with the black stroke representing the path And here is what the image would look like when masked