Использование GPUImage для воссоздания эффекта стекла iOS 7

Я пытаюсь использовать эффект стекла в стиле iOS 7 в своем стекле, применяя эффекты изображения к снимку экрана MKMapView. Эта категория UIImage, предоставляемая Apple, является тем, что я использую в качестве базовой линии. Этот метод обесцвечивает исходное изображение, применяет цвет оттенков и сильно размывает использование входных vals:

[image applyBlurWithRadius:10.0
                 tintColor:[UIColor colorWithRed:229/255.0f green:246/255.0f blue:255/255.0f alpha:0.33] 
     saturationDeltaFactor:0.66
                 maskImage:nil];

Это создает эффект, который я ищу, но занимает слишком много времени - между .3 и .5 секунд для рендеринга на iPhone 4.

enter image description here

Я хотел бы использовать отличный GPUImage, так как мои предварительные попытки были примерно в 5-10 раз быстрее, но я просто могу Кажется, все правильно.

GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:image];

GPUImageSaturationFilter *saturationFilter = [[GPUImageSaturationFilter alloc] init];
saturationFilter.saturation = 0.33; // 1.0 - 0.66;
[stillImageSource addTarget:saturationFilter];

GPUImageMonochromeFilter *monochromeFilter = [[GPUImageMonochromeFilter alloc] init];
[monochromeFilter setColor:(GPUVector4){229/255.0f, 246/255.0f, 1.0f, 0.33f}];
[monochromeFilter setIntensity:0.2];
[saturationFilter addTarget:monochromeFilter];

GPUImageFastBlurFilter *blurFilter = [[GPUImageFastBlurFilter alloc] init];
blurFilter.blurSize = 2;
blurFilter.blurPasses = 3;
[monochromeFilter addTarget:blurFilter];

[saturationFilter prepareForImageCapture];
[monochromeFilter prepareForImageCapture];

[stillImageSource processImage];
image = [blurFilter imageFromCurrentlyProcessedOutput];

Это создает изображение, которое близко, но не совсем там

enter image description here

Размытие не кажется достаточно глубоким, но когда я пытаюсь увеличить blurSize выше, он становится сетчатым, почти как калейдоскоп. Вы можете увидеть сетку здесь, увеличив изображение на втором изображении. Цвет оттенка, который я пытаюсь подражать, кажется, просто вымывает изображение вместо наложения и смешивания, которые, по моему мнению, делают образец Apple.

Я попытался настроить фильтры в соответствии с комментариями, сделанными @BradLarson в другом вопросе SO. Использую ли я неправильные фильтры GPUImage для воспроизведения этого эффекта, или я просто неправильно их настрою?

Ответ 1

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

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

Новая реализация гауссовского размытия, которую я построил, сочетает в себе преимущества производительности предварительно рассчитанных гауссовских весов с возможностью использования произвольного радиуса (сигма) для размытия Гаусса. Он делает это, создавая шейдеры "на лету", поскольку они необходимы для различных радиусов. Он также уменьшает количество образцов текстуры, необходимых для данного размытия, используя аппаратную интерполяцию для считывания двух текселей за раз для каждой точки выборки.

Новый GPUImageiOSBlurFilter объединяет этот настроенный гауссовский фильтр размытия произвольного радиуса с фильтром коррекции цвета, который, как представляется, реплицирует настройку. Apple выполняет цвета после того, как они были размыты. Я добавил ниже сравнение с моим ответом здесь, но в нем отображается встроенное размытие Apple с точки зрения центра управления слева, а мой новый фильтр размытия GPUImage справа

Apple's blurGPUImage's blur

Как способ повышения производительности (размытие Apple, похоже, происходит с сигмой 48, для которой требуется довольно большая площадь для каждого пикселя), я использую 4X понижающую дискретизацию перед размытием Gaussian, затем 4-кратное повышение дискретизации, Это уменьшает количество пикселей, которые должны быть размыты 16X, а также уменьшает сигма размытия от 48 до 12. iPhone 4S может размыть весь экран примерно через 30 мс с помощью этого фильтра.

Получение размытия вправо - это одно. Apple по-прежнему не обеспечивает быстрый способ получения содержимого изображения за вашими взглядами, поэтому, скорее всего, это будет вашим узким местом для быстрого изменения контента.