如何产生类似于 iOS 7 模糊视图的效果?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17055740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:54:33  来源:igfitidea点击:

How can I produce an effect similar to the iOS 7 blur view?

iosgraphicstransparency

提问by Snowman

I'm trying to replicate this blurred background from Apple's publicly released iOS 7 example screen:

我正在尝试从 Apple 公开发布的 iOS 7 示例屏幕中复制这种模糊的背景:

iOS 7 Control Center screenshot

iOS 7 控制中心截图

This questionsuggests applying a CI filter to the contents below, but that's a whole different approach. It's obvious that iOS 7 doesn't capture the contents of the views below, for many reasons:

这个问题建议对下面的内容应用 CI 过滤器,但这是一种完全不同的方法。很明显,iOS 7 没有捕获下面视图的内容,原因有很多:

  1. Doing some rough testing, capturing a screenshot of the views below and applying a CIGaussianBlur filter with a large enough radius to mimic iOS 7's blur style takes 1-2 seconds, even on a simulator.
  2. The iOS 7 blur view is able to blur over dynamic views, such as a video or animations, with no noticeable lag.
  1. 做一些粗略的测试,捕获下面视图的屏幕截图并应用具有足够大半径的 CIGaussianBlur 过滤器来模仿 iOS 7 的模糊样式需要 1-2 秒,即使在模拟器上也是如此。
  2. iOS 7 模糊视图能够在动态视图(例如视频或动画)上进行模糊处理,没有明显的延迟。

Can anyone hypothesize what frameworks they could be using to create this effect, and if it's possible to create a similar effect with current public APIs?

任何人都可以假设他们可以使用哪些框架来创建这种效果,以及是否可以使用当前的公共 API 来创建类似的效果?

Edit:(from comment) We don't exactly know how Apple is doing it, but are there any basic assumptions we can make? We can assume they are using hardware, right?

编辑:(来自评论)我们并不完全知道 Apple 是如何做到的,但是我们可以做出任何基本假设吗?我们可以假设他们正在使用硬件,对吗?

Is the effect self-contained in each view, such that the effect doesn't actually know what's behind it? Or must, based on how blurs work, the contents behind the blur be taken into consideration?

效果是否在每个视图中都是独立的,以至于效果实际上并不知道它背后是什么?还是必须根据模糊的工作原理,考虑模糊背后的内容?

If the contents behind the effect are relevant, can we assume that Apple is receiving a "feed" of the contents below and continuously rendering them with a blur?

如果效果背后的内容是相关的,我们是否可以假设 Apple 正在接收下面内容的“提要”并不断用模糊渲染它们?

回答by user2342340

Why bother replicating the effect? Just draw a UIToolbar behind your view.

为什么要复制效果?只需在您的视图后面绘制一个 UIToolbar。

myView.backgroundColor = [UIColor clearColor];
UIToolbar* bgToolbar = [[UIToolbar alloc] initWithFrame:myView.frame];
bgToolbar.barStyle = UIBarStyleDefault;
[myView.superview insertSubview:bgToolbar belowSubview:myView];

回答by FreaknBigPanda

Apple released code at WWDC as a category on UIImage that includes this functionality, if you have a developer account you can grab the UIImage category (and the rest of the sample code) by going to this link: https://developer.apple.com/wwdc/schedule/and browsing for section 226 and clicking on details. I haven't played around with it yet but I think the effect will be a lot slower on iOS 6, there are some enhancements to iOS 7 that make grabbing the initial screen shot that is used as input to the blur a lot faster.

Apple 在 WWDC 上将代码作为包含此功能的 UIImage 类别发布,如果您有开发者帐户,则可以访问以下链接获取 UIImage 类别(以及其余示例代码):https: //developer.apple。 com/wwdc/schedule/并浏览第 226 节并单击详细信息。我还没有玩过它,但我认为 iOS 6 上的效果会慢很多,iOS 7 有一些增强功能,可以更快地抓取用作模糊输入的初始屏幕截图。

Direct link: https://developer.apple.com/downloads/download.action?path=wwdc_2013/wwdc_2013_sample_code/ios_uiimageeffects.zip

直接链接:https: //developer.apple.com/downloads/download.action?path=wwdc_2013/wwdc_2013_sample_code/ ios_uiimageeffects.zip

回答by Jeremy Fox

Actually I'd bet this would be rather simple to achieve. It probably wouldn't operate or look exactly like what Apple has going on but could be very close.

实际上,我敢打赌这会很容易实现。它可能不会运行或看起来与 Apple 正在发生的事情完全一样,但可能非常接近。

