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 6/7 自定义边到边图像指定尺寸?

如何为iphone中的图像提供动画看起来像花

iPhone/iOS:如何为 Scrollview 的子视图实现拖放?

如何为iCarousel iphone中不同位置的图像实现删除功能

你如何为 iPhone 实现横向启动屏幕?