21

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

模糊盒

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

我的第一种方法是UIGraphicsGetImageFromCurrentImageContext()每隔 .01 秒调用一次,以将 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 将不起作用。关于为什么会这样的任何想法?


更新

我尝试了帕特尔的建议如下:

CALayer *backgroundLayer = [CALayer layer];

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

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

但是,它不起作用:(


添加赏金后的更新:

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

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

4

5 回答 5

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];
于 2012-09-09T02:42:57.873 回答
7

虽然回复可能有点晚,但您可以使用 Core Image 过滤器。它如此缓慢的原因是这条线。

CIContext *context = [CIContext contextWithOptions:nil];

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

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

我个人对此的解决方案是为核心图像上下文制作一个单例。所以我只创造一个。

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

https://github.com/KyleLopez/DemoCoreImage

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

于 2013-08-25T22:57:54.177 回答
1

我还没有对此进行测试,但我想知道您是否可以将 a 放置CALayer在您希望框模糊的位置,然后找到CIFilter可以在CALayer's backgroundFilters. 只是一个想法。

请参阅CALayer.backgroundFilters

于 2012-09-04T21:26:37.087 回答
0

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

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

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

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

于 2012-09-04T20:54:12.230 回答
0

您是否尝试过这个库:

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

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

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

于 2012-09-04T20:54:40.333 回答