我知道可以通过在矩形图像上绘制CGContextFillRect并设置混合模式来对其进行着色.但是,我想不出如何在透明图像(如图标)上进行着色.这必须是可能的,因为SDK在这样的选项卡栏上自己做了这件事.有人能提供一个片段吗?

更新:

自从我最初提出这个问题以来,已经给出了很多很棒的建议.一定要通读所有的答案,找出哪一个最适合你.

更新(2015年4月30日):

有了iOS7.0,我现在可以做以下事情,就可以满足我原质询的需要了.但是如果你有更复杂的情况,看看所有的答案.

UIImage *iconImage = [[UIImage imageNamed:@"myImageName"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];    
UIImageView *icon = [[UIImageView alloc] initWithImage:iconImage];
icon.tintColor = [UIColor redColor];

推荐答案

Update:使用以下代码表示SWIFT UIColor扩展的Gist.


如果你有greyscale image分,想要white become the tinting color分,那么kCGBlendModeMultiply分是合适的.使用此方法时,高光不能比染色 colored颜色 亮.

相反,如果你有non-greyscale image,OR,你有highlights 103 shadows应该保留,混合模式kCGBlendModeColor是可行的.当图像的亮度保持不变时,白色将保持白色,黑色将保持黑色.此模式仅用于着色-与Photoshop的Color图层混合模式相同(免责声明:结果可能略有不同).

请注意,着色Alpha像素在iOS和Photoshop中都不能正常工作-半透明的黑色像素不会保持黑色.我更新了下面的答案来解决这个问题,花了相当长的时间才找到答案.

也可以使用混合模式kCGBlendModeSourceIn/DestinationIn(而不是CGContextClipToMask)之一.

如果要创建UIImage,以下每个代码部分都可以由以下代码包围:

UIGraphicsBeginImageContextWithOptions (myIconImage.size, NO, myIconImage.scale); // for correct resolution on retina, thanks @MobileVet
CGContextRef context = UIGraphicsGetCurrentContext();

CGContextTranslateCTM(context, 0, myIconImage.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGRect rect = CGRectMake(0, 0, myIconImage.size.width, myIconImage.size.height);

// image drawing code here

UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

下面是将透明图像着色为kCGBlendModeColor的代码:

// draw black background to preserve color of transparent pixels
CGContextSetBlendMode(context, kCGBlendModeNormal);
[[UIColor blackColor] setFill];
CGContextFillRect(context, rect);

// draw original image
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextDrawImage(context, rect, myIconImage.CGImage);

// tint image (loosing alpha) - the luminosity of the original image is preserved
CGContextSetBlendMode(context, kCGBlendModeColor);
[tintColor setFill];
CGContextFillRect(context, rect);

// mask by alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, rect, myIconImage.CGImage);

如果您的图像没有半透明像素,您也可以使用kCGBlendModeLuminosity像素进行相反的操作:

// draw tint color
CGContextSetBlendMode(context, kCGBlendModeNormal);
[tintColor setFill];
CGContextFillRect(context, rect);

// replace luminosity of background (ignoring alpha)
CGContextSetBlendMode(context, kCGBlendModeLuminosity);
CGContextDrawImage(context, rect, myIconImage.CGImage);

// mask by alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, rect, myIconImage.CGImage);

如果你不关心亮度,因为你只是得到了一个alpha通道的图像,应该用 colored颜色 着色,你可以用一种更有效的方式来做:

// draw tint color
CGContextSetBlendMode(context, kCGBlendModeNormal);
[tintColor setFill];
CGContextFillRect(context, rect);

// mask by alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, rect, myIconImage.CGImage);

或者反过来说:

// draw alpha-mask
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextDrawImage(context, rect, myIconImage.CGImage);

// draw tint color, preserving alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
[tintColor setFill];
CGContextFillRect(context, rect);

玩得开心!

Ios相关问答推荐

自定义alert 未执行任何操作

带有动画层的UIView表示不会在工作表中设置动画

如何在iPhone 15上消除.NET Maui中状态栏和页面之间的差距

在SwiftUI中插入绘制重复形状

无法使用 NavigationView 和 NavigationLink 在 SwiftUI 中弹出当前屏幕

UIView 阴影不适用于自定义扩展

如何将 -fobjc-arc-exceptions 标志正确添加到 XCode 中?

如何在 SwiftUI 中对表格行使用 Transferable

Apollo iOS 客户端代码生成:错误:无法查询字段

无法初始化 FirebaseApp - Flutter

如何在 SwiftUI 的列表中使用带有 swipeActions 的 NavigationLink

何时需要将应用程序源包含在测试目标中?

Watchkit AppIcon - 名为AppIcon的应用图标集没有任何适用的内容

关闭所有打开的视图控制器的单个函数

如何在 Swift 中使用包含多个值的查询参数构建一个 URL?

UIView 和 initWithFrame 以及一个 NIB 文件.如何加载 NIB 文件?

自动布局:是什么创建了名为 UIView-Encapsulated-Layout-Width & Height 的约束?

Objective-C 将 NSDate 设置为当前 UTC

在自动布局中居中子视图的 X 会引发未准备好约束

zoom UIButton 动画 - Swift