First of all, you'd need to determine the CGRect of the UIView that you will be presenting. Once you've determine that you would just need to grab an image of the part of the UI so that it can be blurred. Something like this...

首先,您需要确定将要呈现的 UIView 的 CGRect。一旦你确定你只需要抓取 UI 部分的图像,以便它可以被模糊。像这样的东西...

- (UIImage*)getBlurredImage {
    // You will want to calculate this in code based on the view you will be presenting.
    CGSize size = CGSizeMake(200,200);

    UIGraphicsBeginImageContext(size);
    [view drawViewHierarchyInRect:(CGRect){CGPointZero, w, h} afterScreenUpdates:YES]; // view is the view you are grabbing the screen shot of. The view that is to be blurred.
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Gaussian Blur
    image = [image applyLightEffect];

    // Box Blur
    // image = [image boxblurImageWithBlur:0.2f];

    return image;
}

Gaussian Blur - Recommended

高斯模糊 - 推荐

Using the UIImage+ImageEffectsCategory Apple's provided here, you'll get a gaussian blur that looks very much like the blur in iOS 7.

使用此处UIImage+ImageEffects提供的 Apple 类别,您将获得与 iOS 7 中的模糊非常相似的高斯模糊。

Box Blur

框模糊

You could also use a box blur using the following boxBlurImageWithBlur:UIImage category. This is based on an algorythem that you can find here.

您还可以使用以下boxBlurImageWithBlur:UIImage 类别使用框模糊。这是基于您可以在此处找到的算法。

@implementation UIImage (Blur)

-(UIImage *)boxblurImageWithBlur:(CGFloat)blur {
    if (blur < 0.f || blur > 1.f) {
        blur = 0.5f;
    }
    int boxSize = (int)(blur * 50);
    boxSize = boxSize - (boxSize % 2) + 1;

    CGImageRef img = self.CGImage;

    vImage_Buffer inBuffer, outBuffer;

    vImage_Error error;

    void *pixelBuffer;

    CGDataProviderRef inProvider = CGImageGetDataProvider(img);
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);

    inBuffer.width = CGImageGetWidth(img);
    inBuffer.height = CGImageGetHeight(img);
    inBuffer.rowBytes = CGImageGetBytesPerRow(img);

    inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);

    pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));

    if(pixelBuffer == NULL)
        NSLog(@"No pixelbuffer");

    outBuffer.data = pixelBuffer;
    outBuffer.width = CGImageGetWidth(img);
    outBuffer.height = CGImageGetHeight(img);
    outBuffer.rowBytes = CGImageGetBytesPerRow(img);

    error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);

    if (error) {
        NSLog(@"JFDepthView: error from convolution %ld", error);
    }

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(outBuffer.data,
                                         outBuffer.width,
                                         outBuffer.height,
                                         8,
                                         outBuffer.rowBytes,
                                         colorSpace,
                                         kCGImageAlphaNoneSkipLast);
    CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
    UIImage *returnImage = [UIImage imageWithCGImage:imageRef];

    //clean up
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);

    free(pixelBuffer);
    CFRelease(inBitmapData);

    CGImageRelease(imageRef);

    return returnImage;
}

@end

Now that you are calculating the screen area to blur, passing it into the blur category and receiving a UIImage back that has been blurred, now all that is left is to set that blurred image as the background of the view you will be presenting. Like I said, this will not be a perfect match for what Apple is doing, but it should still look pretty cool.

现在您正在计算要模糊的屏幕区域,将其传递到模糊类别并接收已模糊的 UIImage 返回,现在剩下的就是将该模糊图像设置为您将要呈现的视图的背景。就像我说的,这与 Apple 正在做的事情并不完美匹配,但它看起来应该仍然很酷。

Hope it helps.

希望能帮助到你。

回答by Adam Waite

iOS8 answered these questions.

iOS8 回答了这些问题。

UIVisualEffect

用户界面视觉效果

- (instancetype)initWithEffect:(UIVisualEffect *)effect

- (instancetype)initWithEffect:(UIVisualEffect *)effect

or Swift:

或斯威夫特:

init(effect effect: UIVisualEffect)

init(effect effect: UIVisualEffect)

回答by Ivo Leko

I just wrote my little subclass of UIView that has ability to produce native iOS 7 blur on any custom view. It uses UIToolbar but in a safe way for changing it's frame, bounds, color and alpha with real-time animation.

我刚刚编写了 UIView 的小子类,它能够在任何自定义视图上生成原生 iOS 7 模糊。它使用 UIToolbar 但以一种安全的方式通过实时动画更改它的框架、边界、颜色和 alpha。

Please let me know if you notice any problems.

