2

此代码产生下图。据我了解 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);

代码结果

4

2 回答 2

1

文档CGContextClipToMask说:

如果 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);
}
于 2016-01-23T22:50:32.023 回答
0

实际上不了解您的担忧,但是您可以像这样在方法中隐藏矩形:

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

CGRect rect = CGRectZero;
CGContextFillRect(context, rect);
于 2013-07-18T12:38:42.610 回答