模糊屏幕与iOS 7的快照API
我相信NDA已经下降了,所以我可以问这个问题。 我有一个UIView子类:
BlurView *blurredView = ((BlurView *)[self.view snapshotViewAfterScreenUpdates:NO]); blurredView.frame = self.view.frame; [self.view addSubview:blurredView];
到目前为止,它在捕获屏幕方面的工作,但现在我想模糊这个观点。 我究竟如何去做呢? 从我读过的东西中,我需要捕获视图的当前内容(上下文?!),并将其转换为CIImage(否),然后将CIGaussianBlur应用于视图并将其拖回视图。
我到底怎么做?
PS视图不是animation,所以它应该是性能明智的。
编辑:这是我迄今为止。 问题是我无法捕捉快照到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 -.-
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; }
来自WWDC的示例代码ios_uiimageeffects
有一个名为UIImage+ImageEffects
的UIImage
类别
这是它的API:
- (UIImage *)applyLightEffect; - (UIImage *)applyExtraLightEffect; - (UIImage *)applyDarkEffect; - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor; - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage;
由于法律上的原因,我不能在这里展示实现,这里有一个演示项目。 应该很容易开始。
这个问题的一半没有得到答案,所以我认为值得补充。
UIScreen的问题
- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates
和UIView的
- (UIView *)resizableSnapshotViewFromRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates withCapInsets:(UIEdgeInsets)capInsets
难道你不能从他们那里得到一个UIImage – “黑屏”的问题。
在iOS7中,Apple提供了第三个用于提取UIImages的API,这是UIView上的一个方法
- (BOOL)drawViewHierarchyInRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates
它不如snapshotView
,但与renderInContext
相比并不差(在Apple提供的例子中,它比renderInContext
快renderInContext
,比snapshotView
慢三倍)
使用示例:
UIGraphicsBeginImageContextWithOptions(image.size, NULL, 0); [view drawViewHierarchyInRect:rect]; UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
然后得到一个模糊的版本
UIImage* lightImage = [newImage applyLightEffect];
其中applyLightEffect
是被接受的答案中提到的苹果的UIImage+ImageEffects
类别中的那些模糊类别方法之一(在接受的答案中UIImage+ImageEffects
这个代码示例的链接不起作用,但是这一个会让你到正确的页面 :文件你想要的是iOS_UIImageEffects
)。
主要参考WWDC2013会话226, 在iOS上实现使用UI
顺便说一句,在苹果的参考文档renderInContext
暗示黑屏问题有一个有趣的笔记..
重要提示:此方法的OS X v10.5实现不支持整个Core Animation组合模型。 不呈现QCCompositionLayer,CAOpenGLLayer和QTMovieLayer图层。 此外,不使用3D变换的图层,也不绘制指定backgroundFilters,filters,compositingFilter或蒙版值的图层。 未来版本的OS X可能会添加对渲染这些图层和属性的支持。
这个笔记从10.5开始没有更新,所以我猜“未来的版本”可能还有一段时间了,我们可以添加新的CASnapshotLayer
(或其他)到列表中。
总结如何使用代工厂的示例代码执行此操作,请使用以下代码:
我想模糊整个屏幕只是为了我的目的,所以我会使用主屏幕边界。
CGRect screenCaptureRect = [UIScreen mainScreen].bounds; UIView *viewWhereYouWantToScreenCapture = [[UIApplication sharedApplication] keyWindow]; //screen capture code UIGraphicsBeginImageContextWithOptions(screenCaptureRect.size, NO, [UIScreen mainScreen].scale); [viewWhereYouWantToScreenCapture drawViewHierarchyInRect:screenCaptureRect afterScreenUpdates:NO]; UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); //blur code UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0]; UIImage *blurredImage = [capturedImage applyBlurWithRadius:1.5 tintColor:tintColor saturationDeltaFactor:1.2 maskImage:nil]; //or use [capturedImage applyLightAffect] but I thought that was too much for me //use blurredImage in whatever way you so desire!
屏幕截图部分的注释
UIGraphicsBeginImageContextWithOptions()
第二个参数是不透明的。 它应该是NO
除非你除了1
之外没有任何alpha
。 如果您返回yes屏幕截图不会查看透明度值,所以它会更快,但可能是错误的。
UIGraphicsBeginImageContextWithOptions()
第三个参数是比例。 可能要像我那样放置在设备的规模,以确定和区分视网膜和非视网膜。 但我没有真正testing这个,我认为0.0f
也可以。
drawViewHierarchyInRect:afterScreenUpdates:
注意你为屏幕更新返回BOOL
。 我试图在背景之前这样做,如果我没有把NO
放到前台,那么应用程序会发生故障。 如果你不离开应用程序,你也许可以脱离YES
。
注意模糊
我在这里有一个非常轻的模糊。 更改blurRadius将使其变得模糊,并且可以更改色调颜色和alpha以制作各种其他效果。
你也需要添加模糊方法的类别工作…
如何添加UIImage + ImageEffects类别
您需要下载类别UIImage + ImageEffects模糊工作。 login后在此处下载: https : //developer.apple.com/downloads/index.action?name=WWDC%202013
search“UIImageEffects”,你会发现它。 只需拿出2个必要的文件,并将其添加到您的项目。 UIImage + ImageEffects.h和UIImage + ImageEffects.m。
此外,我必须在我的构build设置中启用模块,因为我有一个项目,而不是与xCode 5创build。要做到这一点去你的目标生成设置和search“模块”,并确保“启用模块”和“链接框架自动“都设置为是,否则您将有新类别的编译器错误。
祝你好运模糊!
检查WWDC 2013示例应用程序“快速运行”。
模糊是作为一个类别实现的。