Использование CATiledLayer, тонкая линия между плитками при рендеринге, плитки, созданные с помощью ImageMagick - PullRequest
7 голосов
/ 19 ноября 2010

Используя пример PhotoScroller от Apple и 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

Код от Apple такой же. Странно то, что изображения, которые они уже выложили, работают как шарм, в то же время, бок о бок с моими изображениями: (

Мое первое предположение заключалось в том, что размер плиток не соответствовал расчетам в коде, но размеры изменений не фиксировались ни в моем скрипте, ни в коде. Мои изображения обычно меньше, чем у Apple, на самом деле они вдвое меньше.

Кто-нибудь получил такую ​​же проблему?

Ответы [ 3 ]

9 голосов
/ 31 августа 2011

У меня были проблемы с обоими решениями.Подход Дэмиена не полностью исключил все линии на всех масштабах масштабирования, а решение Брента удалило линии, но добавило некоторые артефакты на границах плиток.

Пройдя некоторое время в поисках, я, наконец, нашел решение, которое мне очень понравилось: http://openradar.appspot.com/8503490 (комментарий zephyr.renner ).

В конце концов, предположение Apple о том, что CTM.a == CTM.d не выглядит "безопасным" вообще ...

8 голосов
/ 01 декабря 2010

У меня точно такая же проблема, с использованием кода PhotoScroller.Проблема появляется, когда scale неверно в - (void)drawRect:(CGRect)rect.

Вам необходимо округлить scale ... Добавить scale = 1.0f / roundf(1.0f / scale); после CGFloat scale = CGContextGetCTM(context).a; (это также предотвращает повторное рисование плиток дважды)

И нарисуйте плитки на 1 пиксель больше ... Добавить tileRect.size.width += 1; tileRect.size.height += 1; после tileRect = CGRectIntersection(self.bounds, tileRect);.

2 голосов
/ 19 апреля 2011

Я столкнулся с той же самой проблемой PhotoScroller, и решение Дэмиена было очень близко, но требует одного незначительного исправления, чтобы полностью устранить эти надоедливые швы.

Рисование плиток на один пиксель больше не работало на всех уровнях масштабирования для меня.Причина в том, что мы рисуем изображение с исходным разрешением, а затем оно масштабируется с помощью CTM до разрешения экрана.

Таким образом, 1 добавленный нами пиксель фактически становится 1/4 от пикселя при рисовании вуровень масштабирования 25% на экране.

Поэтому, чтобы увеличить плитку на один пиксель на экране, нам нужно было бы добавить 1,0 / масштаб к ширине / высоте.(и это нужно сделать перед вызовом CGRectIntersection)

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