iOS開發(fā)特殊日期灰色界面的實(shí)現(xiàn)

全國哀悼日期間App需要整體去彩色。采用如下方式實(shí)現(xiàn)。
先建立一個(gè)UIImageView的子類


UIImageView

用重寫setImage的方法修改。

- (void)setImage:(UIImage *)image
{
    super.image = [self makeGrayImage:image];
}

在Xcode中查找所有用到UIImageView的地方,替換成你所建立的子類。(查找范圍記得別選上pods部分,免得修改過多)
這樣SDWebImage展示圖片的方法,也會(huì)走setImage。能把所有圖片都變灰。(button等可以以此類推)。

1.可用修改圖片飽和度的方法修改

- (UIImage*)makeGrayImage:(UIImage*)image {
    //修改飽和度為0
    CIImage *beginImage = [CIImage imageWithCGImage:image.CGImage];
    CIFilter * filter = [CIFilter filterWithName:@"CIColorControls"];
    [filter setValue:beginImage forKey:kCIInputImageKey];
    //飽和度 0---2 默認(rèn)為1
    [filter setValue:0 forKey:@"inputSaturation"];

    // 得到過濾后的圖片
    CIImage *outputImage = [filter outputImage];
    // 轉(zhuǎn)換圖片, 創(chuàng)建基于GPU的CIContext對象
    CIContext *context = [CIContext contextWithOptions: nil];
    CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
    UIImage *newImg = [UIImage imageWithCGImage:cgimg];
    // 釋放C對象
    CGImageRelease(cgimg);
    return newImg;
}

優(yōu)點(diǎn):飽和度為0的過程就是圖片去色的過程。適用所有圖片不會(huì)對透明度有影響。
缺點(diǎn):
1.內(nèi)存占用較大。
2.從iOS10.4開始可以使用。
3.(會(huì)使用GPU)FPS暴漲,出現(xiàn)跳幀的現(xiàn)象。

2.可用灰度處理的方法修改

- (UIImage*)systemImageToGrayImage:(UIImage*)image{
    int width = image.size.width;
    int height = image.size.height;
    //第一步:創(chuàng)建顏色空間(說白了就是 開辟一塊顏色內(nèi)存空間)
    //圖片灰度處理(創(chuàng)建灰度空間)
 
    CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceGray();
    
    //第二步:顏色空間的上下文(保存圖像數(shù)據(jù)信息)
    //參數(shù)1:內(nèi)存大小(指向這塊內(nèi)存區(qū)域的地址)(內(nèi)存地址)
    //參數(shù)2:圖片寬
    //參數(shù)3:圖片高
    //參數(shù)4:像素位數(shù)(顏色空間,例如:32位像素格式和RGB顏色空間,8位)
    //參數(shù)5:圖片每一行占用的內(nèi)存比特?cái)?shù)
    //參數(shù)6:顏色空間
    //參數(shù)7:圖片是否包含A通道(ARGB通道)
    CGContextRef context = CGBitmapContextCreate(nil, width, height, 8, 0, colorRef, kCGImageAlphaNone);
    
    //釋放內(nèi)存
    CGColorSpaceRelease(colorRef);
    if (context == nil) {
        return nil;
    }
    //第三步:渲染圖片(繪制圖片)
    //參數(shù)1:上下文
    //參數(shù)2:渲染區(qū)域
    //參數(shù)3:源文件(原圖片)(說白了現(xiàn)在是一個(gè)C/C++的內(nèi)存區(qū)域)
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.CGImage);
    
    //第四步:將繪制顏色空間轉(zhuǎn)成CGImage(轉(zhuǎn)成可識別圖片類型)
    CGImageRef grayImageRef = CGBitmapContextCreateImage(context);
    
    //第五步:將C/C++ 的圖片CGImage轉(zhuǎn)成面向?qū)ο蟮腢IImage(轉(zhuǎn)成iOS程序認(rèn)識的圖片類型)
    UIImage* dstImage = [UIImage imageWithCGImage:grayImageRef];
    
    //釋放內(nèi)存
    CGContextRelease(context);
    CGImageRelease(grayImageRef);
    return dstImage;
}

優(yōu)點(diǎn):
1.經(jīng)過幾次測試,內(nèi)存占用比修改飽和度方法低5-10mb。
2.iOS10可以支持。
3.占用的幀率(FPS)比較低且穩(wěn)定。
缺點(diǎn):png的透明部分會(huì)變黑,(如果不對有透明部分的控件做操作,則沒問題)。
備注:kCGImageAlphaNone改為kCGImageAlphaPremultipliedLast https://blog.csdn.net/jeffasd/article/details/78142067

3.使用OpenCV實(shí)現(xiàn)(多提供一種思路)

#import <opencv2/opencv.hpp>
#import <opencv2/imgcodecs/ios.h>
- (UIImage*)opencvToGrayImage:(UIImage *)image{
    //image源文件
    if (!image){
        return nil;
    }
    // 1.將iOS的UIImage轉(zhuǎn)成c++圖片(數(shù)據(jù):矩陣)

    cv::Mat mat_image_gray;

    UIImageToMat(image, mat_image_gray);

    // 2. 將c++彩色圖片轉(zhuǎn)成灰度圖片

    // 參數(shù)一:數(shù)據(jù)源

    // 參數(shù)二:目標(biāo)數(shù)據(jù)

    // 參數(shù)三:轉(zhuǎn)換類型

    cv::Mat mat_image_dst;

    cvtColor(mat_image_gray, mat_image_dst, cv::COLOR_BGRA2GRAY);

    // 3.灰度 -> 可顯示的圖片

    cvtColor(mat_image_dst, mat_image_gray, cv::COLOR_GRAY2BGR);

    // 4. 將c++處理之后的圖片轉(zhuǎn)成iOS能識別的UIImage

    return MatToUIImage(mat_image_gray);
}

缺點(diǎn):
1.內(nèi)存占用最多。
2.使用C++編譯,與swift混編需要做很多工作。
3.導(dǎo)入庫較大,需要修改的地方很多,不完善。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容