如果您发现任何问题,请告诉我。

https://github.com/ivoleko/ILTranslucentView

https://github.com/ivoleko/ILTranslucentView

ILTranslucentView examples

ILTranslucentView 示例

回答by Cody C

There is a rumor that Apple engineers claimed, to make this performant they are reading directly out of the gpu buffer which raises security issues which is why there is no public API to do this yet.

有传言称,Apple 工程师声称,为了提高性能,他们直接从 gpu 缓冲区中读取数据,这会引发安全问题,这就是为什么还没有公共 API 来执行此操作的原因。

回答by Simon

Here is a really easy way of doing it:https://github.com/JagCesar/iOS-blur

这是一个非常简单的方法:https: //github.com/JagCesar/iOS-blur

Just copy the layer of UIToolbar and you're done, AMBlurView does it for you. Okay, it's not as blurry as control center, but is's blurry enough.

只需复制 UIToolbar 的图层即可完成,AMBlurView 会为您完成。好吧,它不像控制中心那么模糊,但已经足够模糊了。

Remember that iOS7 is under NDA.

请记住,iOS7 处于保密协议之下。

回答by Senry

You can find your solution from apple's DEMO in this page: WWDC 2013, find out and download UIImageEffects sample code.

您可以在此页面的苹果 DEMO 中找到您的解决方案: WWDC 2013,查找并下载 UIImageEffects 示例代码。

Then with @Jeremy Fox's code. I changed it to

然后使用@Jeremy Fox 的代码。我把它改成

- (UIImage*)getDarkBlurredImageWithTargetView:(UIView *)targetView
{
    CGSize size = targetView.frame.size;

    UIGraphicsBeginImageContext(size);
    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(c, 0, 0);
    [targetView.layer renderInContext:c]; // view is the view you are grabbing the screen shot of. The view that is to be blurred.
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return [image applyDarkEffect];
}

Hope this will help you.

希望这会帮助你。

回答by Marco Antonio Uzcategui Pescoz

This is a solution that you can see in the vidios of the WWDC. You have to do a Gaussian Blur, so the first thing you have to do is to add a new .m and .h file with the code i'm writing here, then you have to make and screen shoot, use the desired effect and add it to your view, then your UITable UIView or what ever has to be transparent, you can play with applyBlurWithRadius, to archive the desired effect, this call works with any UIImage.

这是您可以在 WWDC 的视频中看到的解决方案。你必须做一个高斯模糊,所以你要做的第一件事就是用我在这里写的代码添加一个新的 .m 和 .h 文件,然后你必须制作和屏幕拍摄,使用所需的效果和将它添加到您的视图中,然后您的 UITable UIView 或任何必须是透明的,您可以使用 applyBlurWithRadius 来存档所需的效果,此调用适用于任何 UIImage。

At the end the blured image will be the background and the rest of the controls above has to be transparent.

最后,模糊的图像将成为背景,上面的其余控件必须是透明的。

For this to work you have to add the next libraries:

为此,您必须添加下一个库:

Acelerate.framework,UIKit.framework,CoreGraphics.framework

Acelerate.framework,UIKit.framework,CoreGraphics.framework

I hope you like it.

我希望你喜欢它。

Happy coding.

