iOS 毛玻璃效果

直接上干货

@property (nonatomic, strong) UIImageView *screenView;

- (UIImageView *)screenView {

    if (!_screenView) {

        _screenView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];

        // blurImageWithRadius:方法是直接调用自 UIImage+ImageEffects,模糊图片的  可以搜一下,直接拿来用

        _screenView.image = [[self getNormalImage:[UIApplication sharedApplication].keyWindow] blurImageWithRadius:8];

        _screenView.backgroundColor = [UIColor whiteColor];

        [self.window addSubview:_screenView];

    }

    return _screenView;

}

// 获取屏幕截图

- (UIImage *)getNormalImage:(UIView *)view {

    // kScreenWidth和kScreenHeight均为宏定义,分别表示屏幕的宽和高

    UIGraphicsBeginImageContext(CGSizeMake(kScreenWidth, kScreenHeight));

    CGContextRef context = UIGraphicsGetCurrentContext();

    [view.layer renderInContext:context];

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

        return image;

}

- (void)applicationWillResignActive:(UIApplication *)application {

    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.

    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.

    // 判断APP当前状态,如果是从活跃状态进入switcher页面,则不进行信息保护

    if (application.applicationState != UIApplicationStateActive) {

        [UIView animateWithDuration:0.4 animations:^{

            self.screenView.alpha = 1;

        }];

    }

}





- (void)applicationDidEnterBackground:(UIApplication *)application {

    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.

    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

    [UIView animateWithDuration:0.4 animations:^{

        self.screenView.alpha = 1;

    }];

}

- (void)applicationDidBecomeActive:(UIApplication *)application {

    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

    if (_screenView) {

        [UIView animateWithDuration:0.4 animations:^{

            self.screenView.alpha = 0;

        } completion:^(BOOL finished) {

            [self.screenView removeFromSuperview];

            self.screenView = nil;

        }];

    }

}

UIImage+ImageEffects  由于上传不了这里贴一下

.h文件


@import UIKit;



@interface UIImage (ImageEffects)



#pragma mark - Blur Image



/**

*  Get blured image.

*

*  @return Blured image.

*/

- (UIImage *)blurImage;



/**

*  Get the blured image masked by another image.

*

*  @param maskImage Image used for mask.

*

*  @return the Blured image.

*/

- (UIImage *)blurImageWithMask:(UIImage *)maskImage;



/**

*  Get blured image and you can set the blur radius.

*

*  @param radius Blur radius.

*

*  @return Blured image.

*/

- (UIImage *)blurImageWithRadius:(CGFloat)radius;



/**

*  Get blured image at specified frame.

*

*  @param frame The specified frame that you use to blur.

*

*  @return Blured image.

*/

- (UIImage *)blurImageAtFrame:(CGRect)frame;



#pragma mark - Grayscale Image



/**

*  Get grayScale image.

*

*  @return GrayScaled image.

*/

- (UIImage *)grayScale;



#pragma mark - Some Useful Method



/**

*  Scale image with fixed width.

*

*  @param width The fixed width you give.

*

*  @return Scaled image.

*/

- (UIImage *)scaleWithFixedWidth:(CGFloat)width;



/**

*  Scale image with fixed height.

*

*  @param height The fixed height you give.

*

*  @return Scaled image.

*/

- (UIImage *)scaleWithFixedHeight:(CGFloat)height;



/**

*  Get the image average color.

*

*  @return Average color from the image.

*/

- (UIColor *)averageColor;



/**

*  Get cropped image at specified frame.

*

*  @param frame The specified frame that you use to crop.

*

*  @return Cropped image

*/

- (UIImage *)croppedImageAtFrame:(CGRect)frame;



@end

.m文件


#import "UIImage+ImageEffects.h"

#import <float.h>

@import Accelerate;



@implementation UIImage (ImageEffects)





- (UIImage *)applyLightEffect{

    

    UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3];

    return [self applyBlurWithRadius:30 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];

}





- (UIImage *)applyExtraLightEffect {

    

    UIColor *tintColor = [UIColor colorWithWhite:0.97 alpha:0.82];

    return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];

}





