CGContextClipToMask不剪辑

时间:2013-07-18 11:16:51

标签: ios objective-c cgcontext clipping

此代码生成下图。据我所知CGContextClipToMask,红色矩形不应该是可见的,因为它在剪切区域之外。我在这里错过了什么?谢谢你的帮助!

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
CGContextFillRect(context, rect);
CGContextSetLineWidth(context, 20);
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);

// draw partial circle
UIBezierPath *arc   = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:NO];
CGContextAddPath(context, [arc CGPath]);
CGContextStrokePath(context);

// create mask
CGImageRef mask = CGBitmapContextCreateImage(context);
self.maskCreated(mask);

// save state
CGContextSaveGState(context);

// clip with mask
CGContextClipToMask(context, rect, mask);

// draw test rect
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, CGRectMake(0, 0, 100, 100));

// restore state
CGContextRestoreGState(context);

Code Result

2 个答案:

答案 0 :(得分:1)

CGContextClipToMask的{​​{3}}说:

  

如果mask是图像,则它必须位于DeviceGray颜色空间中,   可能没有alpha分量,也可能没有被图像掩盖   掩盖或掩盖颜色。

我假设您的代码位于-drawRect:子类的UIView方法中,因此您使用的是提供给您的CGContext,它是RGB格式颜色空间,可能有一个alpha组件。您的mask图像是根据该上下文创建的,因此它具有相同的属性。

要解决此问题,请使用单独的位图上下文来生成蒙版,使用不带alpha的灰色色彩空间。这是一个自包含的示例,它与您的代码类似。

- (void)drawRect:(CGRect)rect
{
    // Create a context for the mask
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
    CGContextRef maskContext = CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, 8, 0, colorSpace, kCGImageAlphaNone | kCGBitmapByteOrderDefault);
    CGColorSpaceRelease(colorSpace);

    // Fill with black
    CGContextSetFillColorWithColor(maskContext, [UIColor blackColor].CGColor);
    CGContextFillRect(maskContext, rect);

    // Draw an arc in white
    CGContextSetLineWidth(maskContext, 20);
    CGContextSetStrokeColorWithColor(maskContext, [UIColor whiteColor].CGColor);
    CGContextAddArc(maskContext, CGRectGetMidX(rect), CGRectGetMidY(rect), 50, M_PI, 0, false);
    CGContextStrokePath(maskContext);

    // Create the mask image from the context, and discard the context
    CGImageRef mask = CGBitmapContextCreateImage(maskContext);
    CGContextRelease(maskContext);

    // Now draw into the view itself
    CGContextRef context = UIGraphicsGetCurrentContext();

    // Apply the mask
    CGContextClipToMask(context, rect, mask);

    // Then draw something that overlaps the mask
    CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
    CGContextFillRect(context, rect);

    // Make sure to clean up when we're done
    CGImageRelease(mask);
}

答案 1 :(得分:0)

实际上不了解您的顾虑,但您可以在方法中隐藏矩形,如下所示:

// draw a test rect             
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);

CGRect rect = CGRectZero;
CGContextFillRect(context, rect);