iOS APP界面黑白化处理(悼念日)

iOS本身在这只里面是有色盲模式的,打开后效果极佳,可以说是最好的灰度处理了。但是苹果平没有放开这个API,我们也无法要求用户在特定时间打开它。
而且这个功能是把整个手机都置灰了。iOS APP界面的灰度处理不能像web和安卓那样简单,但是也有方法。

这里根据网络资料整理的两种方案。我们项目目前就是这两种方案混合使用的。

方案一

最开始就想的就是能不能想web那样一键处理,或者增加一个滤镜什么的,简单便捷,不需要处理一个个控件。
将App所有的视图通过滤镜,都变为灰色,也就是在window或者首页的view上添加这样一种灰色滤镜效果,使得整个App界面或者首页变为灰色


+ (void)addGreyFilterToView:(UIView *)view {
  UIView *greyView = [[UIView alloc] initWithFrame:view.bounds];
  greyView.userInteractionEnabled = NO;
  greyView.tag = kFJFGreyFilterTag;
  greyView.backgroundColor = [UIColor lightGrayColor];
  greyView.layer.compositingFilter = @"saturationBlendMode";
  greyView.layer.zPosition = FLT_MAX;
  [view addSubview:greyView];
}

+ (void)removeGreyFilterToView:(UIView *)view {
  UIView *greyView = [view viewWithTag:kFJFGreyFilterTag];
  [greyView removeFromSuperview];
}

该方法的主要原理是设置一个浅灰色的lightGrayColor的颜色,然后将该浅灰色的饱和度,应用到将要显示的视图上,使得将要显示的视图,显示灰色。

饱和度是指色彩的鲜艳程度,也称色彩的纯度。饱和度取决于该色中含色成分和消色成分(灰色)的比例。含色成分越大,饱和度越大;消色成分越大,饱和度越小。

最新实测:iOS12.4;12.5会出现bug。

方案二

对UIColor、UIImage、UIImageView、WKWebView等进行各个处理.

  1. 图片二值化处理
  2. color
  3. H5页面
  1. 图片处理
- (UIImage *)grayImage {
    const int RED =1;
    const int GREEN =2;
    const int BLUE =3;
    
    // Create image rectangle with current image width/height
    CGRect imageRect = CGRectMake(0,0, self.size.width* self.scale, self.size.height* self.scale);
    
    int width = imageRect.size.width;
    int height = imageRect.size.height;
    
    // the pixels will be painted to this array
    uint32_t *pixels = (uint32_t*) malloc(width * height *sizeof(uint32_t));
    
    // clear the pixels so any transparency is preserved
    memset(pixels,0, width * height *sizeof(uint32_t));
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    
    // create a context with RGBA pixels
    CGContextRef context = CGBitmapContextCreate(pixels, width, height,8, width *sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
    
    // paint the bitmap to our context which will fill in the pixels array
    CGContextDrawImage(context,CGRectMake(0,0, width, height), [self CGImage]);
    
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            uint8_t *rgbaPixel = (uint8_t*) &pixels[y * width + x];
            
            // convert to grayscale using recommended method: http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
            uint32_t gray = 0.3 * rgbaPixel[RED] +0.59 * rgbaPixel[GREEN] +0.11 * rgbaPixel[BLUE];
            
            // set the pixels to gray
            rgbaPixel[RED] = gray;
            rgbaPixel[GREEN] = gray;
            rgbaPixel[BLUE] = gray;
        }
    }
    
    // create a new CGImageRef from our context with the modified pixels
    CGImageRef imageRef = CGBitmapContextCreateImage(context);
    
    // we're done with the context, color space, and pixels
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    free(pixels);
    
    // make a new UIImage to return
    UIImage *resultUIImage = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:UIImageOrientationUp];
    
    // we're done with image now too
    CGImageRelease(imageRef);
    
    return resultUIImage;
}

public func grayImage() -> UIImage? {
        
        //        获得宽度和高度数值
        let width = Int(size.width)
        let height = Int(size.height)
        
        //        创建灰度色彩空间对象,各种设备对待颜色的方式都不一样,颜色必须有一个相关的色彩空间
        let spaceRef = CGColorSpaceCreateDeviceGray()
        //        参数data指向渲染的绘制内存的地址,bitsOerComponent表示内存中像素的每个组件的位数,bytesPerRow表示每一行在内存中占的比特数,space表示使用的颜色空间,bitmapInfo表示是否包含alpha通道
        //        CGBitmapInfo().rawValue
        guard let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: 0, space: spaceRef, bitmapInfo: CGBitmapInfo().rawValue) else {
            return nil
        }
        //        然后创建一个和原视图同样尺寸的空间
        let rect = CGRect(x: 0, y: 0, width: width, height: height)
        //        在灰度上下文中画入图片
        //        context.alpha
        guard let cgImage = cgImage else {
            return nil
        }
        context.draw(cgImage, in: rect)
        //        从上下文中获取并生成专为灰度的图片
        
        if let cgImage = context.makeImage() {
            let grayImage = UIImage.init(cgImage: cgImage)
            return grayImage
        }
        return nil
    }
  1. 色值处理
+ (UIColor *)changeGrayWithColor:(UIColor *)color Red:(CGFloat)r green:(CGFloat)g blue:(CGFloat)b alpha:(CGFloat)a {
    CGFloat gray = r * 0.299 +g * 0.587 + b * 0.114;
    UIColor *grayColor = [UIColor colorWithWhite:gray alpha:a];
    return  grayColor;
}
  1. H5
- (instancetype)lg_initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration {
    // js脚本
    NSString *jScript = @"var filter = '-webkit-filter:grayscale(100%);-moz-filter:grayscale(100%); -ms-filter:grayscale(100%); -o-filter:grayscale(100%) filter:grayscale(100%);';document.getElementsByTagName('html')[0].style.filter = 'grayscale(100%)';";
    // 注入
    WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
                 
    WKUserContentController *wkUController = [[WKUserContentController alloc] init];
       [wkUController addUserScript:wkUScript];
    // 配置对象
    WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
    wkWebConfig.userContentController = wkUController;
    configuration = wkWebConfig;
    WKWebView *webView = [self lg_initWithFrame:frame configuration:configuration];
    return webView;
}

然后对各个控件赋值取值的地方,添加一个控制开关,每次启动的时候,通过这个开关开控制方法。

也可以通过黑魔法交换方法。将原来的赋值方法替换为我们需要的结果方法。

ps: xib需要特殊处理。

网络转发总结,参考文章如下:

参考文章:iOS APP界面黑白化处理灰度处理
iOS 一键哀悼模式

你可能感兴趣的:(iOS APP界面黑白化处理(悼念日))