使用CATiledLayer,在渲染时出现瓷砖之间的细线,这些瓷砖是使用ImageMagick生成的。

7
使用苹果公司的PhotoScroller示例和ImageMagick,我成功构建了我的目录应用程序。
但是,我遇到了一个渲染错误。平铺图像之间会出现一条细线。
我的简单脚本使用ImageMagick如下:
#!/bin/sh

file_list=`ls | grep JPG`

for i in 100 50 25; do 
 for file in $file_list; do
  convert $file -scale ${i}%x -crop 256x256 -set filename:tile "%[fx:page.x/256]_%[fx:page.y/256]" +repage +adjoin "${file%.*}_${i}_%[filename:tile].${file#*.}"
 done
done

苹果提供的代码是相同的。奇怪的是,他们提供的已经平铺的图片在同一运行时与我的图片并排工作得很好:(

我最初猜测瓷砖的大小与代码计算不匹配,但是更改大小无法解决,无论是在我的脚本还是在代码中。我的图像通常比苹果提供的小,实际上只有一半大小。

有人遇到过同样的问题吗?


1
感谢提供这个Shell脚本。 :-) - Daniel Rinser
3个回答

9
我遇到了两个问题。Damien的方法不能在所有缩放比例下完全消除所有线条,而Brent的解决方案虽然可以去除线条,但会在瓦片边界处添加一些伪像。
在Google搜索一段时间后,我终于找到了一个适合我的解决方案: http://openradar.appspot.com/8503490 (评论来自zephyr.renner)。
毕竟,苹果假设CTM.a == CTM.d并不是“安全”的...

1
这个解决方案在所有规模下都能完美运行。苹果代码的另一个要点是假设您有部分瓷砖。如果您的图像平铺器只创建了正方形瓷砖,则需要从PhotoScroller示例的drawRect循环中删除此代码行:tileRect = CGRectIntersection(self.bounds, tileRect); - MiKL
1
在“解决方案”中,要小心使用 _scale = (1 / (float)((int)(1/scale))) * 1000; 这行代码。如果比例大于1,_scale 将变为无穷大。 - René

8

我这里也遇到了完全相同的问题,使用PhotoScroller代码。当scale- (void)drawRect:(CGRect)rect中不正确时,就会出现问题。

您需要四舍五入scale... 在CGFloat scale = CGContextGetCTM(context).a;之后添加scale = 1.0f / roundf(1.0f / scale);(它还可以防止瓦片被绘制两次)。

并且将瓦片绘制为1个像素更大... 在tileRect = CGRectIntersection(self.bounds, tileRect);之后添加tileRect.size.width += 1; tileRect.size.height += 1;


很棒,这个可行。我已经不得不四舍五入比例或某些级别的瓷砖没有被称呼。 - Douglas Schmidt
我发现细线只出现在25%缩放级别上,扩大tileRect会在某些点隐藏图像的一些像素吗? - Douglas Schmidt

2
我遇到了这个相同的PhotoScroller问题,Damien的解决方案非常接近,但需要一个小的纠正才能完全消除这些讨厌的接缝。
对我来说,在所有缩放级别上都增加1像素大小的绘制瓷砖并不起作用。原因是我们在原始分辨率下绘制图像,然后由CTM缩放到屏幕分辨率。
因此,我们添加的1个像素实际上在屏幕上25%的缩放级别下绘制时变成了1/4个像素。
因此,为了在屏幕上将瓷砖放大1个像素,我们需要将1.0 / scale添加到宽度/高度中。(在调用CGRectIntersection之前应该这样做)
tileRect.size.width += 1.0/scale; tileRect.size.height += 1.0/scale;
tileRect = CGRectIntersection(self.bounds, tileRect);

明白了!像Damien建议的那样增加1个像素对我来说效果不错,但你的解决方案显然更加精细 :) 谢谢! - Douglas Schmidt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接