- (UIImage *)applyDarkEffect {

    

    UIColor *tintColor = [UIColor colorWithWhite:0.11 alpha:0.73];

    return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];

}





- (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor {

    

    const CGFloat EffectColorAlpha = 0.6;

    UIColor      *effectColor      = tintColor;

    int           componentCount   = (int)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:20 tintColor:effectColor saturationDeltaFactor:1.4 maskImage:nil];

}



- (UIImage *)blurImage {

    

    return [self applyBlurWithRadius:20

                           tintColor:[UIColor colorWithWhite:0 alpha:0.0]

               saturationDeltaFactor:1.4

                           maskImage:nil];

}



- (UIImage *)blurImageWithRadius:(CGFloat)radius {

    

    return [self applyBlurWithRadius:radius

                           tintColor:[UIColor colorWithWhite:0 alpha:0.0]

               saturationDeltaFactor:1.4

                           maskImage:nil];

}



- (UIImage *)blurImageWithMask:(UIImage *)maskImage {

    

    return [self applyBlurWithRadius:20

                           tintColor:[UIColor colorWithWhite:0 alpha:0.0]

               saturationDeltaFactor:1.4

                           maskImage:maskImage];

}



- (UIImage *)blurImageAtFrame:(CGRect)frame {

    

    return [self applyBlurWithRadius:20

                           tintColor:[UIColor colorWithWhite:0 alpha:0.0]

               saturationDeltaFactor:1.4

                           maskImage:nil

                             atFrame:frame];

}



- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage {

    

    // Check pre-conditions.

    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) {

            

            // A description of how to compute the box kernel width from the Gaussian

            // radius (aka standard deviation) appears in the SVG spec:

            // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement

            //

            // For larger values of 's' (s >= 2.0), an approximation can be used: Three

            // successive box-blurs build a piece-wise quadratic convolution kernel, which

            // approximates the Gaussian kernel to within roughly 3%.

            //

            // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5)

            //

            // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel.

            //

            CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];

            NSUInteger radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5);

            if (radius % 2 != 1) {

                

                radius += 1; // force radius to be odd so that the three box-blur methodology works.

            }

            

            vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, (uint32_t)radius, (uint32_t)radius, 0, kvImageEdgeExtend);

            vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, (uint32_t)radius, (uint32_t)radius, 0, kvImageEdgeExtend);

            vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, (uint32_t)radius, (uint32_t)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();

    }



    // Set up output context.

    UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);

    CGContextRef outputContext = UIGraphicsGetCurrentContext();

    CGContextScaleCTM(outputContext, 1.0, -1.0);

    CGContextTranslateCTM(outputContext, 0, -self.size.height);



    // Draw base image.

    CGContextDrawImage(outputContext, imageRect, self.CGImage);



    // Draw effect image.

    if (hasBlur) {

        

        CGContextSaveGState(outputContext);

        

        if (maskImage) {

            

            CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);

        }

        

        CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);

        CGContextRestoreGState(outputContext);

    }



    // Add in color tint.

    if (tintColor) {

        

        CGContextSaveGState(outputContext);

        CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);

        CGContextFillRect(outputContext, imageRect);

        CGContextRestoreGState(outputContext);

    }



    // Output image is ready.

    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();



    return outputImage;

}



- (UIImage *)grayScale {

    

    int width  = self.size.width;

    int height = self.size.height;

    

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

    

    CGContextRef context = CGBitmapContextCreate(nil,

                                                 width,

                                                 height,

                                                 8, // bits per component

                                                 0,

                                                 colorSpace,

                                                 kCGBitmapByteOrderDefault);

    

    CGColorSpaceRelease(colorSpace);

    

    if (context == NULL) {

        

        return nil;

    }

    

    CGContextDrawImage(context,

                       CGRectMake(0, 0, width, height), self.CGImage);

    CGImageRef image   = CGBitmapContextCreateImage(context);

    UIImage *grayImage = [UIImage imageWithCGImage:image];

    CFRelease(image);

    CGContextRelease(context);

    

    return grayImage;

}



