kCGBlendModeClear 不清除,为啥?

Posted

技术标签:

【中文标题】kCGBlendModeClear 不清除,为啥?【英文标题】:kCGBlendModeClear doesn't clear, why?kCGBlendModeClear 不清除,为什么? 【发布时间】:2010-10-04 17:53:56 【问题描述】:

我正在编写几行代码来熟悉 Quartz 2d 的基础知识。 我正在尝试绘制和图像,然后通过 kCGBlendModeClear 混合模式清除它。这是我的UIView子类代码的代码,通过IB将其背景色设置为橙色:

- (void)drawRect:(CGRect)rect 

    UIImage *brush = [UIImage imageNamed:@"brush.png"] ;
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGContextSetBlendMode(ctx,kCGBlendModeNormal ); 
    CGContextDrawImage(ctx, CGRectMake(100, 100, 26, 25), [brush CGImage]);

    CGContextSetBlendMode(ctx, kCGBlendModeClear);

    CGContextSetFillColorWithColor(ctx, [UIColor clearColor].CGColor);

    CGContextFillEllipseInRect(ctx, CGRectMake(110, 110, 5, 5)); // HERE!

阅读文档和this question 我认为标有 HERE 的线会在我之前绘制的图像中产生一个洞。相反,它会在其上创建一个黑色圆圈(应该是橙色)。

为了调试,我尝试在橙色 uiview 上添加自定义视图。这次我的自定义视图有黑色背景。此处的线孔是正确的,但我想知道为什么视图的黑色。更奇怪的是,如果我执行 myView.backgroundColor,我可以设置背景颜色(这不应该被我的 drawRect 实现覆盖吗?)。

我显然缺少 Quartz 的一些基础知识,有人可以帮忙吗?

大卫

【问题讨论】:

【参考方案1】:

几件事。

首先,Porter-Duff 混合模式只能保证在基于位图的上下文中工作。 (即CGBitmapContextCreate创建的上下文)

其次,kCGBlendModeClear 被定义为R = 0——它甚至不检查 src 或 dst 像素。因此,即使不能保证在这里可以正常工作,但它似乎可以正常工作。

(请参阅CGContext.h 以获得比文档给出的更好的解释。)

【讨论】:

两个子问题:1) 您认为 kCGBlendModeClea 是实现橡胶工具的可行方式吗? 2) 你能告诉我更多关于 R 的事情吗? 1) 不行。R=0 很没用,你甚至不能设置清晰的颜色。 2) 混合模式可以用 R、S 和 D 来表示,其中 S 是源像素,D 是目标像素,R 是结果像素。这为您提供了描述混合模式的便捷简写,例如,R = S + D*(1 - Sa) 表示源过度 (kCGBlendModeNormal) 在从 CGContext.h:84 开始的 cmets 中有很好的解释 谢谢!我猜到 ModeCLear 不是答案,但很高兴得到确认。【参考方案2】:

要使kCGBlendModeClear 正常工作,视图不能不透明,也不能设置背景颜色。

另外,下面这行是不必要的,因为kCGBlendModeClear不关心填充颜色:

CGContextSetFillColorWithColor(ctx, [UIColor clearColor].CGColor);

【讨论】:

以上是关于kCGBlendModeClear 不清除,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

如果我不清除缓存,为啥我的 Flask 应用程序不呈现 CSS?

为啥 NSThread 可以在不创建我自己的 autoreleasepool 的情况下清除自动释放的对象

ASP 清除缓存 为啥要设置Response.Buffer = True

为啥我的清除命令搞砸了?

为啥清除 Derived Data 会清除 Xcode 中的各种错误?

为啥重置表单不会清除绑定的模型属性