iOS 7のぼかしビューに似た効果を生成するにはどうすればよいですか?


219

私はAppleの公にリリースされたiOS 7のサンプル画面からこのぼやけた背景を複製しようとしています:

iOS 7コントロールセンターのスクリーンショット

この質問は、以下のコンテンツにCIフィルターを適用することを提案していますが、それはまったく異なるアプローチです。多くの理由により、iOS 7が以下のビューのコンテンツをキャプチャしないことは明らかです。

  1. いくつかの大まかなテストを行い、下のビューのスクリーンショットをキャプチャし、iOS 7のぼかしスタイルを模倣するのに十分な大きさの半径のCIGaussianBlurフィルターを適用すると、シミュレーターでも1〜2秒かかります。
  2. iOS 7のぼかしビューは、ビデオやアニメーションなどの動的なビューをぼかすことができ、目立った遅れはありません。

誰もがこの効果を作成するために使用できるフレームワークを仮定できますか?現在のパブリックAPIで同様の効果を作成することが可能かどうか?

編集:(コメントから)Appleがどのように行っているかは正確にはわかりませんが、基本的な仮定はありますか?彼らはハードウェアを使用していると思いますよね?

エフェクトはその背後にあるものを実際に認識しないように、各ビューで自己完結型ですか?または、ぼかしの仕組みに基づいて、ぼかしの背後にあるコンテンツを考慮する必要がありますか?

エフェクトの背後にあるコンテンツに関連がある場合、Appleが以下のコンテンツの「フィード」を受信し、ぼかしを付けて継続的にレンダリングしていると想定できますか?


(私はアップルがホーム画面をレンダリングするために純粋なGLを使用していると仮定できます。OSの重要な部分であるため、UIViewやその他のパフォーマンスを低下させるもので抽象化しているのではないかと思います)
Dave

ここで私の回答へのコメントで指摘したように:stackoverflow.com/a/17048668/19679彼らはOSを作成したので、当然、現在のビューの下に合成されたレイヤーのコンテンツへのアクセスが加速されます。プライベートIOSurface APIで使用している可能性があるもののいくつかを確認できます:stackoverflow.com/questions/14135215/…。ガウスぼかしは、半径が固定されている場合、または積分画像などの興味深い最適化を使用すれば、一般化されたガウスぼかしの場合よりもはるかに速く作成できます。
ブラッド・ラーソン

@BradLarson-ジェシカ・シンプソンを言い換えると...私はそれが何を意味するのかわからないが、それは一体としてクールに聞こえる!しかし、真剣に、ぼかしフィルターを備えた部分的に透明なビューを使用して、この効果を達成するために別のビューの上に置くことができると言っていますか?
サンゴニー2013年

stackoverflow.com/a/25706250/2308190は、初めて試したときに完全に機能し、簡潔でした
Ben Wheeler

回答:


134

なぜ効果を複製するのですか?ビューの背後にUIToolbarを描画するだけです。

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

8
crizzwaldに同意しません。それはAPpleが何をするかについての期待のルールの良い解釈ではないと思います。
アンドリュージョンソン

117
今週私はApple UIKitエンジニアがTech Talksラボでこのアプローチを実行しました。彼は確かにこのアプローチを支持しませんが、効果の必要性とこれに対する実際のパブリックAPIの欠如を認識し、このアプローチは今のところ「最悪の選択肢」であり、書かれたとおりかなり安全であると述べました。具体的には、frameまたはtransformこのツールバー/ビューまたはそのようなもののアニメーションを実行しようとしないでください。そうしないと、悪いことが起こります。彼はまた、レーダーバグレポートを提出して、内部でケースを作成し、この効果のための実際のパブリックAPIを取得できるようにすることを強く提案しました。
smileyborg 2013年

44
興味深い...アカウント@ user2342340は、この質問に匿名で答えるためだけに作成されたようです。これは、これらのことについて私たちの残りの部分より多くを知っている誰かによる非公式の投稿ではないのかと不思議に思います:)
smileyborg

4
これは、iOS 7を実行しているiPhone 4では機能しません。おそらくiPhone 4では、GPUパワーが低すぎるため、システムが通常のぼかし効果を追加しないためUITabBarです。
Ayush Goel 14

2
どうすれば非白くできますか?ツールバーの背景色を変更すると、ぼかしが表示されません。
Nikita P

