【问题标题】:CIGaussianBlur image sizeCIGaussianBlur 图像大小
【发布时间】:2013-12-30 04:21:32
【问题描述】:

我想模糊我的视野,我使用以下代码:

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

它模糊了视图,但不是全部。如何模糊所有视图?

【问题讨论】:

    标签: ios objective-c blur core-image


    【解决方案1】:

    问题不在于它没有模糊整个图像,而是模糊扩展了图像的边界,使图像变大,结果没有正确对齐。

    为了保持图片大小不变,行后:

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

    您可以在resultImage 的中心抓取一个与原始图像大小相同的矩形CGRect

    // 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 sample code 并下载 iOS_UIImageEffects.zip,则可以获取 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,而是调用vImage high-performance image processing framework 中的vImageBoxConvolve_ARGB8888。该技术在 WWDC 2013 视频Implementing Engaging UI on iOS 中有说明。

    【讨论】:

    • 嘿,罗伯!进展如何?我知道这不是您的主要领域,但我们有一个有趣的场景,我们希望在显示之前对缓冲区进行下采样(图像数据明智)。我确定您收到了很多请求,但以防万一,这里有一个链接:stackoverflow.com/questions/57153640/…,一如既往 - 谢谢!
    【解决方案2】:

    更快的解决方案是完全避免 CGImageRef 并在 CIImage 惰性级别执行所有转换。

    所以,而不是你的不合适:

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

    一个很好的解决方案是这样写:

    目标-C

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

    斯威夫特 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)
    

    斯威夫特 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)
    

    【讨论】:

    【解决方案3】:

    看起来模糊滤镜返回的图像比您开始使用的图像更大,这是有道理的,因为边缘处的像素在它们之外变得模糊。最简单的解决方案可能是让newView 使用contentModeUIViewContentModeCenter,这样它就不会试图压扁模糊的图像;您还可以通过将blurredImage 绘制在适当大小的新上下文的中心来裁剪blurredImage,但您实际上并不需要这样做。

    【讨论】:

      猜你喜欢
      • 2015-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-11
      • 2013-09-10
      相关资源
      最近更新 更多