CGContext: how do I erase pixels (e.g. kCGBlendModeClear) outside of a bitmap context?

前端 未结 3 1830
梦毁少年i
梦毁少年i 2021-02-01 09:29

I\'m trying to build an eraser tool using Core Graphics, and I\'m finding it incredibly difficult to make a performant eraser - it all comes down to:

CGContextSetB

3条回答
  •  醉话见心
    2021-02-01 10:32

    I've managed to get good results by using the following code:

    - (void)drawRect:(CGRect)rect
    {
        if (drawingStroke) {
            if (eraseModeOn) {
                CGContextRef context = UIGraphicsGetCurrentContext();
                CGContextBeginTransparencyLayer(context, NULL);
                [eraseImage drawAtPoint:CGPointZero];
    
                CGContextAddPath(context, currentPath);
                CGContextSetLineCap(context, kCGLineCapRound);
                CGContextSetLineWidth(context, ERASE_WIDTH);
                CGContextSetBlendMode(context, kCGBlendModeClear);
                CGContextSetStrokeColorWithColor(context, [[UIColor clearColor] CGColor]);
                CGContextStrokePath(context);
                CGContextEndTransparencyLayer(context);
            } else {
                [curImage drawAtPoint:CGPointZero];
                CGContextRef context = UIGraphicsGetCurrentContext();
                CGContextAddPath(context, currentPath);
                CGContextSetLineCap(context, kCGLineCapRound);
                CGContextSetLineWidth(context, self.lineWidth);
                CGContextSetBlendMode(context, kCGBlendModeNormal);
                CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
                CGContextStrokePath(context);
            }
        } else {
            [curImage drawAtPoint:CGPointZero];
        }
    
        self.empty = NO;
    }
    

    The trick was to wrap the following into CGContextBeginTransparencyLayer / CGContextEndTransparencyLayer calls:

    • Blitting the erase background image to the context
    • Drawing the "erase" path on top of the erase background image, using kCGBlendModeClear

    Since both the erase background image's pixel data and the erase path are in the same layer, it has the effect of clearing the pixels.

提交回复
热议问题