在iOS上快速模糊

时间:2012-09-04 20:37:55

标签: objective-c image image-processing uiimageview core-graphics

我在尝试模糊iOS应用中的部分屏幕时遇到了麻烦。请参阅图片以更好地了解我正在尝试做什么。

BlurBox

只有“BlurBox”的内容需要模糊,但其余内容可以清晰。因此,如果您正在查看表格视图,则只有BlurBox下方的内容会模糊(即使您滚动)。其余的看起来很清楚。

我的第一个方法是每隔.01s调用UIGraphicsGetImageFromCurrentImageContext()以将BlurBox下的所有图层组合成一个图像。然后模糊该图像并将其显示在所有内容上。

我试图模糊的方法是:

https://github.com/tomsoft1/StackBluriOS

https://github.com/coryleach/UIImageAdjust

https://github.com/esilverberg/ios-image-filters

https://github.com/cmkilger/CKImageAdditions

[layer setRasterizationScale:0.25];
[layer setShouldRasterize:YES];

以及一些自定义尝试。我也看过Apple的GLImageProcessing,但我认为我在这里尝试做的事情有点过分。

问题在于它们都 。该应用程序不在应用程序商店上,所以我愿意使用任何私有/未记录的框架。

我有一种很远的想法是覆盖我使用的所有组件的drawRect方法(UITableViewCells,UITableView等),并在运行中独立地模糊每个组件。然而,这需要一些时间,这听起来像是一个可行的选择吗?


更新

我尝试使用CIFilters,如下所示:

CIImage *inputImage = [[CIImage alloc] initWithImage:[self screenshot]];

CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
[blurFilter setDefaults];
[blurFilter setValue: inputImage forKey: @"inputImage"];
[blurFilter setValue: [NSNumber numberWithFloat:10.0f]
                           forKey:@"inputRadius"];


CIImage *outputImage = [blurFilter valueForKey: @"outputImage"];

CIContext *context = [CIContext contextWithOptions:nil];

self.bluredImageView.image = [UIImage imageWithCGImage:[context createCGImage:outputImage fromRect:outputImage.extent]];

这确实有效,但速度非常慢。 :(

我发现只有当我传入从磁盘加载的图像时,某些实现才会模糊。如果我传入我使用UIGraphicsGetImageFromCurrentImageContext()创建的UIImage,它就不起作用。关于为什么会这样的任何想法?


更新

我已经尝试过如下的Patel建议:

CALayer *backgroundLayer = [CALayer layer];

CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
[blurFilter setDefaults];
backgroundLayer.backgroundFilters = [NSArray arrayWithObject:blurFilter];

[[self.view layer] addSublayer:backgroundLayer];

然而,它不起作用:(


自上次更新后更新:

我已经设法使用TomSoft1's stackblur使BlurBox正常工作,因为他添加了将图像标准化为RGBA格式(32位/像素)的功能。但是,它仍然很慢。

我有一个计时器,每0.03秒调用一次更新,以获取BlurBox下面的图像,模糊该图像,并将其显示在屏幕上。我需要帮助提高BlurBox上的“fps”。

5 个答案:

答案 0 :(得分:41)

我会推荐Brad Larson的GPUImage,它由GPU完全支持各种图像处理效果。它非常快,甚至足够快,在他的演示应用程序中,他可以从相机进行实时视频处理,并且帧速率非常好。

https://github.com/BradLarson/GPUImage

这是我编写的代码片段,用于应用基本的框模糊,模糊图像的底部和顶部三分之一,但图像的中间部分不模糊。他的图书馆非常广泛,几乎包含了可以想象的各种图像滤镜效果。

GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:[self screenshot]];

GPUImageTiltShiftFilter *boxBlur = [[GPUImageTiltShiftFilter alloc] init];
        boxBlur.blurSize = 0.5;

[stillImageSource addTarget:boxBlur];

[stillImageSource processImage];

UIImage *processedImage = [stillImageSource imageFromCurrentlyProcessedOutput];

答案 1 :(得分:7)

虽然回复可能有点迟,但您可以使用核心图像过滤器。它之所以如此缓慢,是因为这条线。

CIContext *context = [CIContext contextWithOptions:nil];

在Apple文档中,为了在Core Image中获得最佳性能,他们首先说明了

“每次渲染时都不要创建CIContext对象。 上下文存储了大量的状态信息;重用它们会更有效。“

我个人的解决方案是为Core Image Context制作一个Singleton。所以我只创造一个。

我的代码在GitHub的这个演示项目中。

https://github.com/KyleLopez/DemoCoreImage

随意使用它,或根据自己的喜好找到其他解决方案。我在CoreImage中找到的最慢的部分是上下文,之后的图像处理非常快。

答案 2 :(得分:1)

我没有对此进行过测试,但我想知道您是否可以将CALayer放置在希望框模糊的位置,然后找到可以在{{1}上设置的有用的CIFilter } CALayer's。只是一个想法。

请参阅CALayer.backgroundFilters

答案 3 :(得分:0)

您可以尝试使用Apple Core Image Filter(CIFilter)例程。它们需要iOS 5,因此您可能无法使用它们。

我不确定它是否比您尝试过的方法更快,但我过去在项目中使用它,并且效果非常好。如果您可以抓住屏幕上想要模糊的部分,将其放入图像中,将其传递过滤镜,然后在屏幕上的适当位置重新显示,这应该可行。

我使用过滤器实时更改图像的颜色,效果很好。

http://developer.apple.com/library/ios/#DOCUMENTATION/GraphicsImaging/Reference/QuartzCoreFramework/Classes/CIFilter_Class/Reference/Reference.html

答案 4 :(得分:0)

你试过这个库吗?

https://github.com/gdawg/uiimage-dsp

它使用vDSP / Accelerate框架,看起来很容易使用。

顺便说一下:0.01秒似乎太快了。 0.03也应该这样做。