使用iOS 7的快照API模糊屏幕

Nik*_*kov 4 objective-c ios ios7

我相信NDA会下降,所以我可以问这个问题.我有一个UIView子类:

BlurView *blurredView = ((BlurView *)[self.view snapshotViewAfterScreenUpdates:NO]);
blurredView.frame = self.view.frame;
[self.view addSubview:blurredView];
Run Code Online (Sandbox Code Playgroud)

它到目前为止在捕获屏幕方面做了它的工作,但现在我想模糊那个视图.我到底该怎么做?根据我的阅读,我需要捕获视图的当前内容(上下文?!)并将其转换为CIImage(不?),然后将CIGaussianBlur应用于它并将其绘制回视图.

我到底该怎么做?

PS视图没有动画,所以它应该是性能明智的.

编辑:这是我到目前为止.问题是我无法将快照捕获到UIImage,我得到一个黑屏.但是如果我直接将视图添加为子视图,我可以看到快照就在那里.

// Snapshot
UIView *view = [self.view snapshotViewAfterScreenUpdates:NO];

// Convert to UIImage
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

// Apply the UIImage to a UIImageView
BlurView *blurredView = [[BlurView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
[self.view addSubview:blurredView];
blurredView.imageView.image = img;

// Black screen -.-
Run Code Online (Sandbox Code Playgroud)

BlurView.m:

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];

    if (self) {
        // Initialization code
        self.imageView = [[UIImageView alloc] init];
        self.imageView.frame = CGRectMake(20, 20, 200, 200);
        [self addSubview:self.imageView];
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

fou*_*dry 13

这个问题的一半没有得到回答,所以我认为值得补充.

UIScreen的问题

- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates
Run Code Online (Sandbox Code Playgroud)

和UIView的

- (UIView *)resizableSnapshotViewFromRect:(CGRect)rect 
                      afterScreenUpdates:(BOOL)afterUpdates 
                           withCapInsets:(UIEdgeInsets)capInsets
Run Code Online (Sandbox Code Playgroud)

是你不能从他们那里得到一个UIImage - "黑屏"问题.

在iOS7中,Apple提供了第三个用于提取UIImages的API,这是一种关于UIView的方法

- (BOOL)drawViewHierarchyInRect:(CGRect)rect 
             afterScreenUpdates:(BOOL)afterUpdates  
Run Code Online (Sandbox Code Playgroud)

它没有那么快snapshotView,但也不差renderInContext(在Apple提供的例子中,它比它renderInContext慢五倍,慢三倍snapshotView)

使用示例:

 UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0);
 [view drawViewHierarchyInRect:rect];
 UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();  
Run Code Online (Sandbox Code Playgroud)

然后得到一个模糊的版本

 UIImage* lightImage = [newImage applyLightEffect];  
Run Code Online (Sandbox Code Playgroud)

在接受的答案中提到的applyLightEffectApple UIImage+ImageEffects类别中的Blur类别方法之一(在接受的答案中对此代码示例的诱人链接不起作用,但是这个将使您到达正确的页面:您想要的文件是iOS_UIImageEffects) .

主要参考是WWDC2013会话226,在iOS上实现 Engaging UI

顺便说一句,Apple的参考文档中有一个有趣的说明renderInContext,就是黑屏问题的暗示.

重要提示:此方法的OS X v10.5实现不支持整个Core Animation组合模型.不渲染QCCompositionLayer,CAOpenGLLayer和QTMovieLayer图层.此外,不渲染使用3D变换的图层,也不渲染指定backgroundFilters,filters,compositingFilter或蒙版值的图层.OS X的未来版本可能会添加对渲染这些图层和属性的支持.

该注释自10.5以来尚未更新,因此我猜"未来的版本"可能还有一段时间,我们可以将新的CASnapshotLayer(或其他)添加到列表中.


Kyl*_*ang 9

来自WWDC的示例代码ios_uiimageeffects

有一个UIImage名为的类别UIImage+ImageEffects

这是它的API:

- (UIImage *)applyLightEffect;
- (UIImage *)applyExtraLightEffect;
- (UIImage *)applyDarkEffect;
- (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor;

- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius 
                       tintColor:(UIColor *)tintColor 
           saturationDeltaFactor:(CGFloat)saturationDeltaFactor 
                       maskImage:(UIImage *)maskImage;
Run Code Online (Sandbox Code Playgroud)

出于法律原因,我无法在此处显示实现,其中有一个演示项目.应该很容易开始.

  • 这只回答了我问题的一半.我仍然需要一个UIImage来应用这些效果,这个方法给了我一个黑色的图像:http://stackoverflow.com/questions/4334233/how-to-capture-uiview-to-uiimage-without-loss-的品质的视网膜显示上 (3认同)