快乐编码。

    //Screen capture.
    UIGraphicsBeginImageContext(self.view.bounds.size);

    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(c, 0, 0);
    [self.view.layer renderInContext:c];

    UIImage* viewImage = UIGraphicsGetImageFromCurrentImageContext();
    viewImage = [viewImage applyLightEffect];

    UIGraphicsEndImageContext();

    //.h FILE
    #import <UIKit/UIKit.h>

    @interface 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;

   @end

    //.m FILE
    #import "cGaussianEffect.h"
    #import <Accelerate/Accelerate.h>
    #import <float.h>


     @implementation UIImage (ImageEffects)


    - (UIImage *)applyLightEffect
    {
        UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3];
        return [self applyBlurWithRadius:1 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
    }


    - (UIImage *)applyExtraLightEffect
    {
        UIColor *tintColor = [UIColor colorWithWhite:0.97 alpha:0.82];
        return [self applyBlurWithRadius:1 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
    }


    - (UIImage *)applyDarkEffect
    {
        UIColor *tintColor = [UIColor colorWithWhite:0.11 alpha:0.73];
        return [self applyBlurWithRadius:1 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
    }


    - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor
    {
        const CGFloat EffectColorAlpha = 0.6;
        UIColor *effectColor = tintColor;
        int componentCount = CGColorGetNumberOfComponents(tintColor.CGColor);
        if (componentCount == 2) {
            CGFloat b;
            if ([tintColor getWhite:&b alpha:NULL]) {
                effectColor = [UIColor colorWithWhite:b alpha:EffectColorAlpha];
            }
        }
        else {
            CGFloat r, g, b;
            if ([tintColor getRed:&r green:&g blue:&b alpha:NULL]) {
                effectColor = [UIColor colorWithRed:r green:g blue:b alpha:EffectColorAlpha];
            }
        }
        return [self applyBlurWithRadius:10 tintColor:effectColor saturationDeltaFactor:-1.0 maskImage:nil];
    }


    - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage
    {
        if (self.size.width < 1 || self.size.height < 1) {
            NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self);
            return nil;
        }
        if (!self.CGImage) {
            NSLog (@"*** error: image must be backed by a CGImage: %@", self);
            return nil;
        }
        if (maskImage && !maskImage.CGImage) {
            NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage);
            return nil;
        }

        CGRect imageRect = { CGPointZero, self.size };
        UIImage *effectImage = self;

        BOOL hasBlur = blurRadius > __FLT_EPSILON__;
        BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__;
        if (hasBlur || hasSaturationChange) {
            UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
            CGContextRef effectInContext = UIGraphicsGetCurrentContext();
            CGContextScaleCTM(effectInContext, 1.0, -1.0);
            CGContextTranslateCTM(effectInContext, 0, -self.size.height);
            CGContextDrawImage(effectInContext, imageRect, self.CGImage);

            vImage_Buffer effectInBuffer;
            effectInBuffer.data     = CGBitmapContextGetData(effectInContext);
            effectInBuffer.width    = CGBitmapContextGetWidth(effectInContext);
            effectInBuffer.height   = CGBitmapContextGetHeight(effectInContext);
            effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext);

            UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
            CGContextRef effectOutContext = UIGraphicsGetCurrentContext();
            vImage_Buffer effectOutBuffer;
            effectOutBuffer.data     = CGBitmapContextGetData(effectOutContext);
            effectOutBuffer.width    = CGBitmapContextGetWidth(effectOutContext);
            effectOutBuffer.height   = CGBitmapContextGetHeight(effectOutContext);
            effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext);

            if (hasBlur) {
                CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];
                NSUInteger radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5);
                if (radius % 2 != 1) {
                    radius += 1;
                }
                vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
                vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
                vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
            }
            BOOL effectImageBuffersAreSwapped = NO;
            if (hasSaturationChange) {
                CGFloat s = saturationDeltaFactor;
                CGFloat floatingPointSaturationMatrix[] = {
                    0.0722 + 0.9278 * s,  0.0722 - 0.0722 * s,  0.0722 - 0.0722 * s,  0,
                    0.7152 - 0.7152 * s,  0.7152 + 0.2848 * s,  0.7152 - 0.7152 * s,  0,
                    0.2126 - 0.2126 * s,  0.2126 - 0.2126 * s,  0.2126 + 0.7873 * s,  0,
                                  0,                    0,                    0,  1,
                };
                const int32_t divisor = 256;
                NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]);
                int16_t saturationMatrix[matrixSize];
                for (NSUInteger i = 0; i < matrixSize; ++i) {
                    saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor);
                }
                if (hasBlur) {
                    vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);
                    effectImageBuffersAreSwapped = YES;
                }
                else {
                    vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);
                }
            }
            if (!effectImageBuffersAreSwapped)
                effectImage = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();

            if (effectImageBuffersAreSwapped)
                effectImage = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
        }

        UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
        CGContextRef outputContext = UIGraphicsGetCurrentContext();
        CGContextScaleCTM(outputContext, 1.0, -1.0);
        CGContextTranslateCTM(outputContext, 0, -self.size.height);

        CGContextDrawImage(outputContext, imageRect, self.CGImage);

        if (hasBlur) {
            CGContextSaveGState(outputContext);
            if (maskImage) {
                CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);
            }
            CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);
            CGContextRestoreGState(outputContext);
        }

        if (tintColor) {
            CGContextSaveGState(outputContext);
            CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);
            CGContextFillRect(outputContext, imageRect);
            CGContextRestoreGState(outputContext);
        }

        UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        return outputImage;
    }

回答by D33pN16h7

Every response here is using vImageBoxConvolve_ARGB8888this function is really, really slow, that is fine, if the performance is not a high priority requirement, but if you are using this for transitioning between two View Controllers (for example) this approach means times over 1 second or maybe more, that is very bad to the user experience of your application.

