iOS の黒 (グレー) ホワイトニングの実装スキーム

ビジネスにもよりますが、通常、製品には次の 2 つの要件があります。

要件 1: すべてを白黒に設定する
要件 2: 特定のインターフェイスを白黒に設定する
大まかな実装:

オプション 1:

サーバーはすべて黒(グレー)の画像を送信し、フォントの色は動的配信に対応しています
.これはインターフェイスが1つしかない場合は問題ありませんが、すべての画像を置き換えると負荷がかかりすぎます.

オプション II:

大まかに言うと、画像、UILabel の色、UIButton の色、webView、ビデオなどです。

画像の場合、通常は UIImageView を使用して表示するため、実行時にメソッド交換を使用して setImage: メソッドを独自のものにします。
次に、プライベート メソッドで画像にフィルターを追加します

+ (void)load {     Method customMethod = class_getInstanceMethod([self クラス], @selector(setImage:));     メソッド originMethod = class_getInstanceMethod([self クラス], @selector(gl_setImage:));     method_exchangeImplementations(customMethod, originMethod);// メソッド交换}



- (void)gl_setImage:(UIImage *)image {       //白黒にするかどうか、1 はオープンを意味する     BOOL isOpenWhiteBlackModel = [[NSUserDefaults standardUserDefaults] boolForKey:@"kIsShowBlackWhiteModel"];     if (isOpenWhiteBlackModel == 1) {         [self gl_setImage :[ self gl_grayImage:image]];     } else {         [self gl_setImage:image];     } }







- (UIImage *)gl_grayImage:(UIImage *)image {         //UIKBSplitImageView是了键盘     if (image == nil || [self.superview isKindOfClass:NSClassFromString(@"UIKBSplitImageView")]) {         return image;     }     //滤镜处理     //CIPhotoEffectNoir黑白     //CIPhotoEffectMono单色     NSString *filterName = @"CIPhotoEffectMono";     CIFilter *filter = [CIFilter filterWithName:filterName];     CIImage *inputImage = [[CIImage alloc] initWithImage:image];     [filter setValue:inputImage forKey:kCIInputImageKey];     CGImageRef cgImage = [self.filterContext createCGImage:filter.outputImage fromRect:[入力画像範囲]];     UIImage *resultImg = [UIImage imageWithCGImage:cgImage];




    









    CGImageRelease(cgImage);
    resultImg を返します。
}

- (CIContext *)filterContext {     CIContext *con = objc_getAssociatedObject(self, @selector(filterContext));     if (!con) {         con = [[CIContext alloc] initWithOptions:nil];         self.filterContext = コン;     コンを返し     ます。}






- (void)setFilterContext:(CIContext *)filterContext {     objc_setAssociatedObject(self, @selector(filterContext), filterContext, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }

H5 グレー表示 - 分類

WKWebView+blackWhiteModel.m ファイル:

#import "WKWebView+blackWhiteModel.h"
#import <objc/runtime.h>

@implementation WKWebView (blackWhiteModel)
+ (void)load {     Method customMethod = class_getInstanceMethod([self クラス], @selector(gl_initWithFrame:configuration:));     メソッド originMethod = class_getInstanceMethod([self クラス], @selector(initWithFrame:configuration:));     method_exchangeImplementations(customMethod, originMethod);// メソッド交换}




- (instancetype)gl_initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
{     BOOL isOpenWhiteBlackModel = [[NSUserDefaults standardUserDefaults] boolForKey:@"kIsShowBlackWhiteModel"];     if (isOpenWhiteBlackModel) {         // 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;
        構成 = wkWebConfig;
        WKWebView *webView = [self gl_initWithFrame:フレーム構成:構成];
        webView を返します。
    戻り
    
    ます [self gl_initWithFrame:フレーム構成:構成];
} @
終了

iOS APPインターフェース 白黒処理(グレースケール処理)(記念日用に用意)

上記の解決策では、init メソッドの置き換えであり、スイッチが 0 の前の webView が色付きになり、スイッチが 1 の後の webView が灰色になるという問題があります。切り替えるかどうかをリクエストした結果は、 webView を作成する前
またはそれ以降です。

H5 グレーアウト — シングル

単一の H5 をグレー表示できます

上記の js コードと同じ:

    BOOL isOpenWhiteBlackModel = [[NSUserDefaults standardUserDefaults] boolForKey:@"kIsShowBlackWhiteModel"];
        
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    WKUserContentController *userController = [[
    WKUserContentController alloc]
    
    init]; {         //メモリアル デー モードがテーマ全体を置き換えますwkViewの色         [userController addUserScript:[self getJsStr]];     }


-(WKUserScript *)getJsStr{     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];     wkUScript を返します。}




iOS記念日モード

UILabel、UIButton などのその他の分類については、以下を参照してください。

https://github.com/GeLeis/App_NoirDemo

3番目の解決策:

画像処理は解決策 2 に似ています
が、Label、View などの色を 1 つずつ分類するのではなく、Color の分類を直接変更します。


+ (void)load {     //关键メソッド交换     メソッド customMethod = class_getClassMethod([self class], @selector(gl_colorWithRed:green:blue:alpha:));     メソッド originMethod = class_getClassMethod([self クラス], @selector(colorWithRed:green:blue:alpha:));     method_exchangeImplementations(customMethod, originMethod);// メソッド交换}




+ (UIColor *)gl_colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { // モノクロモード(白黒     モード)の場合、平均r, g, b 値     //白黒かどうか、1 はオープンを意味する     BOOL isOpenWhiteBlackModel = [[NSUserDefaults standardUserDefaults] boolForKey:@"kIsShowBlackWhiteModel"];     if (isOpenWhiteBlackModel) {         //r, g, b 発生を防ぐための重み調整, 1 0 0, 0 1 0 ,0 0 1 同じ結果         //0.2126, 0.7152, 0.0722 これらの 3 つは、r、g、b の 3 色の表面知覚に対する人間の目の強さに従って計算されます         CGFloat 輝度 = (赤 * 0.2126 + 0.7152 * green + 0.0722 * blue);         return [self gl_colorWithRed:brightness green:brightness blue:brightness alpha:alpha];     }     return [self gl_colorWithRed:red green:green blue:blue alpha:alpha]; }











iOS はアプリの白黒モードを実装します

オプション 4:

ランタイム メソッドではなく、グレー フィルターをビューに直接追加します。

    //RGBA カラー値を取得します
   CGFloat r,g,b,a;
   [[UIColor lightGrayColor] getRed:&r green:&g blue:&b alpha:&a]; //
   フィルター
   ID を作成します cls = NSClassFromString(@"CAFilter");
   id filter = [cls filterWithName:@"colorMonochrome"];
   // フィルタ パラメータを設定
   [filter setValue:@[@(r),@(g),@(b),@(a)] forKey:@"inputColor "] ;
   [filter setValue:@(0) forKey:@"inputBias"];
   [filter setValue:@(1) forKey:@"inputAmount"];
   //ウィンドウに設定
   self.window.layer.filters = [NSArray arrayWithObject:フィルター];

[UIColor lightGrayColor] の代わりに、r、g、b、および a の値を直接変更できます。

特定のコントローラーAだけなら設定するA.view.layer.filters = [NSArray arrayWithObject:filter];だけ

iOS アプリのページがグレー表示されている

もちろん、他のフィルターも使えます。

id cls = NSClassFromString(@"CAFilter");
id フィルター = [cls filterWithName:@"colorSaturate"];
[filter setValue:@(0) forKey:@"inputAmount"];
// window を設定します
self.window.layer.filters = [NSArray arrayWithObject:filter];

CALayer のフィルター

CAFilter は Apple のプライベート メソッドであり、拒否される可能性があるため、このメソッドは使用されません

最終アプローチ

クリック イベントを受信しないビューを追加する

@interface ZRLandlordHPGrayView : UIView

@終わり

@implementation ZRLandlordHPGrayView

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{     return nil; }

@終わり

次に、白黒モードを表示する必要があるインターフェイスで、次のメソッドを追加します。

- (void)showGrayViewWithSuperView:(UIView *)superView
{     //このメソッドは、白黒モードかどうかを格納するために使用されます     BOOL isOpenWhiteBlackModel = [[NSUserDefaults standardUserDefaults] boolForKey:@"kIsShowBlackWhiteModel"];     if (isOpenWhiteBlackModel) {         if ( @available( iOS 12.0, *)) {//ZRLandlordHPGrayView 12 以降のみをサポート             *overlay = [[ZRLandlordHPGrayView alloc] initWithFrame:superView.bounds];             overlay.userInteractionEnabled = NO;             overlay.translatesAutoresizingMaskIntoConstraints = false;             overlay.backgroundColor = [ UIColor grayColor] ;             overlay.layer.compositingFilter = @"saturationBlendMode";             [superView addSubview:overlay];










            [superView BringSubviewToFront:オーバーレイ];
        } }
    }

この方法は12以上しか対応しておらず、
うちのアプリを見てみると基本的に12以下はほとんどないので、最終的にこの方法にしました

その他の参考記事:
iOS インターフェース グレイイング ソリューション ディスカッションiOS でブラック マジックを使用してワンクリックでグローバル画像グレイイング ソリューションを実現する iOS 喪中モード
iOS APP インターフェース 白黒処理 (グレースケール処理) (喪日に備えて)

CALayer のフィルター
CAFilter

おすすめ

転載: blog.csdn.net/ForeverMyheart/article/details/128187220