Подтвердить что ты не робот

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

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

BlurBox

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

Мой первый подход состоял в том, чтобы называть UIGraphicsGetImageFromCurrentImageContext() каждый .01s, чтобы все слои под 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, но я думаю, что это немного переборщило с тем, что я пытаюсь сделать здесь.

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

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


UPDATE

Я попытался использовать 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(), он не работает. Любые идеи о том, почему это было бы?


UPDATE

Я попробовал следующее предложение:

CALayer *backgroundLayer = [CALayer layer];

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

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

Однако это не работает: (


ОБНОВЛЕНИЕ ПОСЛЕ BOUNTY ADDED:

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

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

4b9b3361

Ответ 1

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

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];

Ответ 2

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

CIContext *context = [CIContext contextWithOptions:nil];

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

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

Моим личным решением для этого является создание Singleton для Контекста Core Image. Поэтому я только создаю его.

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

https://github.com/KyleLopez/DemoCoreImage

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

Ответ 3

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

См. CALayer.backgroundFilters

Ответ 4

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

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

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

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

Ответ 5

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

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

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

Кстати: 0.01 кажется слишком быстрым. 0.03 также следует делать.