Взглянув на 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.