iOS Quartz/CoreGraphics绘制羽毛笔画

use*_*198 7 drawing smooth objective-c quartz-graphics ios

我正在根据从用户收集的一组点绘制一条CGContext路径.似乎有一些随机输入抖动导致一些线边看起来呈锯齿状.我认为轻微的羽毛可以解决这个问题.如果我使用的是OpenGL ES,我会简单地将一个羽毛应用到我正在用这条路径行进的精灵上; 但是,这个项目要求我留在Quartz/CoreGraphics中,我似乎无法找到类似的解决方案.

我尝试绘制5条线,每条线略大,更透明,以接近羽毛.这会产生不良结果并显着降低性能.

这是线条图代码:

CGContextMoveToPoint(UIGraphicsGetCurrentContext(),((int)lastPostionDrawing1.x), (((int)lastPostionDrawing1.y)));
CGContextAddCurveToPoint(UIGraphicsGetCurrentContext(), ctrl1_x, ctrl1_y, ctrl2_x, ctrl2_y, lastPostionDrawing2.x, lastPostionDrawing2.y;
[currentPath addCurveToPoint:CGPointMake(lastPostionDrawing2.x-((int)furthestLeft.x)+((int)penSize), lastPostionDrawing2.y controlPoint1:CGPointMake(ctrl1_x, ctrl1_y) controlPoint2:CGPointMake(ctrl2_x, ctrl2_y)];
Run Code Online (Sandbox Code Playgroud)

ipm*_*mcc 2

我将继续假设您的 CGContext 仍然打开了抗锯齿功能,但如果没有,那么显然首先要尝试,正如@Davyd 的评论所暗示的那样:CGContextSetShouldAntialias是感兴趣的函数。

假设这不是问题,并且线条正在通过上下文消除锯齿,但您仍然想要一些“更柔和”的东西。我可以想出几种方法来做到这一点,希望比抚摸 5 次更快。

首先,您可以尝试获取描边路径(即描述当前路径描边轮廓的路径),然后使用CGContextReplacePathWithStrokedPath渐变填充该路径(或任何其他填充技术给出所需的结果)。这将起作用对于直线来说效果很好,但对于弯曲路径来说就不那么简单了(因为渐变填充了描边路径的区域,并且将是线性的或径向的。)

另一个可能不太明显的选择可能是滥用 CG 的阴影绘制来达到此目的。您要查找的函数是:CGContextSetShadowWithColor 方法如下:

  • 保存 GState:CGContextSaveGState
  • 获取原始路径的边界框
  • 复制路径,使用 2.0 * bbox.width 将其从自身平移CGPathCreateCopyByTransformingPath(注意:仅使用 X 方向,这样您就不必担心上下文中的翻转)
  • 使用以下命令将上下文剪辑到原始 bboxCGContextClipToRect
  • 使用以下命令在上下文上设置阴影CGContextSetShadowWithColor
    • 一些最小的模糊(从 0.5 开始,然后从那里开始。模糊参数是非线性的,IME 是一种猜测和检查操作)
    • 偏移量等于 -2.0 * bbox 宽度和 0.0 高度,缩放到基础空间。(注意:这些偏移量位于基础空间中。弄清楚这一点会让人抓狂,但假设您没有添加自己的比例变换,则比例因子将为 1.0 或 2.0,所以实际上,您将设置一个offset.width 为 -2.0*bbox.width 或 -4.0*bbox.width)
    • 您选择的颜色。
  • 抚摸平移的路径。
  • 弹出 GStateCGContextRestoreGState

这应该会留下“仅”阴影,您可以对其进行调整以获得您想要的结果。

话虽如此,CG 的阴影绘制性能(IME)并不是完全出色,也不是完全确定。我预计它会比用 5 次不同的笔画抚摸路径 5 次要快,但也不是绝对如此。

这将取决于实现这种效果对您来说价值多少。