- (UIImage *)scaleWithFixedWidth:(CGFloat)width {

    

    float newHeight = self.size.height * (width / self.size.width);

    CGSize size     = CGSizeMake(width, newHeight);

    UIGraphicsBeginImageContextWithOptions(size, NO, 0);

    

    CGContextRef context = UIGraphicsGetCurrentContext();

    

    CGContextTranslateCTM(context, 0.0, size.height);

    CGContextScaleCTM(context, 1.0, -1.0);

    

    CGContextSetBlendMode(context, kCGBlendModeCopy);

    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), self.CGImage);

    

    UIImage *imageOut = UIGraphicsGetImageFromCurrentImageContext();

    

    UIGraphicsEndImageContext();

    

    return imageOut;

}



- (UIImage *)scaleWithFixedHeight:(CGFloat)height {

    

    float newWidth = self.size.width * (height / self.size.height);

    CGSize size    = CGSizeMake(newWidth, height);

    

    UIGraphicsBeginImageContextWithOptions(size, NO, 0);

    

    CGContextRef context = UIGraphicsGetCurrentContext();

    

    CGContextTranslateCTM(context, 0.0, size.height);

    CGContextScaleCTM(context, 1.0, -1.0);

    

    CGContextSetBlendMode(context, kCGBlendModeCopy);

    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), self.CGImage);

    

    UIImage *imageOut = UIGraphicsGetImageFromCurrentImageContext();

    

    UIGraphicsEndImageContext();

    

    return imageOut;

}



- (UIColor *)averageColor {

    

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    unsigned char rgba[4];

    CGContextRef context = CGBitmapContextCreate(rgba, 1, 1, 8, 4, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

    

    CGContextDrawImage(context, CGRectMake(0, 0, 1, 1), self.CGImage);

    CGColorSpaceRelease(colorSpace);

    CGContextRelease(context);

    

    if(rgba[3] > 0) {

        CGFloat alpha = ((CGFloat)rgba[3])/255.0;

        CGFloat multiplier = alpha/255.0;

        return [UIColor colorWithRed:((CGFloat)rgba[0])*multiplier

                               green:((CGFloat)rgba[1])*multiplier

                                blue:((CGFloat)rgba[2])*multiplier

                               alpha:alpha];

    }

    else {

        return [UIColor colorWithRed:((CGFloat)rgba[0])/255.0

                               green:((CGFloat)rgba[1])/255.0

                                blue:((CGFloat)rgba[2])/255.0

                               alpha:((CGFloat)rgba[3])/255.0];

    }

}



- (UIImage *)croppedImageAtFrame:(CGRect)frame {

    

    frame = CGRectMake(frame.origin.x * self.scale,

                       frame.origin.y * self.scale,

                       frame.size.width * self.scale,

                       frame.size.height * self.scale);

    

    CGImageRef sourceImageRef = [self CGImage];

    CGImageRef newImageRef    = CGImageCreateWithImageInRect(sourceImageRef, frame);

    UIImage   *newImage       = [UIImage imageWithCGImage:newImageRef scale:[self scale] orientation:[self imageOrientation]];

    CGImageRelease(newImageRef);

    return newImage;

}



- (UIImage *)addImageToImage:(UIImage *)img atRect:(CGRect)cropRect {

    

    CGSize size = CGSizeMake(self.size.width, self.size.height);

    UIGraphicsBeginImageContextWithOptions(size, NO, self.scale);

    

    CGPoint pointImg1 = CGPointMake(0,0);

    [self drawAtPoint:pointImg1];

    

    CGPoint pointImg2 = cropRect.origin;

    [img drawAtPoint: pointImg2];

    

    UIImage* result = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    

    return result;

}



- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius

                       tintColor:(UIColor *)tintColor

           saturationDeltaFactor:(CGFloat)saturationDeltaFactor

                       maskImage:(UIImage *)maskImage

                         atFrame:(CGRect)frame

{

    UIImage *blurredFrame = \

    [[self croppedImageAtFrame:frame] applyBlurWithRadius:blurRadius

                                                tintColor:tintColor

                                    saturationDeltaFactor:saturationDeltaFactor

                                                maskImage:maskImage];

    

    return [self addImageToImage:blurredFrame atRect:frame];

}



@end

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值