views:

385

answers:

3

Hello all,

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

+1  A: 

Perhaps this will help: quick and dirty anti-aliasing.... Specifically ensuring anti aliasing is on.

CGContextSetAllowsAntialiasing(theContext, true);
CGContextSetShouldAntialias(theContext, true);
Ryan Zachry
Unfortunately this did not do the trick. The lines are properly antialiased when drawn. The problem occurs only upon transformation. From the docu: Anti-aliasing is turned on by default when a window or bitmap context is created.
Felix
+1  A: 

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.

Johannes Rudolph
Unfortunately this did not do the trick. The lines are properly antialiased when drawn. The problem occurs only upon transformation. From the docu: Anti-aliasing is turned on by default when a window or bitmap context is created.
Felix
+1  A: 

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
Felix