Взглянув на iOS 7, меня удивило количество эффекта blur на всевозможных панельках этой чудо-ОС. Очевидно, данный эффект входит в тренд, а это значит, что нужно использовать его и в своих приложениях.
Для начала расскажу, как достигается этот эффект и наносится на “панельку”.
Возьмем два представления (UIView). На одном находится некая картинка, а второе, которое мы добавили поверх, просто хотим сделать прозрачным с эффектом блюра.
Многие думают, что для достижения эффекта блюра можно просто дать свойство второму представлению, ничего не зная о картинке из первого – это неверно. Вторая панелька должна содержать уже “заблюренную” картинку. Для этого нужно сначала взять картинку из первого представления, добавить на нее эффект блюра (размытие), а затем нанести полученную картинку на второе представление.
Теперь попробуем кодом преобразовать обычное изображение в изображение с эффектом блюра. Для этого мы будем использовать размытие по Гауссу.
Предлагаю 2 способа достижения результата для разных минимально поддерживаемых версий iOS:
iOS 7 и выше (Пример Apple)
Проект можно скачать отсюда
iOS 6 и выше (Мой пример)
Код доступен на GitHub
Категория для UIImage. Добавление эффекта блюра iOS 7 и оттенка для использования в iOS 6 и выше
/**
* -(UIImage*)getBlurredImage
*
* Возвращает изображение с блюром
*/
-(UIImage*)getBlurredImage{
return [self getBlurredImageWithTintColor:nil];
}
/**
* -(UIImage*)getDarkBlurredImage
*
* Возвращает изображение с темным блюром
*/
-(UIImage*)getDarkBlurredImage{
UIColor *tintColor = [UIColor colorWithWhite:0.11 alpha:0.73];
return [self getBlurredImageWithTintColor:tintColor];
}
/**
* -(UIImage*)getLightBlurredImage
*
* Возвращает изображение со светлым блюром
*/
-(UIImage*)getLightBlurredImage{
UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3];
return [self getBlurredImageWithTintColor:tintColor];
}
/**
* -(UIImage*)getExtraLightBlurredImage
*
* Возвращает изображение с очень светлым блюром
*/
-(UIImage*)getExtraLightBlurredImage{
UIColor *tintColor = [UIColor colorWithWhite:0.97 alpha:0.81];
return [self getBlurredImageWithTintColor:tintColor];
}
/**
* -(UIImage*)getBlurredImageWithTintColor:
*
* Возвращает изображение с блюром и указанным оттенком
*
* @param Цвет оттенка
*/
- (UIImage*)getBlurredImageWithTintColor:(UIColor*)tintColor
{
// Создаем контекст для изображения с блюром
CIContext *context = [CIContext contextWithOptions:nil];
// Ковертируем изображение в CIImage
CIImage *inputImage = [CIImage imageWithCGImage:self.CGImage];
// Настраиваем фильтр "Gaussian Blur"
CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
// Устанавливаем к фильтру входящее изображение
[filter setValue:inputImage forKey:kCIInputImageKey];
// Настраиваем радиус размытия
CGFloat blurRadius = 15.0f;
// Устанавливаем к фильтру радиус размытия
[filter setValue:[NSNumber numberWithFloat:blurRadius] forKey:@"inputRadius"];
// Получаем изображение с блюром.
// ВНИМАНИЕ: Итоговый размер блюра по размерам может быть меньше
// размера изображения из-за данного типа блюра (Gaussian Blur)
CIImage *result = [filter valueForKey:kCIOutputImageKey];
// Конвертируем изображение в CGImageRef
CGImageRef cgImage = [context createCGImage:result fromRect:[inputImage extent]];
UIImage *outputImage = nil;
// Если имеется цвет оттенка, то добавляем его
if (tintColor) {
// Берем область изображения
CGRect imageRect = { CGPointZero, self.size };
// Настраиваем контекст для изображения с блюром
UIGraphicsBeginImageContext(imageRect.size);
CGContextRef outputContext = UIGraphicsGetCurrentContext();
// Переворачиваем систему координат
CGContextScaleCTM(outputContext, 1.0, -1.0);
CGContextTranslateCTM(outputContext, 0, -self.size.height);
// Рисуем изображение с блюром на контексте
CGContextDrawImage(outputContext, imageRect, cgImage);
// Сохраняем текущее состояние контекста
CGContextSaveGState(outputContext);
// Настраиваем цвет оттенка
CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);
// Заливаем контекст цветом оттенка
CGContextFillRect(outputContext, imageRect);
// Восстанавливаем состояние контекста
CGContextRestoreGState(outputContext);
// Получаем итоговое изображение с блюром и оттенком
outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
else{
// Если оттенка нет, то конвертируем изображение в UIImage
outputImage = [UIImage imageWithCGImage:cgImage];
}
return outputImage;
}
На весь эффект блюра и наложения оттенка на изображение скриншота с iPhone 5 уходит в среднем 0.044 секунды.

В iOS 7 если поднять Control Center над каким-то динамическим изображением, блюр картинка будет отображать изменение оригинала, что как раз создает впечатление что для вьюшки Control Center абсолютно безразлично что под ней находится. Как это реализовано по-вашему? Скриншот и применение блюр эффекта производится с некоторым интервалом?
Анастасия, это реализовано точно также с помощью капчинга и обработки того изображения, которое находится под вьюшкой. Просто новый способ Apple с использованием Accelerate.framework может капчить и блюрить изображение настолько быстро, что это можно делать в режиме реального времени не ниже 30 FPS. Именно так Apple и делает в этом примере.
А вы пробовали iFlou? Эта библиотека отлично работает и позволяет легко сделать эффект blur на iOS.