64

AppleはWWDCで、この機能を含むUIImageのカテゴリとしてコードをリリースしました。開発者アカウントをお持ちの場合は、https://developer.appleにアクセスして、UIImageカテゴリ(および残りのサンプルコード)を入手できます。 com / wwdc / schedule /およびセクション226を参照し、詳細をクリックします。まだ試していませんが、iOS 6では効果がかなり遅くなると思います。iOS7には、ぼかしへの入力として使用される最初のスクリーンショットの取得を大幅に高速化する拡張機能がいくつかあります。

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


1
ビデオを見ることができますが、サンプルコードをダウンロードする場所がわかりません。
Nathan H

単純な背景のアルファ変更と比較して、それほど大きな違いは見られませんでした。私は映像を表示していますし、彼らはより多くのぼかしを必要とするので、おそらくそれは...だ
ジャック・

37

実際、これは簡単に実現できると思います。おそらく動作しないか、Appleが行っているのとまったく同じには見えませんが、非常に近い可能性があります。

最初に、表示する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;
}

ガウスぼかし-推奨

ここUIImage+ImageEffects提供されているカテゴリApple を使用すると、iOS 7のぼかしによく似たガウスぼかしが得られます。

ボックスぼかし

次の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

これで、ぼかすための画面領域を計算し、ぼかしカテゴリに渡し、ぼかされたUIImageを受け取りました。あとは、表示するビューの背景として、ぼかした画像を設定するだけです。私が言ったように、これはAppleがやっていることと完全に一致するわけではありませんが、それでもかなりクールに見えるはずです。

それが役に立てば幸い。


ぼやけた画像の青色と赤色が入れ替わっているようです。
ヘンリー

誰かがあなたのコードを使用してこのプロジェクトを作成したようです:github.com/alexdrone/ios-realtimeblur/blob/master/RealTimeBlur/…しかし、残念ながら帰属はなく、「All Rights Reserved」の著作権ステートメントが追加されています頂点で。
Mark Erdmann 2013

@マーク、頭を上げてくれてありがとう。ただし、このぼかしアルゴリズムは私自身のものではありません。上記の投稿でどこから入手したかについてはすでに述べました。私の投稿で言うように、「これは、ここで見つけることができるアルゴリズムに基づいています。」indieambitions.com/idevblogaday/…へのリンクを使用して、私は間違いなくこの人物にメッセージを送信し、帰属が不明であることを通知します。ありがとう
ジェレミーフォックス

@MarkErdmannは、xcodeで独自のファイルを確認します。「All Rights Reserved」があります。これは、xcodeが追加する一般的なものです。また、作者は、ライセンスがmit lisenceに基づいて許可されていることを示すlicense.mdを追加しました
サンタクロース

使用しないでください。renderInContext新しいdrawViewHierarchyInRect:またはを使用してくださいsnapshotView:。WWDCトーク216「iOS7でのEngaging UIの実装」では、パフォーマンスが5〜15倍向上すると主張しています。
bcattle 14

25

iOS8はこれらの質問に答えました。

UIVisualEffect

- (instancetype)initWithEffect:(UIVisualEffect *)effect

またはSwift:

init(effect effect: UIVisualEffect)


このソリューションは、iOS 9がリリースされるまでほとんど役に立たないと思います。ほとんどのアプリケーションはiOS 7をサポートしており、このソリューションはサポートされていません。
Dmitry Sobolev 2014年

true true、今のところ、この種のものを使用できます:github.com/nicklockwood/FXBlurView
Adam Waite

これをiOS8のXcode 6ツールチェーンで実装しました。CPUを使用して実装しようとしましたが、この方法よりも著しく遅く動作します。
Jon

Xcodeがストーリーボード自体で提供するときにコーディングする理由!!!!! ありがとう@AdamWaite
Oza

20

私は、UIViewの小さなサブクラスを作成しました。これは、カスタムビューでネイティブiOS 7のぼかしを生成する機能を備えています。UIToolbarを使用しますが、フレーム、境界、色、アルファをリアルタイムアニメーションで安全に変更できます。

問題が発生した場合はお知らせください。

https://github.com/ivoleko/ILTranslucentView

ILTranslucentViewの例


