4

NDA がダウンしていると思うので、この質問をすることができます。私は UIView サブクラスを持っています:

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

これまでのところ、画面をキャプチャする役割を果たしていますが、今度はそのビューをぼかす必要があります。これについてどうすればいいですか?私が読んだことから、ビューの現在の内容 (コンテキスト?!) をキャプチャし、それを 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 -.-

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;
}
4

4 に答える 4

13

この質問の半分は答えられなかったので、追加する価値があると思いました。

UIScreenの問題

- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates

そしてUIViewの

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

それらから UIImage を派生させることはできません - 「黒い画面」の問題です。

iOS7 では、Apple は UIImages を抽出するための 3 番目の API を提供します。これは、UIView のメソッドです。

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

ほど速くはありませんsnapshotViewが、比較すると悪くはありませんrenderInContext(Apple が提供する例では、 よりも 5 倍速く、よりrenderInContext3 倍遅くなりますsnapshotView) 。

使用例:

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

次に、ぼやけたバージョンを取得します

 UIImage* lightImage = [newImage applyLightEffect];  

applyLightEffect受け入れられた回答で言及されているAppleのカテゴリのぼかしカテゴリメソッドの1つはどこUIImage+ImageEffectsですか(受け入れられた回答のこのコードサンプルへの魅力的なリンクは機能しませんが、これは正しいページに移動します:必要なファイルはですiOS_UIImageEffects) .

主な参考文献は、WWDC2013 セッション 226、Implementing Engaging UI on iOS です。

renderInContextところで、Apple のリファレンス ドキュメントには、ブラック スクリーンの問題を示唆する興味深い記述があります。

重要: このメソッドの OS X v10.5 実装は、Core Animation コンポジション モデル全体をサポートしていません。QCCompositionLayer、CAOpenGLLayer、および QTMovieLayer レイヤーはレンダリングされません。さらに、3D 変換を使用するレイヤーはレンダリングされず、backgroundFilters、フィルター、compositingFilter、またはマスク値を指定するレイヤーもレンダリングされません。OS X の将来のバージョンでは、これらのレイヤーとプロパティのレンダリングのサポートが追加される可能性があります。

メモは 10.5 以降更新されていないため、「将来のバージョン」はまだしばらく先になる可能性があり、新しいCASnapshotLayerもの (または何でも) をリストに追加できます。

于 2014-01-18T00:36:46.910 に答える
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;

法的な理由により、ここで実装を示すことはできません。デモ プロジェクトが含まれています。簡単に始められるはずです。

于 2013-09-22T09:08:37.967 に答える
0

WWDC 2013 サンプル アプリケーションの「running with a snap」を確認します。

ぼかしはカテゴリとして実装されています。

于 2013-09-22T09:04:40.233 に答える