背景:安全扫描过程中发现我们的App切后台的时候,截屏页面没有模糊处理,客户认为不安全,需要我们类似于银行App那种模糊处理,就有了以下解决方案。
实现思路:
1、当我们的app应用进入后台前截屏图片高斯模糊处理,
2、当我们的app进入后台后把处理了的模糊图片添加到window上
3、当我们的app进入前台后remove模糊图片
具体实现代码: 创建一个单例类来实现上述步骤:
WSScreenShotManager.h类
@interface WSScreenShotManager : NSObject
/**
单例创建对象
@return self
*/
+ (instancetype)shared;
/**
截屏处理
*/
- (void)screenShot;
- (void)showMask;
- (void)hiddenMask;
WSScreenShotManager.m类
static WSScreenShotManager * manager = nil;
@interface WSScreenShotManager ()
@property (nonatomic, strong) UIImageView *screenShotImageV;
@end
@implementation WSScreenShotManager
+ (instancetype)shared {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[self alloc] init];
});
return manager;
}
- (void)screenShot {
CGSize imageSize = CGSizeZero;
//屏幕朝向
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIInterfaceOrientationIsPortrait(orientation))
imageSize = [UIScreen mainScreen].bounds.size;
else
imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
//按理应取用户看见的那个window
for (UIWindow *window in [[UIApplication sharedApplication] windows])
{
CGContextSaveGState(context);
CGContextTranslateCTM(context, window.center.x, window.center.y);
CGContextConcatCTM(context, window.transform);
CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);
if (orientation == UIInterfaceOrientationLandscapeLeft)
{
CGContextRotateCTM(context, M_PI_2);
CGContextTranslateCTM(context, 0, -imageSize.width);
}
else if (orientation == UIInterfaceOrientationLandscapeRight)
{
CGContextRotateCTM(context, -M_PI_2);
CGContextTranslateCTM(context, -imageSize.height, 0);
} else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
CGContextRotateCTM(context, M_PI);
CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);
}
if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)])
{
[window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
}
else
{
[window.layer renderInContext:context];
}
CGContextRestoreGState(context);
}
//截取屏幕图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
//截屏图片高斯模糊处理后
UIImage *gaussianImage = [self coreGaussianBlurImage:image blurNumber:8];
//生成控件
UIImageView *bgImgv = [[UIImageView alloc] initWithImage:gaussianImage];
bgImgv.frame = CGRectMake(0, 0, imageSize.width, imageSize.height);
self.screenShotImageV = bgImgv;
}
/**
模糊 处理
@param image 要处理的image
@param blur 模糊度
@return 处理后的image
*/
- (UIImage *)coreGaussianBlurImage:(UIImage * _Nonnull)image blurNumber:(CGFloat)blur{
if (!image) {
return nil;
}
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *inputImage = [CIImage imageWithCGImage:image.CGImage];
CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
[filter setValue:inputImage forKey:kCIInputImageKey];
[filter setValue:[NSNumber numberWithFloat:blur] forKey:@"inputRadius"];
CIImage *result = [filter valueForKey:kCIOutputImageKey];
CGImageRef cgImage = [context createCGImage:result fromRect:[inputImage extent]];
UIImage *blurImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return blurImage;
}
//显示window
- (void)showMask {
[[UIApplication sharedApplication].delegate.window addSubview:self.screenShotImageV];
}
//隐藏window
- (void)hiddenMask {
[self.screenShotImageV removeFromSuperview];
}
使用方法:
- app将要切换后台时截屏保存 并处理高斯模糊图片
- app进入后台后image以window控件添加到app当前window上面
- app重新切换到前台时移除image window
- (void)applicationWillResignActive:(UIApplication *)application
{
//将要注销响应回到后台的时候截取当前屏幕
[[WSScreenShotManager shared] screenShot];
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
//进入后台
[[WSScreenShotManager shared] showMask];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
//将要进入前台
[[WSScreenShotManager shared] hiddenMask];
}
这样就实现了切后台数据模糊处理方案。