美文网首页Swift学习笔记iOS学习笔记iOS开发
iOS APP界面黑白化处理(悼念日)

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

作者: 香橙柚子 | 来源:发表于2022-12-03 11:55 被阅读0次

    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界面黑白化处理(悼念日)

        本文链接:https://www.haomeiwen.com/subject/bhxufdtx.html