7

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

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:

#!/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 :(

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?

Douglas Schmidt
  • 368
  • 1
  • 2
  • 12

3 Answers3

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.

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).

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

Daniel Rinser
  • 8,855
  • 4
  • 41
  • 39
  • 1
    This solution works like a charm at all scales. Another point of the Apple code is the assumption that you have partial tiles. **If your image tiler only created square tiles you need to remove** this line of code from the PhotoScroller example: `tileRect = CGRectIntersection(self.bounds, tileRect);` in the for loop of drawRect – MiKL Nov 22 '11 at 12:30
  • 1
    Be careful with the line `_scale = (1 / (float)((int)(1/scale))) * 1000;` from the "solution". If the scale is larger than 1, `_scale` will become infinity. – René Feb 26 '12 at 20:15
8

I have the exact same issue here, using PhotoScroller code. Problem appears, when scale is not right in - (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).

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

Damien Debin
  • 2,812
  • 25
  • 41
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.

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.

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

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)

tileRect.size.width += 1.0/scale; tileRect.size.height += 1.0/scale;
tileRect = CGRectIntersection(self.bounds, tileRect);
Brent
  • 103
  • 1
  • 5