Iphone 如何从CATiledLayer中删除这些旋转伪影?

Iphone 如何从CATiledLayer中删除这些旋转伪影?,iphone,cocoa-touch,quartz-graphics,catiledlayer,Iphone,Cocoa Touch,Quartz Graphics,Catiledlayer,我有一个CATiledLayer,我使用以下方法将内容渲染到其中 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx 我使用QuartzDemo代码绘制了一个模式。在我将旋转变换应用于层的父层(UIView)之前,这非常有效: 轮换: 当我开始在CATiledLayer中绘制线条和文字时,这些锯齿形的人工制品会变得更糟 我按如下方式应用了变换(我还尝试在视图本身上使用仿射变换): 我转换containerView而不

我有一个CATiledLayer,我使用以下方法将内容渲染到其中

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
我使用QuartzDemo代码绘制了一个模式。在我将旋转变换应用于层的父层(UIView)之前,这非常有效:

轮换:

当我开始在CATiledLayer中绘制线条和文字时,这些锯齿形的人工制品会变得更糟

我按如下方式应用了变换(我还尝试在视图本身上使用仿射变换):

我转换containerView而不是层本身,因为我在视图中有几个层,我希望在不改变相对位置的情况下同时旋转它们

我过去在旋转视图时没有问题

有没有一种方法可以旋转CATiledLayer而不出现这些问题

任何帮助都将不胜感激

你的


Felix

正如Ryan Zachry已经指出的,反走样将在这里帮助您。您在这里体验的效果是“楼梯”效果

像素是正方形的,因此很容易画直线(水平或垂直),而不会产生任何瑕疵。如果以一定角度绘制线,则需要栅格化线。线条绘制算法在尝试将线条映射到像素时需要进行近似。这种算法的一个例子是(非常流行且易于实现,但不具有抗锯齿功能)。 它的作用如下:

正如您在这张图片中可以非常清楚地看到的,以任何角度绘制直线会产生所谓的楼梯效果。要避免这种效果,可以使用抗锯齿。抗混叠实际上是信号理论的一部分。当以较低的分辨率表示高分辨率信号时,这是一种最小化失真伪影(称为混叠)的技术。从上面的线条示例可以看出,这非常适用于计算机图形学

消除混叠确实很复杂,但其想法是通过不仅在每像素的基础上近似直线,而且使用智能着色使直线显示在某个不精确的位置来增强图像

要在核心图形中启用内置抗锯齿,请在执行旋转之前执行以下操作:

CGContextSetAllowsAntialiasing(theContext, true);
CGContextSetShouldAntialias(theContext, true);

请注意,就处理能力而言,抗锯齿可能非常昂贵,您应该仅在必要时使用它。

我发现解决此问题的唯一方法是:

  • 将图层绘制到位图上下文中
  • 将该上下文的CGImageRef设置为图层内容

  • OpenGL中的反走样通常很昂贵,因此在iOS上的核心动画中禁用,因为处理资源有限。这里的关键词是速度:核心动画针对转化为动画平滑度的绘图速度进行了优化。如果优先考虑图像质量,则不应将核心动画与旋转变换一起使用


    对于核心动画中的某些任务,可以在层内容周围添加1像素的边框。如果没有消除混叠,边缘将是锯齿状的,但当内容不在边缘上时,它不受此影响,而是会由于纹理过滤而变得平滑。

    不幸的是,这没有起到作用。绘制线时,线会正确消除锯齿。问题只有在转换时才会出现。从docu:创建窗口或位图上下文时,默认情况下会启用抗锯齿。只是一个澄清的备注。当您执行这两个步骤时,由于“纹理过滤”(请参见@EmilEriksson的答案),网格将显得平滑。
    CGContextSetAllowsAntialiasing(theContext, true);
    CGContextSetShouldAntialias(theContext, true);