iPhone - 如何为图像着色?
Posted
技术标签:
【中文标题】iPhone - 如何为图像着色?【英文标题】:iPhone - How do you color an image? 【发布时间】:2010-11-16 10:30:42 【问题描述】:我很想知道如何为图像着色(例如,将白色 .png 设为红色)。我已经看到了各种建议,但从未确认这实际上是可能的。我试过这个:
-(UIImage *)colorizeImage:(UIImage *)baseImage color:(UIColor *)theColor
UIGraphicsBeginImageContext(baseImage.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect area = CGRectMake(0, 0, baseImage.size.width, baseImage.size.height);
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -area.size.height);
CGContextSaveGState(ctx);
CGContextClipToMask(ctx, area, baseImage.CGImage);
[theColor set];
CGContextFillRect(ctx, area);
CGContextRestoreGState(ctx);
CGContextSetBlendMode(ctx, kCGBlendModeNormal);
CGContextDrawImage(ctx, area, baseImage.CGImage);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
myImageView.image = [self colorizeImage:[UIImage imageNamed:@"whiteImage.png"] color:[UIColor redColor]];
但它不起作用 - 屏幕上的图像仍然是白色的。
【问题讨论】:
但是你到底想做什么?您是否尝试将所有完全白色的像素 (RGB(255,255,255)) 变为红色?您只想添加红色调吗?您的“whiteImage.png”实际上只是一个全白的大矩形吗? 是的,我想将白色(或灰色)像素变成红色。 png 的透明部分应保持透明。 whiteImage.png 不是白色矩形 - 例如,它是动物的图像。 是否有什么特殊原因不能让您只拥有同一图像的红色版本,并根据需要在它们之间切换?双色图像压缩得非常小。 可以参考***.com/questions/19274789/… 【参考方案1】:将此设为 UIImage 类别。它还考虑了 ios 4 的比例因子。
- (UIImage *)imageWithOverlayColor:(UIColor *)color
CGRect rect = CGRectMake(0.0f, 0.0f, self.size.width, self.size.height);
if (UIGraphicsBeginImageContextWithOptions)
CGFloat imageScale = 1.0f;
if ([self respondsToSelector:@selector(scale)]) // The scale property is new with iOS4.
imageScale = self.scale;
UIGraphicsBeginImageContextWithOptions(self.size, NO, imageScale);
else
UIGraphicsBeginImageContext(self.size);
[self drawInRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
更新 - Swift 版本:
func imageWithColor(color: UIColor) -> UIImage
let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
UIGraphicsBeginImageContextWithOptions(self.size, false, 0.0);
drawInRect(rect)
let context = UIGraphicsGetCurrentContext()
CGContextSetBlendMode(context, .SourceIn)
CGContextSetFillColorWithColor(context, color.CGColor)
CGContextFillRect(context, rect);
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
【讨论】:
感谢...正是我需要根据用户选择的主题为界面功能的背景着色。 +1 谢谢它对我有用。在我只得到白色之前,现在 CGContextSetBlendMode(ctx, kCGBlendModeMultiply); 正如 willc2 所说,它工作正常。 一天早上才发现这个……原来如此简单!我爱你戴夫·巴尔顿。 这很棒,迄今为止完成 UIImage 着色的最佳解决方案。我花了一整天的时间寻找一种方法来重新着色 UIImage 并且还能够使用resizableImageWithCapInsets
方法。 [[[UIImage imageNamed:@"myImage.png"] imageWithOverlayColor:[UIColor blackColor]] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 15)];
在 iOS7+ 中有一个更简单的解决方案,请参阅***.com/a/27356928/3624478【参考方案2】:
将您的混合模式更改为 multiply,您的代码将正常工作:
CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
【讨论】:
+1 谢谢它对我有用。以前我只能得到白色,现在它工作正常。【参考方案3】:从 iOS 7 开始,您可以像这样使用单一颜色为图像着色
目标 C
UIImage *image = [UIImage imageNamed:@"myImage.png"];
UIImageView *imageView = [[UIImageView alloc]initWithImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
imageView.tintColor = [UIColor redColor];
斯威夫特 3
let image = UIImage(named:"myImage.png")?.withRenderingMode(.alwaysTemplate)
let imageView = UIImageView(image:image)
imageView.tintColor = .red
这将使用单一颜色为整个图像着色并保留 Alpha 通道。
【讨论】:
【参考方案4】:我认为从 iOS7 为图像着色的最佳方法是在图像上指定属性 UIImageRenderingModeAlwaysTemplate:
myImageView.image = [[UIImage imageNamed:@"myImage"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
然后用imageView的tintColor给它上色
myImageView.tintColor = [UIColor purpleColor]; //Maybe purple is not the best choice ;)
我认为它更容易(不需要类别),当然也优化了!
注意:如果您使用的是 xcassets,您可以在 XCode 中将渲染属性设置为 UIImageRenderingModeAlwaysTemplate,如下图所示:
【讨论】:
【参考方案5】:好的,怎么样?
在您的资产创建阶段(不是在应用程序运行时动态创建),反转图像的配色方案。现在是白色的部分 -> 透明。现在透明的部分 -> 无论页面的背景是什么。
在每个图像下,放置一个相同大小的空白视图。当您希望将图像变为红色时,将该空白视图的颜色更改为红色。
这可行吗?
【讨论】:
【参考方案6】:@geek 小子,如果这对你有帮助,请告诉我...
// translate/flip the graphics context (for transforming from CG* coords to UI* coords)
CGContextTranslateCTM(context, 0, img.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
//将“context”替换为UIGraphicsGetCurrentContext()
,或者如果你有当前上下文的实例。
希望对您有所帮助。
【讨论】:
【参考方案7】:短,甜,更好:)
- (UIImage *)colorizeImage:(UIImage *)image withColor:(UIColor *)color
定义UIColorFromRGB
使用十六进制颜色代码,然后调用colorizeImage:withColor
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
- (void)viewDidLoad
[super viewDidLoad];
UIImage *imgToColor = [UIImage imageNamed:@"myImage.png"];
imgToColor = [self colorizeImage:imgToColor withColor:UIColorFromRGB(0xff00ff)];
// use normal UIColor or UIColorFromRGB() for hex
- (UIImage *)colorizeImage:(UIImage *)image withColor:(UIColor *)color
CGRect rect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
UIGraphicsBeginImageContextWithOptions(image.size, NO, [[UIScreen mainScreen] scale]);
[image drawInRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
【讨论】:
【参考方案8】:如果将 UIImageView 的 backgroundColor 设置为 [UIColor redColor],则原始 PNG 中透明的部分将变为红色。或者,您可以尝试添加一个背景颜色为红色的半透明 UIView 作为 imageview 的子视图。这将为显示图像的视图添加红色雾度。
【讨论】:
谢谢,但我只想为现有的像素着色,而不是整个矩形。【参考方案9】:您首先绘制颜色,然后在其上绘制图像。除非图像是部分透明的,否则它将完全覆盖背景颜色。我建议先尝试绘制原始图像,然后使用kCGBlendModeHue
在其上绘制红色。
我不确定你为什么要翻转和翻译你的上下文。你的照片是倒置的吗?
【讨论】:
以上是关于iPhone - 如何为图像着色?的主要内容,如果未能解决你的问题,请参考以下文章
如何为 iPhone 6 / 6 Plus 仅横向应用程序创建启动图像?
iPhone/iOS:如何为 Scrollview 的子视图实现拖放?