iOS CoreGraphics:用半透明图案抚摸会导致颜色损坏

Posted

技术标签:

【中文标题】iOS CoreGraphics:用半透明图案抚摸会导致颜色损坏【英文标题】:iOS CoreGraphics: Stroking with semi-transparent patterns leads to colors corruption 【发布时间】:2011-06-09 14:36:47 【问题描述】:

我的任务是制作类似于擦除工具(用手指操作)的东西,它会显示背景图像而不是已擦除的图像。

这是我的源图片和目标图片(仅供测试,真实的会有所不同):

http://img232.imageshack.us/img232/6030/29572847.png

这是我的代码。创建模式:

- (void)setFrame:(CGRect)frame 
   [super setFrame:frame];
   if(revealPattern) CGPatternRelease(revealPattern);
   CGPatternCallbacks callbacks =  0, &patternCallback, NULL;
   revealPattern = CGPatternCreate(self, self.bounds, CGAffineTransformIdentity, self.bounds.size.width, self.bounds.size.height, kCGPatternTilingConstantSpacing, true, &callbacks);   

模式回调函数(**info* 包含指向self的指针):

void patternCallback(void *info, CGContextRef context) 
   CGRect rect = ((DrawView *)info).bounds;
   CGImageRef imageRef = ((DrawView *)info).backgroundImage.CGImage;
   CGContextTranslateCTM(context, 0, rect.size.height);
   CGContextScaleCTM(context, 1.0, -1.0);
   CGContextDrawImage(context, rect, imageRef);

以及绘制方法:

- (void)drawPoints:(CGContextRef)context
   if([points count] < 2) return;
   CGPoint lastPoint = [[points objectAtIndex: 0] CGPointValue];
   CGContextBeginPath(context);
   CGContextMoveToPoint(context, lastPoint.x, lastPoint.y);

   CGContextSetBlendMode(context, kCGBlendModeNormal);
   CGColorSpaceRef revealPatternSpace = CGColorSpaceCreatePattern(NULL);        
   CGContextSetStrokeColorSpace(context, revealPatternSpace);
   CGFloat revealAlpha = 1.0;
   CGContextSetStrokePattern(context, revealPattern, &revealAlpha);
   CGContextSetAlpha(context, 0.1);
   CGColorSpaceRelease(revealPatternSpace);

   CGContextSetLineCap(context, kCGLineCapRound);
   CGContextSetLineJoin(context, kCGLineJoinRound);
   CGContextSetLineWidth(context, self.lineWidth);
   for(int i = 1; i < [points count]; i++)
       CGPoint currPoint = [[points objectAtIndex: i] CGPointValue];
       CGContextAddLineToPoint(context, currPoint.x, currPoint.y);
       lastPoint = currPoint;
   
   CGContextStrokePath(context);

如果局部变量 revealAlpha 的值为 1.0(如上一段代码所示),则一切正常。 但是我需要擦除是半透明的(这样用户需要在同一个地方刷几次才能完全擦除)。问题就出现在这里。如果我使 revealAlpha 小于 1.0,则显示的目标图像看起来已损坏。

以下是 revealAlpha == 1.0revealAlpha == 0.1 的结果:

http://img593.imageshack.us/img593/1809/69373874.png

如果你看的足够近,你会发现右图的蓝色渐变不再平滑了。

【问题讨论】:

大概,问题在于revealAlpha在某些地方永远不会达到1.0。 (假设问题是多次滑动后,平滑的蓝色渐变从未显露。看来颜色损坏是由于红色图像残留的痕迹造成的......)准确吗? 【参考方案1】:

我同意另一张海报。看起来您的图像没有损坏。相反,看起来您正在使前视图部分可见。作为测试,尝试将revealAlpha 更改为0.5。这样,用手指轻扫一次会将前层的不透明度设置为 50%,第二次轻扫会将其设置为 0%。知道发生了什么会更容易。

【讨论】:

以上是关于iOS CoreGraphics:用半透明图案抚摸会导致颜色损坏的主要内容,如果未能解决你的问题,请参考以下文章

用渐变抚摸 CGPath?

Quartz2D 编程指南变换图案阴影

定制图案铅笔素描图

在具有透明背景的绘制文本上添加图案覆盖

透明背景图案

iOS绘图框架CoreGraphics分析