iOS 7 흐림보기와 유사한 효과를 만들려면 어떻게해야합니까?


219

Apple이 공개적으로 출시 한 iOS 7 예제 화면 에서이 흐린 배경을 복제하려고합니다.

iOS 7 제어 센터 스크린 샷

이 질문 은 CI 필터를 아래 내용에 적용하는 것을 제안하지만 완전히 다른 접근법입니다. iOS 7은 여러 가지 이유로 아래보기의 내용을 캡처하지 않습니다.

  1. 거친 테스트를 수행하고 아래 뷰의 스크린 샷을 캡처하고 iOS 7의 블러 스타일을 모방하기에 충분히 큰 반경을 가진 CIGaussianBlur 필터를 적용하면 시뮬레이터에서도 1-2 초가 걸립니다.
  2. iOS 7 흐림보기는 눈에 띄게 지연없이 비디오 또는 애니메이션과 같은 동적보기를 흐리게 처리 할 수 ​​있습니다.

누구나이 효과를 만들기 위해 사용할 수있는 프레임 워크를 가정하고 현재 공개 API로 비슷한 효과를 만들 수 있습니까?

편집 : (의견에서) 우리는 Apple이 어떻게하고 있는지 정확히 알지 못하지만 기본적인 가정이 있습니까? 우리는 그들이 하드웨어를 사용한다고 가정 할 수 있습니다.

효과가 각보기에 자체적으로 포함되어있어 효과가 실제로 뒤에있는 것을 알 수 없습니까? 또는 흐림 효과의 작동 방식에 따라 흐림 효과의 내용을 고려해야합니까?

효과 뒤에있는 내용이 관련이있는 경우 Apple에서 아래 내용의 "피드"를 수신하고 계속해서 흐리게 렌더링한다고 가정 할 수 있습니까?


(애플이 순수한 GL을 사용하여 홈 화면을 렌더링한다고 가정 할 수있다. UIViews 및 OS의 핵심 부분이기 때문에 성능을 저하시킬 수있는 다른 것들로 애플릿을 추상화하고 있다고 의심한다)
Dave

내 답변에 대한 의견에서 여기에 표시된 것처럼 : stackoverflow.com/a/17048668/19679 그들은 OS를 작성 했으므로 물론 현재보기 아래에 합성 된 레이어의 내용에 대한 액세스를 가속화 할 것입니다. : 우리는 그들이 민간 IOSurface의 API에서 사용하고있는 것의 일부 볼 수 있습니다 stackoverflow.com/questions/14135215/...을 . 가우스 흐림은 반경이 고정되어 있거나 통합 이미지와 같은 흥미로운 최적화를 사용하는 경우 일반 가우시안 흐림보다 훨씬 빠르게 만들 수 있습니다.
Brad Larson

@BradLarson-Jessica Simpson의 말을 바꾸면 ... 그게 무슨 뜻인지 모르겠지만, 멋지다! 그러나 진지하게, 당신은 블러 필터와 함께 부분적으로 투명한 뷰를 사용 하고이 효과를 달성하기 위해 다른 뷰 위에 놓을 수 있다고 말하고 있습니까?
sangony

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이 도구 모음 / 뷰 또는 아무것도 같은, 또는 일어날 나쁜 일들을. 또한 내부에 사례를 구축하기 위해이 문제에 대한 레이더 버그 보고서를 제출할 것을 강력히 제안했습니다.
smileyborg

44
흥미롭게도 @ user2342340 계정은이 질문에 익명으로 응답하기 위해 만들어진 것 같습니다. 이 내용에 대해 우리 이외의 다른 사람보다 더 잘 아는 사람이 비공식 게시물이 아닌지 궁금해합니다.)
smileyborg

4
iOS 7을 실행하는 iPhone 4에서는 작동하지 않습니다. 아마도 iPhone 4에서는 GPU 성능이 너무 낮아서 일반적인 흐림 효과를 UITabBar자체적으로 추가하지 않기 때문일 수 있습니다.
Ayush Goel

2
흰색이 아닌 것을 어떻게 만드나요? 툴바의 배경색을 변경해도 흐림이 표시되지 않습니다.
Nikita P

