一张图片,通过混合模式绘制后,能得到不同效果的图片。
这里的示例仅是测试效果;实际上可以通过不同程度的混合模式绘制,来得到符合需求的效果。
效果如下:
ViewController.h
1 #import2 3 @interface ViewController : UIViewController 4 @property (strong, nonatomic) UIImageView *imgVBlend; 5 @property (strong, nonatomic) UILabel *lblMsg; 6 7 @end
ViewController.m
1 #import "ViewController.h" 2 #import "UIImage+BlendMode.h" 3 4 @interface ViewController () 5 - (void)layoutUI; 6 - (void)changeBlendMode; 7 @end 8 9 @implementation ViewController 10 #define kImgBlend [UIImage imageNamed:@"ImageForBlend"] 11 12 - (void)viewDidLoad { 13 [super viewDidLoad]; 14 15 [self layoutUI]; 16 } 17 18 - (void)didReceiveMemoryWarning { 19 [super didReceiveMemoryWarning]; 20 // Dispose of any resources that can be recreated. 21 } 22 23 - (void)layoutUI { 24 //添加图片视图_imgVBlend 25 CGPoint newPoint = self.view.center; 26 _imgVBlend = [[UIImageView alloc] initWithImage:kImgBlend]; 27 _imgVBlend.center = newPoint; 28 //在允许进行用户交互操作前提下,通过为图片视图_imgVBlend添加点击手势识别器,来实现点击事件操作 29 _imgVBlend.userInteractionEnabled = YES; //设置是否允许进行用户交互操作;默认值为NO 30 UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self 31 action:@selector(changeBlendMode)]; 32 gesture.numberOfTouchesRequired = 1; //设置触摸手指数;默认值为1 33 gesture.numberOfTapsRequired = 1; //设置点击数;默认值为1,表示单击 34 [_imgVBlend addGestureRecognizer:gesture]; 35 [self.view addSubview:_imgVBlend]; 36 37 //添加标签_lblMsg 38 _lblMsg = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width - 40, 120)]; 39 newPoint.y += 144; 40 _lblMsg.center = newPoint; 41 _lblMsg.numberOfLines = 0; 42 _lblMsg.text = @"在屏幕中绘图时设置透明度;点击图片切换为混合模式绘制的图片"; 43 _lblMsg.textAlignment = NSTextAlignmentLeft; 44 _lblMsg.textColor = [UIColor blackColor]; 45 _lblMsg.layer.borderColor = [UIColor grayColor].CGColor; 46 _lblMsg.layer.borderWidth = 1.0; 47 [self.view addSubview:_lblMsg]; 48 49 50 // enum CGBlendMode { 51 // /* Available in Mac OS X 10.4 & later. */ 52 // kCGBlendModeNormal, 53 // kCGBlendModeMultiply, 54 // kCGBlendModeScreen, 55 // kCGBlendModeOverlay, 56 // kCGBlendModeDarken, 57 // kCGBlendModeLighten, 58 // kCGBlendModeColorDodge, 59 // kCGBlendModeColorBurn, 60 // kCGBlendModeSoftLight, 61 // kCGBlendModeHardLight, 62 // kCGBlendModeDifference, 63 // kCGBlendModeExclusion, 64 // kCGBlendModeHue, 65 // kCGBlendModeSaturation, 66 // kCGBlendModeColor, 67 // kCGBlendModeLuminosity, 68 // 69 // /* Available in Mac OS X 10.5 & later. R, S, and D are, respectively, 70 // premultiplied result, source, and destination colors with alpha; Ra, 71 // Sa, and Da are the alpha components of these colors. 72 // 73 // The Porter-Duff "source over" mode is called `kCGBlendModeNormal': 74 // R = S + D*(1 - Sa) 75 // 76 // Note that the Porter-Duff "XOR" mode is only titularly related to the 77 // classical bitmap XOR operation (which is unsupported by 78 // CoreGraphics). */ 79 // 80 // kCGBlendModeClear, /* R = 0 */ 81 // kCGBlendModeCopy, /* R = S */ 82 // kCGBlendModeSourceIn, /* R = S*Da */ 83 // kCGBlendModeSourceOut, /* R = S*(1 - Da) */ 84 // kCGBlendModeSourceAtop, /* R = S*Da + D*(1 - Sa) */ 85 // kCGBlendModeDestinationOver, /* R = S*(1 - Da) + D */ 86 // kCGBlendModeDestinationIn, /* R = D*Sa */ 87 // kCGBlendModeDestinationOut, /* R = D*(1 - Sa) */ 88 // kCGBlendModeDestinationAtop, /* R = S*(1 - Da) + D*Sa */ 89 // kCGBlendModeXOR, /* R = S*(1 - Da) + D*(1 - Sa) */ 90 // kCGBlendModePlusDarker, /* R = MAX(0, (1 - D) + (1 - S)) */ 91 // kCGBlendModePlusLighter /* R = MIN(1, S + D) */ 92 // }; 93 // typedef enum CGBlendMode CGBlendMode; /* Available in Mac OS X 10.4 & later. */ 94 } 95 96 - (void)changeBlendMode { 97 static CGBlendMode blendMode = kCGBlendModeNormal; 98 NSString *strMsg; 99 switch (blendMode) { 100 case kCGBlendModeNormal: { 101 strMsg = @"kCGBlendModeNormal: 正常;也是默认的模式。前景图会覆盖背景图"; 102 break; 103 } 104 case kCGBlendModeMultiply: { 105 strMsg = @"kCGBlendModeMultiply: 正片叠底;混合了前景和背景的颜色,最终颜色比原先的都暗"; 106 break; 107 } 108 case kCGBlendModeScreen: { 109 strMsg = @"kCGBlendModeScreen: 滤色;把前景和背景图的颜色先反过来,然后混合"; 110 break; 111 } 112 case kCGBlendModeOverlay: { 113 strMsg = @"kCGBlendModeOverlay: 覆盖;能保留灰度信息,结合kCGBlendModeSaturation能保留透明度信息,在imageWithBlendMode方法中两次执行drawInRect方法实现我们基本需求"; 114 break; 115 } 116 case kCGBlendModeDarken: { 117 strMsg = @"kCGBlendModeDarken: 变暗"; 118 break; 119 } 120 case kCGBlendModeLighten: { 121 strMsg = @"kCGBlendModeLighten: 变亮"; 122 break; 123 } 124 case kCGBlendModeColorDodge: { 125 strMsg = @"kCGBlendModeColorDodge: 颜色变淡"; 126 break; 127 } 128 case kCGBlendModeColorBurn: { 129 strMsg = @"kCGBlendModeColorBurn: 颜色加深"; 130 break; 131 } 132 case kCGBlendModeSoftLight: { 133 strMsg = @"kCGBlendModeSoftLight: 柔光"; 134 break; 135 } 136 case kCGBlendModeHardLight: { 137 strMsg = @"kCGBlendModeHardLight: 强光"; 138 break; 139 } 140 case kCGBlendModeDifference: { 141 strMsg = @"kCGBlendModeDifference: 插值"; 142 break; 143 } 144 case kCGBlendModeExclusion: { 145 strMsg = @"kCGBlendModeExclusion: 排除"; 146 break; 147 } 148 case kCGBlendModeHue: { 149 strMsg = @"kCGBlendModeHue: 色调"; 150 break; 151 } 152 case kCGBlendModeSaturation: { 153 strMsg = @"kCGBlendModeSaturation: 饱和度"; 154 break; 155 } 156 case kCGBlendModeColor: { 157 strMsg = @"kCGBlendModeColor: 颜色"; 158 break; 159 } 160 case kCGBlendModeLuminosity: { 161 strMsg = @"kCGBlendModeLuminosity: 亮度"; 162 break; 163 } 164 //Apple额外定义的枚举 165 //R: premultiplied result, 表示混合结果 166 //S: Source, 表示源颜色(Sa对应透明度值: 0.0-1.0) 167 //D: destination colors with alpha, 表示带透明度的目标颜色(Da对应透明度值: 0.0-1.0) 168 case kCGBlendModeClear: { 169 strMsg = @"kCGBlendModeClear: R = 0"; 170 break; 171 } 172 case kCGBlendModeCopy: { 173 strMsg = @"kCGBlendModeCopy: R = S"; 174 break; 175 } 176 case kCGBlendModeSourceIn: { 177 strMsg = @"kCGBlendModeSourceIn: R = S*Da"; 178 break; 179 } 180 case kCGBlendModeSourceOut: { 181 strMsg = @"kCGBlendModeSourceOut: R = S*(1 - Da)"; 182 break; 183 } 184 case kCGBlendModeSourceAtop: { 185 strMsg = @"kCGBlendModeSourceAtop: R = S*Da + D*(1 - Sa)"; 186 break; 187 } 188 case kCGBlendModeDestinationOver: { 189 strMsg = @"kCGBlendModeDestinationOver: R = S*(1 - Da) + D"; 190 break; 191 } 192 case kCGBlendModeDestinationIn: { 193 strMsg = @"kCGBlendModeDestinationIn: R = D*Sa;能保留透明度信息"; 194 break; 195 } 196 case kCGBlendModeDestinationOut: { 197 strMsg = @"kCGBlendModeDestinationOut: R = D*(1 - Sa)"; 198 break; 199 } 200 case kCGBlendModeDestinationAtop: { 201 strMsg = @"kCGBlendModeDestinationAtop: R = S*(1 - Da) + D*Sa"; 202 break; 203 } 204 case kCGBlendModeXOR: { 205 strMsg = @"kCGBlendModeXOR: R = S*(1 - Da) + D*(1 - Sa)"; 206 break; 207 } 208 case kCGBlendModePlusDarker: { 209 strMsg = @"kCGBlendModePlusDarker: R = MAX(0, (1 - D) + (1 - S))"; 210 break; 211 } 212 case kCGBlendModePlusLighter: { 213 strMsg = @"kCGBlendModePlusLighter: R = MIN(1, S + D)(最后一种混合模式)"; 214 break; 215 } 216 default: { 217 break; 218 } 219 } 220 _imgVBlend.image = [kImgBlend imageWithBlendMode:blendMode tintColor:[UIColor orangeColor]]; //使用分类Category来扩展UIImage,添加自定义实例方法imageWithBlendMode 221 _lblMsg.text = strMsg; 222 223 blendMode++; 224 if (blendMode > kCGBlendModePlusLighter) { 225 blendMode = kCGBlendModeNormal; 226 } 227 } 228 229 @end
UIImage+BlendMode.h
1 #import2 3 @interface UIImage (BlendMode) 4 - (UIImage *)imageWithBlendMode:(CGBlendMode)blendMode tintColor:(UIColor *)tintColor; 5 6 @end
UIImage+BlendMode.m
1 #import "UIImage+BlendMode.h" 2 3 @implementation UIImage (BlendMode) 4 5 - (UIImage *)imageWithBlendMode:(CGBlendMode)blendMode tintColor:(UIColor *)tintColor { 6 UIImage *img; 7 UIGraphicsBeginImageContextWithOptions(self.size, NO, 0); //开始图片上下文绘制 8 9 [tintColor setFill]; //填充颜色 10 CGRect newRect = CGRectMake(0, 0, self.size.width, self.size.height); 11 UIRectFill(newRect); 12 [self drawInRect:newRect blendMode:blendMode alpha:1.0]; //设置绘画透明混合模式和透明度 13 if (blendMode == kCGBlendModeOverlay) { 14 [self drawInRect:newRect blendMode:kCGBlendModeDestinationIn alpha:1.0]; //能保留透明度信息 15 } 16 17 img = UIGraphicsGetImageFromCurrentImageContext(); 18 19 UIGraphicsEndImageContext(); //结束图片上下文绘制 20 return img; 21 } 22 23 @end