рисование изображения из CALayers - PullRequest
1 голос
/ 31 января 2011

Я создаю какое-то приложение для цензуры.Я дошел до того, что могу сделать пикселирование изображения, полученного с помощью моего iPhone.

Но в конце я хочу получить изображение, подобное этому: http://images -mediawiki-sites.thefullwiki.org / 11/4/8/8 / 8328511755287292.jpg

Поэтому я думал, что нужно полностью пикселировать мое изображение, а затем добавить маску поверх него для достижения желаемого эффекта.Так что с точки зрения слоев это выглядит так: originalImage + maskedPixelatedVersionOfImage .. Я думал анимировать маску при касании изображения, чтобы масштабировать маску до желаемого размера.Чем дольше вы держите палец на изображении, тем больше становится маска ...

После некоторого поиска, я думаю, это можно сделать с помощью CALayers и CAAnimation.Но как мне затем объединить эти слои с изображением, которое я могу сохранить в фотоальбоме на iphone?

Правильный ли я подход здесь?

РЕДАКТИРОВАНИЕ:

Хорошо, я думаю, что решение Оле является правильным, хотя я все еще не получаю то, что хочу: код, который я использую:

    CALayer *maskLayer = [CALayer layer];
    CALayer *mosaicLayer = [CALayer layer];

    // Mask image ends with 0.15 opacity on both sides. Set the background color of the layer
    // to the same value so the layer can extend the mask image.
    mosaicLayer.contents = (id)[img CGImage];
    mosaicLayer.frame = CGRectMake(0,0, img.size.width, img.size.height);
    UIImage *maskImg = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"mask" ofType:@"png"]];
    maskLayer.contents = (id)[maskImg CGImage];
    maskLayer.frame = CGRectMake(100,150, maskImg.size.width, maskImg.size.height);

    mosaicLayer.mask = maskLayer;

    [imageView.layer addSublayer:mosaicLayer];

    UIGraphicsBeginImageContext(imageView.layer.bounds.size);
    [imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *saver = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

Так что в моем imageView я сделал: setImage, который имеет оригинальный(неотредактированная) версия фотографии.Кроме того, я добавляю подслой mosaicLayer, который имеет свойство mask: maskLayer.Я думал, что при рендеринге корневого слоя imageView все будет хорошо.Разве это не правильно?

Кроме того, я понял кое-что еще: моя маска растянута и повернута, что, я полагаю, как-то связано с imageOrientation?Я заметил, что случайно сохранил mosaicLayer в моей библиотеке, что также объясняет проблему, с которой я столкнулся, потому что маска, казалось, маскировала неправильную часть моего изображения ...

Ответы [ 2 ]

7 голосов
/ 31 января 2011

Чтобы отобразить дерево слоев, поместите все слои в общий контейнерный слой и вызовите:

UIGraphicsBeginImageContext(containerLayer.bounds.size);
[containerLayer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
4 голосов
/ 31 января 2011

Если вы хотите отказаться от поддержки устройств до iPhone 3G S (iPhone и iPhone 3G), я бы предложил для этого использовать шейдеры OpenGL ES 2.0.Хотя может быть легко наложить CALayer, содержащий пиксельную версию изображения, я думаю, вам не хватит производительности.

В моих тестах выполнение простого вычисления на основе ЦП для каждого пикселя изображения 480 x 320 привело к частоте кадров около 4 кадров в секунду на iPhone 4. Возможно, вы сможетеСэмплируйте только часть этих пикселей для достижения желаемого эффекта, но все равно будет медленной операцией перерисовывать пикселированное изображение в соответствии с живым видео.

Вместо этого, если вы используете фрагментный шейдер OpenGL ES 2.0 дляОбрабатывая входящее видеоизображение в реальном времени, вы должны иметь возможность получать необработанное изображение с камеры, применять этот фильтр выборочно над требуемой областью и либо отображать, либо сохранять полученное изображение с камеры.Эта обработка будет происходить почти полностью на графическом процессоре, который, как я обнаружил, выполняет простые операции, подобные этой, на скорости 60 кадров в секунду на iPhone 4.

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

...