私は他のいくつかのアプローチを試しました(自分でUIToolbarを追加する、またはAppleのUIImage + ImageEffects.hカテゴリを追加するなど)。あなたは最高で最も簡単なソリューションでした。ありがとう!
Yunus Nedim Mehel 2013年

4
新しいiOS 7.0.3ダウンロードにどれだけ反応しますか?この手法を使用した他のクラスは、正しくレンダリングされなくなりました:[
achi

@achiさん、iOS 7.0.3には何の問題もありませんでした。
Ivo Leko 2013

あなたのアプローチを使用してアニメーション化し、Appleに受け入れられているアプリがあるかどうか知っていますか?
ブラッドゴス

こんにちは、みんな。はい、このクラスを使用するアプリはAppleによって承認されます!
Ivo Leko 14

10

Appleのエンジニアが主張している噂によると、このパフォーマンスを実現するために、GPUバッファーから直接読み取りを行っているため、セキュリティの問題が発生し、これがまだこれを行うパブリックAPIがないのです。


6
これが本当なら、それは-はるかに-これまでで最悪の解決策です。
elslooo 2013

2
aaaaaandとぼかしはiOS 7から削除されました
Code Guru

3
パフォーマンスの問題が発生しているデバイスでのみ削除されました。
Cody C

24
この投稿は噂の出所ですか?:)
Jano

11
そのうわさはおそらく二段です。iOS上のOpenGL ES 2.0を使用すると、セキュリティリスクを伴うことなく、フレームバッファーの読み取りと書き込みができます。ぼかしはGLSLシェーダーを使用して行われるため、高速で実行されます。
ベントフォード2013

7

これは、WWDCのvidiosで確認できるソリューションです。あなたはガウスぼかしをしなければならないので、あなたがしなければならない最初のことは私がここに書いているコードで新しい.mと.hファイルを追加することです、そしてあなたは作ってスクリーンショットし、望ましい効果を使い、それをビューに追加してから、UITable UIViewまたは透明にする必要があるものを適用すると、applyBlurWithRadiusを使用して目的の効果をアーカイブできます。この呼び出しは、任意のUIImageで機能します。

最後に、ぼかした画像が背景になり、上のコントロールの残りは透明でなければなりません。

これを機能させるには、次のライブラリを追加する必要があります。

Acelerate.framework、UIKit.framework、CoreGraphics.framework

気に入ってくれるといいな。

ハッピーコーディング。

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

7

このページのアップルのデモからソリューションを見つけることができます: WWDC 2013、UIImageEffectsサンプルコードを見つけてダウンロードします。

次に、@ 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];
}

これがお役に立てば幸いです。


7

これは本当に簡単な方法です:https : //github.com/JagCesar/iOS-blur

UIToolbarのレイヤーをコピーするだけで完了です。AMBlurViewがそれを行います。わかりました、コントロールセンターほどぼやけていませんが、十分にぼやけています。

iOS7はNDAの下にあることに注意してください。


6

ここでのすべての応答はvImageBoxConvolve_ARGB8888を使用しています。パフォーマンスが優先度の高い要件ではない場合、この関数は本当に非常に遅く、問題ありませんが、2つのビューコントローラー間の遷移にこれを使用している場合(たとえば)、このアプローチは1を超える時間を意味します。 2番目またはそれ以上の場合、それはアプリケーションのユーザーエクスペリエンスにとって非常に悪いことです。

このすべての画像処理をGPUに任せたい場合は(そうする必要があります)、はるかに優れた効果と、50ミリ秒を丸めた素晴らしい時間を得ることができます(最初のアプローチで1秒の時間があると仮定します)。 。

まず、ここからGPUImage Framework(BSDライセンス)をダウンロードします

次に、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

次に、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

最後に、次のフレームワークをプロジェクトに追加します。

AVFoundation CoreMedia CoreVideo OpenGLES

ええ、このはるかに高速なアプローチを楽しんでいます;)


4

背景をぼかす機能のあるカスタムビューを使用してみてください。AppleのWWDCコードのように、背景のスナップショットを撮ってぼかすことでこれを行います。使い方はとても簡単です。

また、パフォーマンスを失わずに動的なぼかしを偽造するために、いくつかの改善を行いました。私のビューの背景は、ビューと共にスクロールするscrollViewであり、スーパービューの残りの部分にぼかし効果を提供します。

GitHubの例とコードを参照してください


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.