iOS 圖像的渲染模式
最近做項(xiàng)目需要減小圖片資源, 原本通過(guò)不同的背景圖片進(jìn)行界面主題等內(nèi)容切換,現(xiàn)在需要直接通過(guò)渲染改變背景圖片的顏色. 這里就涉及到圖片的渲染顏色, 這里一般而言有兩種方式.
1. 直接使用tintColor解決
iOS7的時(shí)候,UIView有一個(gè)新增加屬性叫做tintColor, 這個(gè)屬性是一個(gè)非默認(rèn)的著色顏色值, 會(huì)影響以這個(gè)View為根的所有視圖層次結(jié)構(gòu)的顏色. 我們常見(jiàn)的app圖標(biāo), navigationBar, Tabbar等控件,都有默認(rèn)的tintColor.具體的相關(guān)內(nèi)容請(qǐng)參考 詳解UIView的TintColor屬性.
其中比較特殊的是UIImageView中image的渲染顏色, 對(duì)于UIImage,我們需要設(shè)置image的渲染模式成AlwaysTemplate
, 這樣會(huì)將該圖的每一個(gè)像素如果其alpha通道為1, 那么將它的顏色設(shè)置成tintColor, 如果alpha通道不為1(半透明或者透明),那么該像素會(huì)渲染成透明, 這樣就滿(mǎn)足了我們的需求.
// 加載圖片
var image = UIImage(named: "text.jpg")
// 設(shè)置渲染模式
image = image?.imageWithRenderingMode(.AlwaysTemplate)
self.imageView?.image = image
// 設(shè)置需要渲染成的tintColor, 那么UIImage會(huì)根據(jù)每個(gè)像素是否透明進(jìn)行渲染
self.imageView.tintColor = UIColor.red
當(dāng)然UIImage也有其他的渲染模式, 默認(rèn)請(qǐng)求下UIImage渲染成圖片的原始顏色
2. 使用CoreGraphic重繪
當(dāng)前tintColor方法里面,只能改變圖片的渲染顏色, 如果對(duì)圖片還有其他的處理要求, 那么就只能通過(guò)CoreGraphic來(lái)對(duì)圖片進(jìn)行重繪了.
在圖片的拉伸每瞒,渲染和swift實(shí)現(xiàn)一個(gè)與智能機(jī)器人聊天的app(二) 文章里面提到的需求類(lèi)似, 具體的繪制方法如下:
- (UIImage *)coloredImage:(UIImage *)image red:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpa:(CGFloat)alpa {
// 獲取圖片大小
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
// 創(chuàng)建位圖繪圖上下文
UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale);
// 獲取位圖繪圖上下文并開(kāi)始渲染操作
CGContextRef context = UIGraphicsGetCurrentContext();
[image drawInRect:rect];
// 全局渲染成需要的顏色(會(huì)和圖片進(jìn)行混合, 只要設(shè)置成混合模式是kCGBlendModeSourceAtop, 就能得到圖片輪廓但是圖顏色是我們需要的顏色)
CGContextSetRGBFillColor(context, red, green, blue, alpa);
// 純色圖片渲染的關(guān)鍵設(shè)置
CGContextSetBlendMode(context, kCGBlendModeSourceAtop);
// 全局渲染顏色
CGContextFillRect(context, rect);
// 獲取到繪圖結(jié)果,結(jié)束位圖繪圖上下文并返回繪圖結(jié)果
UIImage *resulet = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resulet;
}
上面的方法就是對(duì)傳入的圖片進(jìn)行染色處理,相關(guān)的解釋在代碼里有, 但是這樣處理只能將圖片處理成純色圖片, 如果原始圖片是有一定透明度變化的的gradient圖是無(wú)法滿(mǎn)足需求的, 但是第一種使用tintColor就能滿(mǎn)足需求
其中還有一部分使用的是圖片拉伸相關(guān)內(nèi)容, 這里也貼出來(lái):
- (void)viewDidAppear:(BOOL)animated {
NSString *imageName = @"MessageBubble";
UIImage *image = [UIImage imageNamed:imageName];
// 原始的圖片
UIImageView *originView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 200, 48, 35)];
originView.image = image;
// 尖頭向右的圖片
UIImage *rightImage = [self coloredImage:image red:51/255.0 green:123/255.0 blue:214/255.0 alpa:1];
// 設(shè)置可拉伸區(qū)域
rightImage = [rightImage resizableImageWithCapInsets:UIEdgeInsetsMake(17, 21, 17.5, 26.5)];
UIImageView *rightImageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 300, 320, 100)];
rightImageView.image = rightImage;
// 尖頭向左的圖片
UIImage *leftImage = [UIImage imageWithCGImage:image.CGImage scale:2.0 orientation:UIImageOrientationUpMirrored];
leftImage = [self coloredImage:leftImage red:255/255.0 green:0.0 blue:0.0 alpa:1];
leftImage = [leftImage resizableImageWithCapInsets:UIEdgeInsetsMake(17, 26.5, 17.5, 21)];
UIImageView *leftImageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 450, 320, 100)];
leftImageView.image = leftImage;
// 將他們顯示出來(lái)
[self.view addSubview:originView];
[self.view addSubview:rightImageView];
[self.view addSubview:leftImageView];
}