64

Apple은 WWDC에서이 기능을 포함하는 UIImage의 범주로 코드를 출시했습니다. 개발자 계정이있는 경우 https://developer.apple 링크로 이동하여 UIImage 범주 (및 나머지 샘플 코드)를 가져올 수 있습니다 . com / wwdc / schedule / 및 섹션 226을 찾아보고 세부 정보를 클릭하십시오. 나는 아직 그것을 가지고 놀지 않았지만 iOS 6에서는 효과가 훨씬 느려질 것이라고 생각합니다 .iOS 7에는 흐림으로의 입력으로 사용되는 초기 스크린 샷을 훨씬 더 빨리 잡는 기능이 향상되었습니다.

직접 링크 : https://developer.apple.com/downloads/download.action?path=wwdc_2013/wwdc_2013_sample_code/ios_uiimageeffects.zip


1
비디오를보고 볼 수는 있지만 샘플 코드를 다운로드 할 위치를 알 수 없습니다!
Nathan H

나는 단순한 배경 알파 변화와 비교할 때 큰 차이를 보지 못했습니다. 아마 내가 비디오를 표시하고 있기 때문에 더 많은 흐림 효과가 필요하기 때문에 ...
Ja –ck

37

실제로 이것은 달성하기가 다소 간단 할 것이라고 확신합니다. 아마도 애플이 작동하는 것과 똑같이 작동하거나 보이지 않을 수도 있지만 매우 가까울 수 있습니다.

우선, 제시 할 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를 다시 수신 했으므로 이제 남은 것은 흐릿한 이미지를 표시 할 뷰의 배경으로 설정하는 것입니다. 내가 말했듯이, 이것은 애플이하는 일과 완벽하게 일치하지는 않지만 여전히 멋지게 보일 것입니다.

도움이 되길 바랍니다.


흐릿한 이미지의 파란색과 빨간색이 흔들린 것 같습니다.
Henry

누군가가이 프로젝트를 생성하는 코드를 사용하는 것 같습니다 : github.com/alexdrone/ios-realtimeblur/blob/master/RealTimeBlur/...을 하지만 불행히도 어떤 속성이 없다, 그들은는 "판권 소유"저작권 문을 추가 한 상단에.
Mark Erdmann

@ 마크, 고마워요. 그러나이 흐림 알고리즘은 내 것이 아닙니다. 나는 이미 위의 게시물에서 어디서 얻었는지 언급했습니다. 내 게시물에서 알 수 있듯이 "이것은 여기서 찾을 수있는 알고리즘을 기반으로합니다." indieambitions.com/idevblogaday/…에 대한 링크와 함께 나는 확실히이 사람에게 메시지를 보내고 그들이 속성이 누락되었음을 알릴 것이다. 감사합니다
Jeremy Fox

@MarkErdmann은 xcode에서 자신의 파일을 살펴 봅니다. "모든 권리 보유"가 있습니다. xcode가 추가하는 일반적인 것입니다. 또한 저자는 방금 라이센스에 따라 라이센스를 부여한 license.md를 추가했습니다
Santa Claus

를 사용하지 말고 renderInContext새로운 drawViewHierarchyInRect:또는를 사용하십시오 snapshotView:. WWDC 토크 216 "iOS7에서 매력적인 UI 구현"은 5-15 배의 성능 향상을 요구합니다.
bcattle

25

iOS8이이 질문에 대답했습니다.

UIVisualEffect

- (instancetype)initWithEffect:(UIVisualEffect *)effect

또는 스위프트 :

init(effect effect: UIVisualEffect)


iOS 9가 나올 때 까지이 솔루션은 거의 쓸모가 없다고 생각합니다. 대부분의 응용 프로그램은 여전히 ​​iOS 7을 지원하며이 솔루션은 지원되지 않습니다.
Dmitry Sobolev

진정한 사실, 당신은 지금 이런 종류의 일을 사용할 수 있습니다 github.com/nicklockwood/FXBlurView
아담 웨이트

iOS8이있는 Xcode 6 툴체인으로 이것을 구현했으며 훌륭하게 작동합니다. CPU를 사용하여 구현하려고 시도했지만이 방법보다 눈에 띄게 느리게 작동합니다.
Jon

