Pixelate-переход в iOS - PullRequest
       41

Pixelate-переход в iOS

4 голосов
/ 27 марта 2012

Как реализовать пиксельный переход, такой как this (анимированный GIF) в iOS?

Возможно ли реализовать с Core Animation?

Ответы [ 3 ]

2 голосов
/ 28 марта 2012

C4 - комментарий Трэвиса верен, ваш лучший вариант, вероятно, сделать анимацию живой. Вы захотите взять код в QA1703 для захвата экрана, но отрегулируйте размер контекста, который вы создаете в UIGraphicsBeginImageContextWithOptions, и соответственно измените матрицу текущего преобразования (CTM) Core Graphics сразу после вызова UIGraphicsGetCurrentContext. Так что, просто набрав, как я пишу это, ваши настройки будут выглядеть примерно так:

- (UIImage*)screenshotWithScale:(CGFloat)scale
{
    // Create a graphics context with the target size
    // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
    // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
    CGSize imageSize = [[UIScreen mainScreen] bounds].size;

    /* YOU'VE ADDED: */
    imageSize.width *= scale;
    imageSize.height *= scale;

    if (NULL != UIGraphicsBeginImageContextWithOptions)
    /* ... then stuff as per the original, down to ... */

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextScaleCTM(context, scale, scale);

    // Iterate over every window from back to front
    for (UIWindow *window in [[UIApplication sharedApplication] windows]) 
        /* etc, etc, down to... */

     // Retrieve the screenshot image
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    CGContextRestoreGState(context);
    UIGraphicsEndImageContext();

    return image;
}

При масштабе = 1,0 вы получите UIImage, точно равный экрану. С масштабом = 0,5 вы получите один с вдвое меньшим количеством пикселей по горизонтали и вертикали, с масштабом = 0,25 вы получите по четыре раза больше пикселей по горизонтали и т. Д.

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

2 голосов
/ 28 марта 2012

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

Я показываю пример моего GPUImagePixellateFilter в этом ответе , который может дать такой эффект, если вы настроите свойство fractionalWidthOfAPixel для таймера.

Для фотоизображение, вам нужно будет вставить свой UIImage в виде GPUImagePicture и связать его через фильтр пикселов с GPUImageView.Для каждого обновления ширины пикселя вы должны вызывать -processImage в источнике изображения, чтобы обновить изображение на экране.После начальной настройки и загрузки изображений эта анимация должна работать со скоростью 60 кадров в секунду на каждом устройстве iOS, поддерживающем OpenGL ES 2.0.

2 голосов
/ 28 марта 2012

Существуют фильтры CIPixellate и CIHexagonalPixellate, описанные в Справочнике по фильтру базовых изображений, но в настоящее время они доступны только для OSX ... но не для iOS, к сожалению.

http://developer.apple.com/library/mac/#documentation/graphicsimaging/reference/CoreImageFilterReference/Reference/reference.html

...