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

发布于 2024-08-27 13:26:27 字数 783 浏览 8 评论 0 原文

我有一个 CATiledLayer,我在其中

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

使用 QuartzDemo 代码绘制图案的以下方法渲染内容。这非常有效,直到我将旋转变换应用于图层的parentLayer(UIView):

旋转:

< img src="https://i.sstatic.net/oC6P3.png" alt="Rotated CATiledLayer">

当我开始在 CATiledLayer 中绘制线条和文本时,这些锯齿形伪像变得更糟。

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

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

我变换containerView而不是图层本身,因为我在该视图中有几个图层,我想同时旋转而不改变相对位置。

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

有没有办法可以旋转 CATiledLayer 而不会出现这些问题?

任何帮助将不胜感激。

你的,

菲利克斯

I have a CATiledLayer into which I render content in the following method

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

I used the QuartzDemo code to draw a pattern. This works very well until I apply a rotation transform to the layer's parentLayer (a UIView):

Non-Rotated CATiledLayer

rotated:

Rotated CATiledLayer

These zigzag artefacts become worse when I start drawing lines and texts into the CATiledLayer.

I applied the transform as follows (I also tried using an affine transform on the view itself):

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

I transform the containerView rather than the layer itself, as I have several layers in that view that I would like to rotate at the same time without changing the relative positions.

I did not have problems when rotating UIImageViews in the past.

Is there a way that I can rotate the CATiledLayer without these problems?

Any help would be greatly appreciated.

Yours,

Felix

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凉宸 2024-09-03 13:26:27

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

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

The only way of fixing this issue I found was this:

  1. Draw the layer into a bitmap context
  2. Set the CGImageRef of that context as the layer contents
荒人说梦 2024-09-03 13:26:27

OpenGL 中的抗锯齿通常非常昂贵,因此由于处理资源有限,iOS 上的核心动画被禁用。这里的关键词是速度:核心动画针对绘图速度进行了优化,这意味着动画的流畅度。如果图像质量是优先考虑的,则不应将核心动画与旋转变换一起使用。

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

Anti-aliasing in OpenGL is often expensive and thus is disabled for Core Animation on iOS since processing resources are limited. The keyword here is speed: Core Animation is optimized for speed of drawing which translates to smoothness of animation. If image quality is the priority, you should not use Core Animation with rotational transforms.

For some tasks in Core Animation, you can add a 1 px border around your layer content. Without anti-aliasing, edges will be jagged but when the content is not on an edge, it is not affected by this and will instead be smoothed out because of texture filtering.

ζ澈沫 2024-09-03 13:26:27

正如 Ryan Zachry 已经指出的那样,抗锯齿功能将在这方面为您提供帮助。您在这里体验到的效果是“楼梯”效果。

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

From wikipedia

As在这张图中你可以很清楚地看到,以任何角度画一条线都会产生所谓的楼梯效应。为了避免这种效果,您可以使用抗锯齿功能。抗锯齿实际上是信号理论的一部分。这是一种在以较低分辨率表示高分辨率信号时最大限度地减少失真伪影(称为混叠)的技术。正如您从上面的线条示例中看到的,这非常适用于计算机图形学。

抗锯齿确实很复杂,但其想法是不仅在每个像素的基础上近似线条,而且还使用智能着色使线条出现在不精确的某个位置,从而增强图像。

来自维基百科

启用内置抗锯齿功能在 Core Graphics 中,在执行旋转之前执行以下操作:

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

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

As Ryan Zachry has already pointed out, anti-aliasing will help you here. The effect you are experiencing here is the "stairs"-effect.

Pixels are square, so it is easy to draw straight lines (horizontally or vertically) without producing any artifacts. If you're drawing lines at an angle, you will need to rasterize your line. An algorithm for line drawing will need to make approximations when trying to map your line to the pixels. An example for such an algorithm is Bresenham's (very popular and easy to implement but does not feature anti-aliasing).
Here's what it does:

From wikipedia

As you can see very clear in this picture, drawing a line at any angle results in the so-called stairs-effect. To avoid this effect you can use anti-aliasing. Anti-aliasing is actually a part of signal theory. It is the technique of minimizing the distortion artifacts known as aliasing when representing a high-resolution signal at a lower resolution. As you can see from the line example above, this applies very well to computer graphics.

Anti-aliasing is really complicated, but the idea is to enhance the picture by approximating the line not only on a per-pixel basis but also to use intelligent coloring to make the line appear at a certain location that is not pixel-exact.

From Wikipedia

To enable built-in anti-aliasing in Core Graphics, do the following before performing your rotation:

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

Note that anti-aliasing can be very expensive in terms of processing power, you should only use it when necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文