2

我想绘制平铺图像,然后使用通常的平移和缩放手势对其进行转换。将我带到这里的问题是,每当我对大量小数位进行缩放转换时,瓷砖中间会出现一条细线像素(1 或 2)。我设法隔离了这样的问题:

CGContextSaveGState(UIGraphicsGetCurrentContext());

CGContextSetFillColor(UIGraphicsGetCurrentContext(), CGColorGetComponents([UIColor redColor].CGColor));
CGContextFillRect(UIGraphicsGetCurrentContext(), rect);//rect from drawRect:

float scale = 0.7;
CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(50, 50, 100, 100), testImage);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(150, 50, 100, 100), testImage);
CGContextRestoreGState(UIGraphicsGetCurrentContext());

使用 0.7 比例尺,这两个图像显示正确平铺: 0.7 刻度

使用 0.777777 比例(将第 6 行更改为“float scale = 0.777777;”),出现视觉伪影:

0.777777 比例

有没有办法避免这个问题?这发生在 CGImage、CGLayer 和矩形等原始形式中。它也发生在 MacOSx 上。

谢谢您的帮助!

编辑:补充说这也发生在原始形式上,如 CGContextFillRect

edit2:它也发生在 MacOSx 上!

4

2 回答 2

2

Quartz 有一个浮点坐标系,因此缩放可能会导致值不在像素边界上,从而在边缘产​​生可见的抗锯齿。如果你不想这样,你有两个选择:

  1. 调整您的比例因子,使您的所有缩放坐标都是积分的。这可能并不总是可行的,尤其是当你画很多东西的时候。

  2. 使用 为您的图形上下文禁用抗锯齿CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(), false);。这将产生清晰的像素边界,但除了直线之外的任何东西都可能看起来不太好。

于 2012-08-28T19:22:31.747 回答
0

总而言之,iOS 正在处理整数边界上的离散像素。当您的帧减少 0.7 时,50 减少到 35,就在像素边界上。在 0.777777 它不是 - 所以 iOS 适应和移动/缩小/混合任何东西。

你真的有两个选择。如果要使用上下文的缩放,则向上或向下舍入所需的值,以便得到整数缩放的帧值(您的代码显示 50 作为标准乘法值。)

否则,您无法缩放上下文,而是将内容一一缩放,并根据需要使用 CGIntegralRect 将所有维度向上或向下舍入。

编辑:如果我的怀疑是正确的,那么您还有另一种选择。假设您想要 0.77777 的比例因子和 50,50,100,100 的帧。你取 50,乘以比例,然后向上或向下舍入返回值。然后,您使用该值除以 0.7777 来重新计算新帧以获得一些小数值,当按 0.7777 缩放时返回一个整数。Quartz 非常擅长确定您的意思是整数值,因此忽略了小的舍入误差。我敢打赌,这对你来说会很好。

于 2012-08-28T17:56:13.660 回答