2013-09-22 34 views
3

我相信NDA已關閉,所以我可以問這個問題。我有一個UIView子類:模糊屏幕與iOS 7的快照API

BlurView *blurredView = ((BlurView *)[self.view snapshotViewAfterScreenUpdates:NO]); 
blurredView.frame = self.view.frame; 
[self.view addSubview:blurredView]; 

到目前爲止,它在捕獲屏幕上的工作,但現在我想模糊該視圖。我究竟如何去做這件事?從我讀過的內容中,我需要捕獲視圖(上下文?!)的當前內容並將其轉換爲CIImage(不是?),然後將CIGaussianBlur應用於它並在視圖上繪製。

我到底該怎麼做?

P.S.該視圖不是動畫,所以它應該是明智的性能。

編輯:這是我到目前爲止。問題是我無法捕捉快照到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; 
} 
+1

WWDC2013示例代碼中有一個UIImageView類別。 –

+0

我檢查了它,但它使用資源中的圖像作爲源,而我需要使用快照。我無法弄清楚。 –

回答

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; 

出於法律原因,我不能在這裏顯示的實施,有一個演示項目。應該很容易開始。

+3

這隻回答我的問題的一半。我仍然需要得到一個UIImage應用這些效果,並且這種方法給了我一個黑色的圖像:http://stackoverflow.com/questions/4334233/how-to-capture-uiview-to-uiimage-without-loss-視網膜顯示質量 –

+0

如果您只需要圖像,則不需要快照API。只需在'self.view'上直接渲染圖像? –

+0

因此,如果我不拍屏幕快照,我會在哪裏獲得圖像? –

0

檢查WWDC 2013示例應用程序 「啪的一聲跑」。

模糊是作爲一個類別實現的。

12

這個問題的一半沒有得到答案,所以我認爲值得添加。

與UIScreen的

- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates 

和UIView的的

- (UIView *)resizableSnapshotViewFromRect:(CGRect)rect 
         afterScreenUpdates:(BOOL)afterUpdates 
          withCapInsets:(UIEdgeInsets)capInsets 

的問題是,你不能從他們那裏獲得一個UIImage - 在 '黑屏' 的問題。

在iOS7蘋果提供了第三件API的用於提取UIImages,一種方法上的UIView

- (BOOL)drawViewHierarchyInRect:(CGRect)rect 
      afterScreenUpdates:(BOOL)afterUpdates 

這是不一樣快snapshotView,但不壞相比renderInContext(由蘋果它提供的示例比renderInContext快5倍,比snapshotView慢三次)

實施例使用:

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

然後得到一個模糊的版本

UIImage* lightImage = [newImage applyLightEffect]; 

其中applyLightEffect是對蘋果公司在接受的答案中提到UIImage+ImageEffects類別的那些模糊的分類方法之一(誘人連結此代碼示例中接受的答案是不行的,但是this one will get you to the right page:你想要的文件是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(或其他)到列表中。

4

總結如何與代工的示例代碼做到這一點,使用以下命令:

我想模糊整個屏幕稍稍所以我的目的,所以我會使用主屏幕邊界。屏幕捕獲部分

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()第三個參數是規模。可能想像我那樣放置設備的規模以確保區分視網膜和非視網膜。但我沒有真正測試過這個,我認爲0.0f也可以。

drawViewHierarchyInRect:afterScreenUpdates:小心你爲屏幕更新返回的內容BOOL。我在背景之前試圖做到這一點,如果我沒有放置NO,那麼當我回到前臺時,應用程序會發生故障。儘管如果你不離開應用程序,你也許可以逃脫YES

注意事項模糊

我在這裏有一個很輕的模糊。更改blurRadius會使它變得模糊,並且您可以更改色調顏色和alpha以製作各種其他效果。

你也需要添加一個類別模糊方法工作...

如何添加的UIImage + ImageEffects類別

您需要下載類別的UIImage + ImageEffects的模糊上班。登錄後在此處下載:https://developer.apple.com/downloads/index.action?name=WWDC%202013

搜索「UIImageEffects」,就可以找到它。只需拿出2個必要的文件並將它們添加到您的項目。 UIImage + ImageEffects.h和UIImage + ImageEffects.m。

此外,我必須在我的構建設置中啓用模塊,因爲我有一個項目不是使用xCode 5創建的。爲此,請轉到您的目標構建設置並搜索「模塊」並確保「啓用模塊「和」鏈接框架自動「都設置爲yes,否則編譯器會在新類別中出現錯誤。

祝你好運模糊!