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