代码之家  ›  专栏  ›  技术社区  ›  Felix Lamouroux

我该如何从我的定位层中移除那些旋转伪影?

  •  6
  • Felix Lamouroux  · 技术社区  · 15 年前

    我有一个catiledLayer,在其中我用以下方法呈现内容

    —(void)drawlayer:(calayer*)layer incontext:(cgContextRef)ctx
    < /代码> 
    
    

    我用quartzdemo代码绘制了一个模式。在我将旋转变换应用于层的父层(uiview)之前,这非常有效:

    旋转:

    当我开始在CatiledLayer中绘制线条和文本时,这些锯齿形的艺术品会变得更糟。

    我应用了如下转换(我还尝试对视图本身使用仿射转换):

    self.containerview.layer.transform=cattransform3dmakerrotation(angleradians,0.0f,0.0f,1.0f);
    < /代码> 
    
    

    我转换了ContainerView而不是图层本身,因为我在该视图中有多个图层,我希望在不更改相对位置的情况下同时旋转它们。

    我在过去旋转uiImageView时没有遇到问题。

    有没有一种方法可以在没有这些问题的情况下旋转catiledLayer?

    如有任何帮助,我们将不胜感激。

    你的,

    <菲利克斯>方法

    - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
    

    我用quartzdemo代码绘制了一个模式。在我将旋转变换应用于层的父层(uiview)之前,这非常有效:

    Non-Rotated CATiledLayer

    旋转:

    Rotated CATiledLayer

    当我开始在CatiledLayer中绘制线条和文本时,这些锯齿形的艺术品会变得更糟。

    我应用了如下转换(我还尝试对视图本身使用仿射转换):

    self.containerView.layer.transform = CATransform3DMakeRotation(angleRadians, 0.0f, 0.0f, 1.0f);
    

    我转换了ContainerView而不是层本身,因为我在该视图中有几个层,我希望在不更改相对位置的情况下同时旋转。

    我以前在旋转uiImageView时没有遇到问题。

    有没有一种方法可以在没有这些问题的情况下旋转catiledLayer?

    任何帮助都将不胜感激。

    你的,

    费利克斯

    4 回复  |  直到 14 年前
        1
  •  3
  •   Felix Lamouroux    15 年前

    解决这个问题的唯一方法是:

    1. 将层绘制到位图上下文中
    2. 将该上下文的cgimageref设置为层内容
        2
  •  2
  •   Emil Eriksson    14 年前

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

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

        3
  •  1
  •   Community CDub    8 年前

    或许这将有助于: quick and dirty anti-aliasing... . 特别是确保启用了“消除混叠”。

    CGContextSetAllowsAntialiasing(theContext, true);
    CGContextSetShouldAntialias(theContext, true);
    
        4
  •  1
  •   Community CDub    8 年前

    正如RyanZachry已经指出的,消除混叠将在这里帮助您。你在这里感受到的效果是“阶梯”效应。

    像素是正方形的,因此很容易绘制直线(水平或垂直),而不会产生任何伪影。如果你在一个角度上画线,你将需要光栅化你的线。在试图将线条映射到像素时,绘制线条的算法需要进行近似。这种算法的一个例子是 bresenham's (非常流行并且易于实现,但不具有反混叠功能)。 它的作用是:

    正如你在这张图片中看到的,在任何角度画一条线都会产生所谓的楼梯效果。为了避免这种效果,可以使用消除混叠。消除混叠实际上是信号理论的一部分。这是一种在低分辨率下表示高分辨率信号时最小化失真伪影(称为混叠)的技术。从上面的线条示例可以看出,这非常适用于计算机图形。

    消除混叠确实很复杂,但其目的是通过近似每像素的线条来增强图片效果,而且还可以使用智能着色使线条出现在非像素精确的特定位置。

    要在核心图形中启用内置消除混叠,请在执行旋转之前执行以下操作:

    cContextSetAllowsAntialiasing(theContext,true);
    cContextSetShouldAntialias(上下文,true);
    < /代码> 
    
    

    请注意,在处理能力方面,消除混叠可能非常昂贵,您只应在必要时使用它。

    -效果。

    像素是正方形的,因此很容易绘制直线(水平或垂直),而不会产生任何伪影。如果你在一个角度上画线,你将需要光栅化你的线。在试图将线条映射到像素时,绘制线条的算法需要进行近似。这种算法的一个例子是Bresenham's(非常流行,易于实现,但不具有消除混叠功能)。 它的作用是:

    From wikipedia

    正如你在这张图片中看到的,在任何角度画一条线都会产生所谓的楼梯效果。为了避免这种效果,可以使用消除混叠。消除混叠实际上是信号理论的一部分。这是一种在低分辨率下表示高分辨率信号时最小化失真伪影(称为混叠)的技术。从上面的线条示例中可以看到,这非常适用于计算机图形。

    消除混叠确实很复杂,但其目的是通过对每像素的线条进行近似来增强图片效果,而且还可以使用智能着色使线条出现在不精确的像素位置。

    From Wikipedia

    要在核心图形中启用内置消除混叠,请在执行旋转之前执行以下操作:

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

    请注意,在处理能力方面,消除混叠可能非常昂贵,您只应在必要时使用它。