Xcode가 스토리 보드 자체에서 제공 할 때 코딩 해야하는 이유 !!!!! 감사합니다 @AdamWaite
Mihir Oza

20

방금 모든 사용자 정의보기에서 기본 iOS 7 흐림 효과를 생성 할 수있는 UIView의 작은 하위 클래스를 작성했습니다. UIToolbar를 사용하지만 실시간 애니메이션으로 프레임, 경계, 색상 및 알파를 안전하게 변경할 수 있습니다.

문제가 발견되면 알려주십시오.

https://github.com/ivoleko/ILTranslucentView

ILTranslucentView 예제


UIToolbar를 직접 추가하거나 Apple의 UIImage + ImageEffects.h 카테고리를 추가하는 것과 같은 다른 접근법을 시도했습니다. 당신은 가장 쉽고 쉬운 솔루션이었습니다. 감사!
Yunus Nedim Mehel

4
새로운 iOS 7.0.3 다운로드에 얼마나 잘 반응합니까? 이 기술을 사용하고 다른 클래스가 더 이상 제대로 렌더링되지 않습니다 : [
아치

@achi, iOS 7.0.3에 아무런 문제가 없었습니다.
Ivo Leko

귀하의 접근 방식을 사용하여 애니메이션을 적용하고 Apple에서 승인 한 앱이 있는지 알고 있습니까?
브래드 고스

여러분 안녕하세요. 예,이 클래스를 사용하는 앱은 Apple에서 승인합니다!
Ivo Leko

10

애플 엔지니어가 주장하는 소문이 있는데,이 성능을 gpu 버퍼에서 직접 읽으면 보안 문제가 발생하여 아직 공개 API가없는 이유가 있습니다.


6
이것이 사실이라면 그것은 최악의 해결책입니다.
elslooo

2
aaaaaand 흐림은 iOS 7에서 제거되었습니다.
Code Guru

3
성능 문제가 발생한 장치에서만 제거되었습니다.
Cody C

24
이 게시물이 소문의 출처입니까? :)
Jano

11
그 소문은 아마 이층 일 것이다. iOS의 OpenGL ES 2.0을 사용하면 보안 위험없이 프레임 버퍼를 읽고 쓸 수 있습니다. 블러는 GLSL 쉐이더를 사용하여 수행되므로 빠르게 실행됩니다.
bentford

7

이것은 WWDC의 비디오에서 볼 수있는 솔루션입니다. 가우시안 블러 (Gaussian Blur)를해야하므로 가장 먼저해야 할 일은 여기에 쓰고있는 코드로 새로운 .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 페이지의 Apple DEMO에서 솔루션을 찾고 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을 사용 하고 있습니다. 이 기능은 성능이 높은 우선 순위 요구 사항이 아닌 경우이 기능은 실제로 매우 느립니다.하지만 두 View Controller간에 전환에 사용하는 경우 (예 :)이 방법은 1 이상의 시간을 의미합니다 두 번째 이상은 응용 프로그램의 사용자 경험에 매우 나쁩니다.

이 모든 이미지 처리를 GPU에 두는 것을 선호한다면 (그리고 당신은) 훨씬 더 나은 효과를 얻을 수 있고 50ms를 반올림하는 놀라운 시간을 얻을 수 있습니다 (첫 번째 접근 방식에서 1 초의 시간이 있다고 가정). .

먼저 여기 에서 GPUImage Framework (BSD 라이센스)를 다운로드 하십시오 .

다음으로 GPUImage에서 다음 클래스 (.m 및 .h)를 추가하십시오 (흐림 효과에만 필요한 최소 클래스인지 확실하지 않습니다)

  • GPUImage.h
  • GPUImageAlphaBlendFilter
  • GPUImageFilter
  • GPUImageFilterGroup
  • GPUImageGaussianBlurPositionFilter
  • GPUImageGaussianSelectiveBlurFilter
  • GPUImageLuminanceRangeFilter
  • GPUImageOutput
  • GPUImageTwoInputFilter
  • GL 프로그램
  • 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.