这里的每个响应都使用vImageBoxConvolve_ARGB8888这个函数真的很慢,这很好,如果性能不是一个高优先级的要求,但是如果你使用它在两个视图控制器之间进行转换(例如),这种方法意味着时间超过 1第二或更多,这对您的应用程序的用户体验非常不利。

If you prefer leave all this image processing to the GPU (And you should) you can get a much better effect and also awesome times rounding 50ms (supposing that you have a time of 1 second in the first approach), so, lets do it.

如果您更愿意将所有这些图像处理留给 GPU(并且您应该),您可以获得更好的效果,并且还可以在 50 毫秒内获得很棒的时间(假设您在第一种方法中的时间为 1 秒),所以,让我们这样做.

First download the GPUImage Framework (BSD Licensed) here.

首先下载GPUImage框架(BSD许可)在这里

Next, Add the following classes (.m and .h) from the GPUImage (I'm not sure that these are the minimum needed for the blur effect only)

接下来,从 GPUImage 添加以下类(.m 和 .h)(我不确定这些只是模糊效果所需的最低限度)

  • GPUImage.h
  • GPUImageAlphaBlendFilter
  • GPUImageFilter
  • GPUImageFilterGroup
  • GPUImageGaussianBlurPositionFilter
  • GPUImageGaussianSelectiveBlurFilter
  • GPUImageLuminanceRangeFilter
  • GPUImageOutput
  • GPUImageTwoInputFilter
  • GLProgram
  • GPUImageBoxBlurFilter
  • GPUImageGaussianBlurFilter
  • GPUImageiOSBlurFilter
  • GPUImageSaturationFilter
  • GPUImageSolidColorGenerator
  • GPUImageTwoPassFilter
  • GPUImageTwoPassTextureSamplingFilter

  • iOS/GPUImage-Prefix.pch

  • iOS/GPUImageContext
  • iOS/GPUImageMovieWriter
  • iOS/GPUImagePicture
  • iOS/GPUImageView
  • GPUImage.h
  • GPUImageAlphaBlendFilter
  • GPU图像过滤器
  • GPUImageFilterGroup
  • GPUImageGaussianBlurPositionFilter
  • GPUImageGaussianSelectiveBlurFilter
  • GPUImageLuminanceRangeFilter
  • GPU图像输出
  • GPUImageTwoInputFilter
  • GL程序
  • GPUImageBoxBlurFilter
  • GPUImageGaussianBlurFilter
  • GPUImageiOSBlurFilter
  • GPU图像饱和度过滤器
  • GPUImageSolidColorGenerator
  • GPUImageTwoPassFilter
  • GPUImageTwoPassTextureSamplingFilter

  • iOS/GPUImage-Prefix.pch

  • iOS/GPUImageContext
  • iOS/GPUImageMovieWriter
  • iOS/GPUImagePicture
  • iOS/GPU 图像视图

Next, create a category on UIImage, that will add a blur effect to an existing UIImage:

接下来,在 UIImage 上创建一个类别,这将为现有的 UIImage 添加模糊效果:

#import "UIImage+Utils.h"

#import "GPUImagePicture.h"
#import "GPUImageSolidColorGenerator.h"
#import "GPUImageAlphaBlendFilter.h"
#import "GPUImageBoxBlurFilter.h"

@implementation UIImage (Utils)

- (UIImage*) GPUBlurredImage
{
    GPUImagePicture *source =[[GPUImagePicture alloc] initWithImage:self];

    CGSize size = CGSizeMake(self.size.width * self.scale, self.size.height * self.scale);

    GPUImageBoxBlurFilter *blur = [[GPUImageBoxBlurFilter alloc] init];
    [blur setBlurRadiusInPixels:4.0f];
    [blur setBlurPasses:2.0f];
    [blur forceProcessingAtSize:size];
    [source addTarget:blur];

    GPUImageSolidColorGenerator * white = [[GPUImageSolidColorGenerator alloc] init];

    [white setColorRed:1.0f green:1.0f blue:1.0f alpha:0.1f];
    [white forceProcessingAtSize:size];

    GPUImageAlphaBlendFilter * blend = [[GPUImageAlphaBlendFilter alloc] init];
    blend.mix = 0.9f;

    [blur addTarget:blend];
    [white addTarget:blend];

    [blend forceProcessingAtSize:size];
    [source processImage];

    return [blend imageFromCurrentlyProcessedOutput];
}

@end

And last, add the following frameworks to your project:

最后,将以下框架添加到您的项目中:

AVFoundation CoreMedia CoreVideo OpenGLES

AVFoundation CoreMedia CoreVideo OpenGLES

Yeah, got fun with this much faster approach ;)

是的,这种更快的方法很有趣;)