Возможно ли разбивать изображения в UIScrollView без необходимости вручную создавать все плитки?

В примере кода iPhone " PhotoScroller" из WWDC 2010, они показывают, как сделать довольно хороший мимик приложения "Фотографии" с прокруткой, масштабированием и подкачкой изображений. Они также разбивают изображения, чтобы показать, как отображать изображения с высоким разрешением и поддерживать хорошую производительность.

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

Мой вопрос: есть ли способ рисовать изображения без необходимости вручную просматривать все ваши фотографии и создавать "плитки"? Как приложение Photos может отображать большие изображения на лету?

Edit Вот код из ответа Deepa:

- (UIImage *)tileForScale:(float)scale row:(int)row col:(int)col size:(CGSize)tileSize  image:(UIImage *)inImage
{
CGRect subRect = CGRectMake(col*tileSize.width, row * tileSize.height, tileSize.width, tileSize.height);
CGImageRef tiledImage = CGImageCreateWithImageInRect([inImage CGImage], subRect);
UIImage *tileImage = [UIImage imageWithCGImage:tiledImage]; 
return tileImage;
}

Ответы

Ответ 1

Здесь приведен фрагмент кода для создания черепичного изображения:

В исходном коде PhotoScroller замените tileForScale: row: col: со следующим:

inImage - изображение, которое вы хотите создать.

- (UIImage *)tileForScale: (float)scale row: (int)row column: (int)col size: (CGSize)tileSize image: (UIImage*)inImage
{
    CGRect subRect = CGRectMake(col*tileSize.width, row * tileSize.height, tileSize.width, tileSize.height);
    CGImageRef tiledImage = CGImageCreateWithImageInRect([inImage CGImage], subRect);
    UIImage *tileImage = [UIImage imageWithCGImage: tiledImage];
    return tileImage;
}

С уважением, Deepa

Ответ 3

Извините Иона, но я думаю, что вы не можете делать то, что хотите.

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

  • Вы делаете плитки, чтобы сэкономить время и быть более отзывчивыми. Загрузка и черепица требуют времени для большого изображения.
  • Предыдущая причина особенно важна при первом запуске приложения.

Если эти две причины не имеют для вас никакого смысла, и вы все еще хотите это сделать, я бы использовал Quartz для создания плит. Функция CGImage CGImageCreateWithImageInRect стала бы моей отправной точкой.

Ответ 4

Ответ Deepa выше загрузит все изображение в память как UIImage (входная переменная в его функции), победив цель тайлирования.

Ответ 5

Многие форматы изображений поддерживают декодирование на уровне регионов. Вместо того, чтобы загружать все изображение в память, декомпрессировать все это и отбрасывать все, кроме области интереса (ROI), вы можете загружать и декодировать только ROI по требованию. По большей части это устраняет необходимость предварительного генерации и сохранения фрагментов изображений. Я никогда не работал с ImageMagick, но я был бы поражен, если бы он не смог этого сделать. (Я сделал это с использованием Java Advanced Imaging (JAI) API, который не поможет вам на iPhone...)

Я играл с примером PhotoScroller, и то, как он работает с предварительно сгенерированными фрагментами, - это только демонстрация идеи CATiledLayer и создание рабочего проекта. Просто заменить стратегию загрузки плитки изображения - просто переписать метод TilingView tileForScale:row:col: для возврата плитки UIImage из какого-либо другого источника, будь то Quartz или ImageMagick или что-то еще.