CIGaussianBlur размер изображения

Эй, хотите размыть мой вид, и я использую этот код:

//Get a UIImage from the UIView
NSLog(@"blur capture");
UIGraphicsBeginImageContext(BlurContrainerView.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

//Blur the UIImage
CIImage *imageToBlur = [CIImage imageWithCGImage:viewImage.CGImage];
CIFilter *gaussianBlurFilter = [CIFilter filterWithName: @"CIGaussianBlur"];
[gaussianBlurFilter setValue:imageToBlur forKey: @"inputImage"];
[gaussianBlurFilter setValue:[NSNumber numberWithFloat: 5] forKey: @"inputRadius"]; //change number to increase/decrease blur
CIImage *resultImage = [gaussianBlurFilter valueForKey: @"outputImage"];

//create UIImage from filtered image
blurredImage = [[UIImage alloc] initWithCIImage:resultImage];

//Place the UIImage in a UIImageView
UIImageView *newView = [[UIImageView alloc] initWithFrame:self.view.bounds];
newView.image = blurredImage;

NSLog(@"%f,%f",newView.frame.size.width,newView.frame.size.height);
//insert blur UIImageView below transparent view inside the blur image container
[BlurContrainerView insertSubview:newView belowSubview:transparentView];

и это размывает представление, но не все. Как я могу размыть весь вид?

billed: postimg.org/image/9bee2e4zx/

3 ответов


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

чтобы сохранить изображение того же размера, после строки:

CIImage *resultImage    = [gaussianBlurFilter valueForKey: @"outputImage"];

вы можете захватить CGRect для прямоугольника размером с исходное изображение в центре этого resultImage:

// note, adjust rect because blur changed size of image

CGRect rect             = [resultImage extent];
rect.origin.x          += (rect.size.width  - viewImage.size.width ) / 2;
rect.origin.y          += (rect.size.height - viewImage.size.height) / 2;
rect.size               = viewImage.size;

а затем используйте CIContext чтобы захватить эту часть изображение:

CIContext *context      = [CIContext contextWithOptions:nil];
CGImageRef cgimg        = [context createCGImage:resultImage fromRect:rect];
UIImage   *blurredImage = [UIImage imageWithCGImage:cgimg];
CGImageRelease(cgimg);

альтернативно, для iOS 7, Если вы идете в iOS UIImageEffects пример кода скачать iOS_UIImageEffects.zip, вы можете затем захватить


более быстрое решение-полностью избежать CGImageRef и выполнить все преобразования на ленивом уровне CIImage.

Итак, вместо неуместного:

// create UIImage from filtered image (but size is wrong)
blurredImage = [[UIImage alloc] initWithCIImage:resultImage];

хорошее решение-написать:

С

// cropping rect because blur changed size of image
CIImage *croppedImage = [resultImage imageByCroppingToRect:imageToBlur.extent];
// create UIImage from filtered cropped image
blurredImage = [[UIImage alloc] initWithCIImage:croppedImage];

Swift 3

// cropping rect because blur changed size of image
let croppedImage = resultImage.cropping(to: imageToBlur.extent)
// create UIImage from filtered cropped image
let blurredImage = UIImage(ciImage: croppedImage)

Swift 4

// cropping rect because blur changed size of image
let croppedImage = resultImage.cropped(to: imageToBlur.extent)
// create UIImage from filtered cropped image
let blurredImage = UIImage(ciImage: croppedImage)

похоже, что фильтр размытия возвращает вам изображение, которое больше, чем то, с которым вы начали, что имеет смысл, поскольку пиксели по краям размываются мимо них. Самым простым решением, вероятно, было бы сделать newView использовать contentMode of UIViewContentModeCenter поэтому он не пытается раздавить размытое изображение; вы также можете обрезать blurredImage рисуя его в центре нового контекста соответствующего размера, но вам это действительно не нужно.