全國哀悼日期間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)入庫較大,需要修改的地方很多,不完善。