使用CATiledLayer,渲染时Tiles之间的细线,使用ImageMagick生成的tile

时间:2022-03-24 00:18:17

Using the PhotoScroller example by Apple and ImageMagick I managed to build my catalog app.

使用Apple和I​​mageMagick的PhotoScroller示例,我设法构建了我的目录应用程序。

But I'm having a rendering bug. The tiled images are rendered with a thin line between them.

但我有一个渲染错误。平铺图像在它们之间用细线渲染。

My simple script using ImageMagick is this:

我使用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

The code from Apple is the same. The bizarre thing is that the images that they provida already tiled works like a charm, in the same run time, side-by-side with my images :(

Apple的代码是一样的。奇怪的是,他们提供的图像已经铺设成像魅力,在相同的运行时间,与我的图像并排:(

My first guess was that the size of the tiles was not matching with the calculations on code, but change sizes didn't fix, neither on my script or in the code. My images are usually smaller than those provided by apple, half the size actually.

我的第一个猜测是,磁贴的大小与代码上的计算不匹配,但更改大小无法修复,无论是在我的脚本还是在代码中。我的图像通常小于苹果提供的图像,实际尺寸只有一半。

Anyone got the same issue?

有人有同样的问题吗?

3 个解决方案

#1


9  

I had problems with both solutions. Damien's approach did not fully eliminate all lines at all zoom scales and Brent's solution removed the lines, but added some artifacts at tile borders.

我有两个解决方案的问题。 Damien的方法并没有完全消除所有缩放比例的线条,布伦特的解决方案删除了​​线条,但在瓷砖边框添加了一些文物。

After googling around for some while, I finally found a solution that worked nicely for me: http://openradar.appspot.com/8503490 (comment by zephyr.renner).

谷歌搜索了一段时间后,我终于找到了一个适合我的解决方案:http://openradar.appspot.com/8503490(由zephyr.renner评论)。

After all, Apple's assumption that CTM.a == CTM.d doesn't seem to be "safe" at all...

毕竟,Apple假设CTM.a == CTM.d似乎根本不“安全”......

#2


8  

I have the exact same issue here, using PhotoScroller code. Problem appears, when scale is not right in - (void)drawRect:(CGRect)rect.

我在这里使用PhotoScroller代码有完全相同的问题。当缩放不正确时出现问题 - (void)drawRect:(CGRect)rect。

You need to round scale... Add scale = 1.0f / roundf(1.0f / scale); after CGFloat scale = CGContextGetCTM(context).a; (it also prevents tiles from being drawn twice).

你需要舍入比例...添加比例= 1.0f / roundf(1.0f / scale);在CGFloat scale = CGContextGetCTM(context)之后.a; (它还可以防止瓷砖被绘制两次)。

And draw tiles 1 pix larger... Add tileRect.size.width += 1; tileRect.size.height += 1; after tileRect = CGRectIntersection(self.bounds, tileRect);.

并绘制瓷砖1像素更大...添加tileRect.size.width + = 1; tileRect.size.height + = 1;在tileRect = CGRectIntersection(self.bounds,tileRect);之后;

#3


2  

I have encountered this same PhotoScroller issue and Damien's solution was very close but requires one minor correction to completely eliminate those pesky seams.

我遇到了同样的PhotoScroller问题,Damien的解决方案非常接近但需要一个小的修正才能完全消除那些讨厌的接缝。

Drawing tiles one pixel larger didn't work at all zoom levels for me. The reason is that we are drawing the image at the original resolution and then it is scaled by the CTM to the screen resolution.

对于我来说,一个像素更大的绘图区块在所有缩放级别都不起作用。原因是我们以原始分辨率绘制图像,然后由CTM将其缩放到屏幕分辨率。

So, the 1 pixel we added actually becomes 1/4 of a pixel when drawn at the 25% zoom level on the screen.

因此,当我们在屏幕上以25%的缩放级别绘制时,我们添加的1个像素实际上变为1/4像素。

Therefore, to enlarge the tile by one pixel on the screen we would need to add 1.0/scale to the width/height. (and this should be done before calling CGRectIntersection)

因此,要在屏幕上将图块放大一个像素,我们需要在宽度/高度上添加1.0 /比例。 (这应该在调用CGRectIntersection之前完成)

tileRect.size.width += 1.0/scale; tileRect.size.height += 1.0/scale;
tileRect = CGRectIntersection(self.bounds, tileRect);

#1


9  

I had problems with both solutions. Damien's approach did not fully eliminate all lines at all zoom scales and Brent's solution removed the lines, but added some artifacts at tile borders.

我有两个解决方案的问题。 Damien的方法并没有完全消除所有缩放比例的线条,布伦特的解决方案删除了​​线条,但在瓷砖边框添加了一些文物。

After googling around for some while, I finally found a solution that worked nicely for me: http://openradar.appspot.com/8503490 (comment by zephyr.renner).

谷歌搜索了一段时间后,我终于找到了一个适合我的解决方案:http://openradar.appspot.com/8503490(由zephyr.renner评论)。

After all, Apple's assumption that CTM.a == CTM.d doesn't seem to be "safe" at all...

毕竟,Apple假设CTM.a == CTM.d似乎根本不“安全”......

#2


8  

I have the exact same issue here, using PhotoScroller code. Problem appears, when scale is not right in - (void)drawRect:(CGRect)rect.

我在这里使用PhotoScroller代码有完全相同的问题。当缩放不正确时出现问题 - (void)drawRect:(CGRect)rect。

You need to round scale... Add scale = 1.0f / roundf(1.0f / scale); after CGFloat scale = CGContextGetCTM(context).a; (it also prevents tiles from being drawn twice).

你需要舍入比例...添加比例= 1.0f / roundf(1.0f / scale);在CGFloat scale = CGContextGetCTM(context)之后.a; (它还可以防止瓷砖被绘制两次)。

And draw tiles 1 pix larger... Add tileRect.size.width += 1; tileRect.size.height += 1; after tileRect = CGRectIntersection(self.bounds, tileRect);.

并绘制瓷砖1像素更大...添加tileRect.size.width + = 1; tileRect.size.height + = 1;在tileRect = CGRectIntersection(self.bounds,tileRect);之后;

#3


2  

I have encountered this same PhotoScroller issue and Damien's solution was very close but requires one minor correction to completely eliminate those pesky seams.

我遇到了同样的PhotoScroller问题,Damien的解决方案非常接近但需要一个小的修正才能完全消除那些讨厌的接缝。

Drawing tiles one pixel larger didn't work at all zoom levels for me. The reason is that we are drawing the image at the original resolution and then it is scaled by the CTM to the screen resolution.

对于我来说,一个像素更大的绘图区块在所有缩放级别都不起作用。原因是我们以原始分辨率绘制图像,然后由CTM将其缩放到屏幕分辨率。

So, the 1 pixel we added actually becomes 1/4 of a pixel when drawn at the 25% zoom level on the screen.

因此,当我们在屏幕上以25%的缩放级别绘制时,我们添加的1个像素实际上变为1/4像素。

Therefore, to enlarge the tile by one pixel on the screen we would need to add 1.0/scale to the width/height. (and this should be done before calling CGRectIntersection)

因此,要在屏幕上将图块放大一个像素,我们需要在宽度/高度上添加1.0 /比例。 (这应该在调用CGRectIntersection之前完成)

tileRect.size.width += 1.0/scale; tileRect.size.height += 1.0/scale;
tileRect = CGRectIntersection(self.bounds, tileRect);