Создание эффекта размытия в iOS7
Я искал ответ на этот вопрос через несколько часов, и я просто не могу понять это. Я хочу добавить гауссовский эффект размытия к изображению, когда я нажимаю кнопку "Button". Пользователь добавляет изображение.
Я создал действие для "Button" на основе источников из SO и других мест в Интернете. Это не будет работать. Что я делаю не так? Любой код был бы очень признателен. Вот мое действие "Button":
- (IBAction)test:(id)sender {
CIFilter *gaussianBlurFilter = [CIFilter filterWithName: @"CIGaussianBlur"];
[gaussianBlurFilter setValue:imageView.image forKey: @"inputImage"];
[gaussianBlurFilter setValue:[NSNumber numberWithFloat: 10] forKey: @"inputRadius"];
}
Если вам нужно что-то еще, что я сделал для ответа на вопрос, сообщите мне: D
![Here is my UI]()
Ответы
Ответ 1
Три наблюдения:
-
Вам нужно установить inputImage
как CIImage
из UIImage
:
[gaussianBlurFilter setValue:[CIImage imageWithCGImage:[imageView.image CGImage]] forKey:kCIInputImageKey];
-
Я не вижу, чтобы вы хватали outputImage
, например:
CIImage *outputImage = [gaussianBlurFilter outputImage];
-
И вы, вероятно, хотите преобразовать это CIImage
обратно в UIImage
.
Итак, все вместе:
CIFilter *gaussianBlurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
[gaussianBlurFilter setDefaults];
CIImage *inputImage = [CIImage imageWithCGImage:[imageView.image CGImage]];
[gaussianBlurFilter setValue:inputImage forKey:kCIInputImageKey];
[gaussianBlurFilter setValue:@10 forKey:kCIInputRadiusKey];
CIImage *outputImage = [gaussianBlurFilter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgimg = [context createCGImage:outputImage fromRect:[inputImage extent]]; // note, use input image extent if you want it the same size, the output image extent is larger
UIImage *image = [UIImage imageWithCGImage:cgimg];
CGImageRelease(cgimg);
В качестве альтернативы, если вы перейдете к примерному образцу кода WWDC 2013 (требуется заплаченная подписка разработчика) и загрузите iOS_UIImageEffects
, вы можете захватить категорию UIImage+ImageEffects
. Это дает несколько новых методов:
- (UIImage *)applyLightEffect;
- (UIImage *)applyExtraLightEffect;
- (UIImage *)applyDarkEffect;
- (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor;
- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage;
Итак, чтобы размыть и изображение и осветлить его (придать эффект "матового стекла" ), вы можете:
UIImage *newImage = [image applyLightEffect];
Интересно, что код Apple не использует CIFilter
, а скорее вызывает vImageBoxConvolve_ARGB8888
vImage high-performance инфраструктура обработки изображений.
Этот метод проиллюстрирован в видео WWDC 2013 Внедрение взаимодействия с пользовательским интерфейсом на iOS.
Я знаю, что вопрос касался iOS 7, но теперь в iOS 8 можно добавить эффект размытия для любого объекта UIView
с помощью UIBlurEffect
:
UIVisualEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
effectView.frame = imageView.bounds;
[imageView addSubview:effectView];
Ответ 2
Это сработало для меня, однако оно медленное. Я сделаю преобразование при загрузке приложения и использую однократно преобразованное изображение во многих местах.
Этот эффект размытия для iOS 8.4. Быстрый язык.
override func viewDidLoad()
{
super.viewDidLoad()
var backgroundImage = self.blurImage(UIImage(named: "background.jpg")!)
self.view.backgroundColor = UIColor(patternImage:backgroundImage)
}
func blurImage(imageToBlur:UIImage) -> UIImage
{
var gaussianBlurFilter = CIFilter(name: "CIGaussianBlur")
gaussianBlurFilter.setValue(CIImage(CGImage: imageToBlur.CGImage), forKey:kCIInputImageKey)
var inputImage = CIImage(CGImage: imageToBlur.CGImage)
var outputImage = gaussianBlurFilter.outputImage
var context = CIContext(options: nil)
var cgimg = context.createCGImage(outputImage, fromRect: inputImage.extent())
return UIImage(CGImage: cgimg)!
}
Ответ 3
Ввод CIFilter
должен быть CIImage
не a UIImage
.
Ответ 4
Swift 2.0
Сделайте расширение UIImageView. (File-New-File-Empty Swift File -Name it Extensions.)
import Foundation
import UIKit
extension UIImageView{
//Method 1
func makeBlurImage(targetImageView:UIImageView?)
{
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = targetImageView!.bounds
blurEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight] // for supporting device rotation
targetImageView?.addSubview(blurEffectView)
}
//Method 2
func convertToBlurImage(imageToBlur:UIImage) -> UIImage
{
let gaussianBlurFilter = CIFilter(name: "CIGaussianBlur")
gaussianBlurFilter!.setValue(CIImage(CGImage: imageToBlur.CGImage!), forKey:kCIInputImageKey)
let initialImage = CIImage(CGImage: imageToBlur.CGImage!)
let finalImage = gaussianBlurFilter!.outputImage
let finalImagecontext = CIContext(options: nil)
let finalCGImage = finalImagecontext.createCGImage(finalImage!, fromRect: initialImage.extent)
return UIImage(CGImage: finalCGImage)
}
}
Применение:
Используя метод 1:
override func viewDidLoad() {
super.viewDidLoad()
let sampleImageView = UIImageView(frame: CGRectMake(0, 200, 300, 325))
let sampleImage:UIImage = UIImage(named: "ic_120x120")!
sampleImageView.image = sampleImage
//Convert To Blur Image Here
sampleImageView.makeBlurImage(sampleImageView)
self.view.addSubview(sampleImageView)
}
Используя метод 2:
override func viewDidLoad() {
super.viewDidLoad()
let sampleImageView = UIImageView(frame: CGRectMake(0, 200, 300, 325))
let sampleImage:UIImage = UIImage(named: "ic_120x120")!
//Convert to Blurred Image Here
let sampleImage2 = sampleImageView.convertToBlurImage(sampleImage)
sampleImageView.image = sampleImage2
self.view.addSubview(sampleImageView)
}
Ответ 5
Здесь расширение для размытия изображения на
Swift 3
extension UIImage {
public func blurImage(radius: CGFloat) -> UIImage {
let inputImage = CIImage(image: self)!
let parameters: [String:Any] = [
kCIInputRadiusKey: radius,
kCIInputImageKey: inputImage
]
let filter = CIFilter(name: "CIGaussianBlur",
withInputParameters: parameters)!
let cgimg = CIContext().createCGImage(filter.outputImage!, from: inputImage.extent)
return UIImage(cgImage: cgimg!)
}
}
Ответ 6
Swift 4 UIImage
расширение без развертывания силы:
extension UIImage {
/// Applies a gaussian blur to the image.
///
/// - Parameter radius: Blur radius.
/// - Returns: A blurred image.
func blur(radius: CGFloat = 6.0) -> UIImage? {
let context = CIContext()
guard let inputImage = CIImage(image: self) else { return nil }
guard let clampFilter = CIFilter(name: "CIAffineClamp") else { return nil }
clampFilter.setDefaults()
clampFilter.setValue(inputImage, forKey: kCIInputImageKey)
guard let blurFilter = CIFilter(name: "CIGaussianBlur") else { return nil }
blurFilter.setDefaults()
blurFilter.setValue(clampFilter.outputImage, forKey: kCIInputImageKey)
blurFilter.setValue(radius, forKey: kCIInputRadiusKey)
guard let blurredImage = blurFilter.value(forKey: kCIOutputImageKey) as? CIImage,
let cgImage = context.createCGImage(blurredImage, from: inputImage.extent) else { return nil }
let resultImage = UIImage(cgImage: cgImage, scale: scale, orientation: imageOrientation)
return resultImage
}
}
Я настоятельно рекомендую размыть изображение в фоновом потоке:
let image = UIImage(named: "myImage")
DispatchQueue.global(qos: .userInitiated).async {
let blurredImage = image.blur()
DispatchQueue.main.async {
self.myImageView.image = blurredImage
}
}