получение снимка изображения с поддержкой CATiledLayer в UIScrollView - PullRequest
5 голосов
/ 03 февраля 2012

У меня есть пользовательский вид карты, который сделан из UIScrollView.Подвид прокрутки поддерживает CATiledLayer.Здесь все отлично работает.Панорамирование и масштабирование загружает новые фрагменты карты, и все работает хорошо.

То, что я хочу сделать, - это захватывать кадры видео анимации для этого вида прокрутки.По сути, я хочу создать видео с анимированными изменениями в представлениях прокрутки contentOffset и zoomScale.

Я знаю, что концепция является разумной, поскольку я могу получить функцию частного API UIGetScreenImage(), чтобы захватывать экран приложения, скажем, со скоростью 10 кадров в секунду, комбинировать эти изображения, и я получаю анимации воспроизведения, которые являются плавными и имеютвременные кривые, используемые анимацией просмотра прокрутки.

Моя проблема, конечно, в том, что я не могу использовать закрытый API.Прохождение альтернатив, описанных Apple здесь , оставляет мне почти один предположительно правильный вариант: запросить CALayer до renderInContext и взять UIGraphicsGetImageFromCurrentImageContext() из этого.

Похоже, это просто не работает с CATiledLayer представлениями.Захваченное, не масштабированное изображение - это то, что захватывается, как будто плитки с более высоким разрешением никогда не загружаются.В некоторой степени это имеет смысл, учитывая, что CATiledLayer использует фоновые потоки для повышения производительности, и вызов renderInContext из основного потока может не перехватить эти обновления.Результат аналогичен, даже если я отрисовываю плиточный слой presentationLayer.

Существует ли санкционированный Apple способ захвата изображения вида с поддержкой CATiledLayer во время анимации содержащего прокрутки вида?Или в любой момент?

Ответы [ 3 ]

1 голос
/ 06 мая 2013

Кстати, это выполнимо, если вы правильно реализуете renderLayer:inContext: в представлении с поддержкой CATiledLayer.

0 голосов
/ 25 августа 2015

Этот код работает для меня.

- (UIImage *)snapshotImageWithView:(CCTiledImageScrollView *)view
{
// Try our best to approximate the best tile set zoom scale to use
CGFloat tileScale;
if (view.zoomScale >= 0.5) {
    tileScale = 2.0;
}
else if (view.zoomScale >= 0.25) {
    tileScale = 1.0;
}
else {
    tileScale = 0.5;
}

// Calculate the context translation based on how far zoomed in or out.
CGFloat translationX = -view.contentOffset.x;
CGFloat translationY = -view.contentOffset.y;
if (view.contentSize.width < CGRectGetWidth(view.bounds)) {
    CGFloat deltaX = (CGRectGetWidth(view.bounds) - view.contentSize.width) / 2.0;
    translationX += deltaX;
}
if (view.contentSize.height < CGRectGetHeight(view.bounds)) {
    CGFloat deltaY = (CGRectGetHeight(view.bounds) - view.contentSize.height) / 2.0;
    translationY += deltaY;
}

// Pass the tileScale to the context because that will be the scale used in drawRect by your CATiledLayer backed UIView
UIGraphicsBeginImageContextWithOptions(CGSizeMake(CGRectGetWidth(view.bounds) / view.zoomScale, CGRectGetHeight(view.bounds) / view.zoomScale), NO, tileScale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, translationX / view.zoomScale, translationY / view.zoomScale);

// The zoomView is a subview of UIScrollView. The CATiledLayer backed UIView is a subview of the zoomView.
[view.zoomView.layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return image;

}

Полный пример кода находится здесь: https://github.com/gortega56/CCCanvasView

0 голосов
/ 03 февраля 2012

Я провел быструю проверку и использовал renderInContext: в представлении обтекания вид прокрутки, похоже, работал.Вы пробовали это?

...