it-swarm.com.ru

Быстрое размытие на iOS

У меня проблемы с попыткой размывания части экрана в моем приложении для iOS. Смотрите изображение, чтобы лучше понять, что я пытаюсь сделать. 

BlurBox

Только содержимое «BlurBox» должно быть размытым, а остальное может быть четким. Поэтому, если вы смотрите на табличное представление, только содержимое под BlurBox будет размытым (даже при прокрутке). Остальное будет выглядеть ясно. 

Мой первый подход состоял в том, чтобы вызывать UIGraphicsGetImageFromCurrentImageContext() каждые 0,01, чтобы все слои под BlurBox объединялись в одно изображение. Затем размыть это изображение и показать его на все. 

Методы, которые я пробовал для размытия:

https://github.com/tomsoft1/StackBluriOS

https://github.com/coryleach/UIImageAdjust

https://github.com/esilverberg/ios-image-filters

https://github.com/cmkilger/CKImageAdditions

[layer setRasterizationScale:0.25];
[layer setShouldRasterize:YES];

А также несколько пользовательских попыток. Я также посмотрел на Apple GLImageProcessing , но думаю, что это немного излишне для того, что я пытаюсь сделать здесь. 

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

В некотором роде у меня была идея переопределить метод drawRect всех компонентов, которые я использую (UITableViewCells, UITableView и т.д.), И размыть каждый из них независимо на лету. Однако это займет некоторое время, это звучит как жизнеспособный вариант? 


ОБНОВИТЬ:

Я попытался использовать CIFilters следующим образом:

CIImage *inputImage = [[CIImage alloc] initWithImage:[self screenshot]];

CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
[blurFilter setDefaults];
[blurFilter setValue: inputImage forKey: @"inputImage"];
[blurFilter setValue: [NSNumber numberWithFloat:10.0f]
                           forKey:@"inputRadius"];


CIImage *outputImage = [blurFilter valueForKey: @"outputImage"];

CIContext *context = [CIContext contextWithOptions:nil];

self.bluredImageView.image = [UIImage imageWithCGImage:[context createCGImage:outputImage fromRect:outputImage.extent]];

Это работает, но невероятно медленно. :(

Я вижу, что некоторые реализации будут размыты, только когда я передам изображение, загруженное с диска. Если я передам UIImage, который я создал с помощью UIGraphicsGetImageFromCurrentImageContext(), он не будет работать. Любые идеи о том, почему это будет?


ОБНОВИТЬ:

Я попробовал предложение Пателя следующим образом:

CALayer *backgroundLayer = [CALayer layer];

CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
[blurFilter setDefaults];
backgroundLayer.backgroundFilters = [NSArray arrayWithObject:blurFilter];

[[self.view layer] addSublayer:backgroundLayer];

Тем не менее, это не работает :(


ОБНОВЛЕНИЕ ПОСЛЕ ДОБАВЛЕНИЯ:

Мне удалось заставить BlurBox работать правильно, используя TomSoft1 stackblur , так как он добавил возможность нормализовать изображение в формат RGBA (32 бит/пиксель) на лету. Тем не менее, это все еще довольно медленно. 

У меня есть таймер, вызывающий обновление каждые 0,03 с, чтобы получить изображение того, что находится под BlurBox, размыть это изображение и отобразить его на экране. Мне нужна помощь для повышения «fps» на BlurBox. 

20
random

Я бы порекомендовал Брэд Ларсон GPUImage, который полностью поддерживается GPU для широкого спектра эффектов обработки изображений. Это очень быстро, и даже достаточно быстро, чтобы в своем демонстрационном приложении он обрабатывал видео с камеры в режиме реального времени, а частота кадров была превосходной.

https://github.com/BradLarson/GPUImage

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

GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:[self screenshot]];

GPUImageTiltShiftFilter *boxBlur = [[GPUImageTiltShiftFilter alloc] init];
        boxBlur.blurSize = 0.5;

[stillImageSource addTarget:boxBlur];

[stillImageSource processImage];

UIImage *processedImage = [stillImageSource imageFromCurrentlyProcessedOutput];
41
brynbodayle

Ответ может быть немного запоздалым, но вы можете использовать фильтры Core Image. Причина, по которой он такой медленный, заключается в этой линии.

CIContext *context = [CIContext contextWithOptions:nil];

В документах Apple, чтобы получить лучшую производительность в Core Image, они утверждают, во-первых

«Не создавайте объект CIContext каждый раз, когда вы визуализируете .. Контексты хранят много информации о состоянии; более эффективно использовать их повторно».

Мое личное решение - создать синглтон для основного контекста изображения. Так что я создаю только один.

Мой код находится в этом демонстрационном проекте на GitHub.

https://github.com/KyleLopez/DemoCoreImage

Не стесняйтесь использовать его или найти другое решение по своему вкусу. Самая медленная часть, которую я нашел в CoreImage, это контекст, обработка изображений после которого действительно быстрая.

7
Kyle

Я не проверял это, но мне интересно, можете ли вы поместить CALayer туда, где вы хотите, чтобы окно было размытым, а затем найти полезную CIFilter, которую вы можете установить в CALayer'sbackgroundFilters. Просто мысль.

Смотрите CALayer.backgroundFilters

1
epatel

Вы можете попробовать набор процедур Apple Core Image Filter (CIFilter). Они требуют iOS 5, поэтому вы не сможете их использовать. 

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

Я использовал фильтры, чтобы изменить цвета изображения в режиме реального времени, и это работало хорошо.

http://developer.Apple.com/library/ios/#DOCUMENTATION/GraphicsImaging/Reference/QuartzCoreFramework/Classes/CIFilter_Class/Reference/Reference.html

0
PaulPerry

Вы пробовали эту библиотеку:

https://github.com/gdawg/uiimage-dsp

Он использует фреймворк vDSP/Accelerate и кажется простым в использовании.

Кстати: 0,01 с кажется слишком быстрым. 0.03 тоже должно быть.

0
Codo