iPhone - 如何为图像着色?

时间:2009-08-03 16:40:34

标签: iphone image colors

我很想知道如何为图像着色(例如,制作白色.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]];

但它不起作用 - 屏幕上的图像仍为白色。

9 个答案:

答案 0 :(得分:64)

将此设为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 :(得分:12)

将混合模式更改为乘以,您的代码将起作用:

CGContextSetBlendMode(ctx, kCGBlendModeMultiply);

答案 2 :(得分:10)

从iOS 7开始,您可以使用单一颜色为图像着色

目标C

UIImage *image = [UIImage imageNamed:@"myImage.png"];
UIImageView *imageView = [[UIImageView alloc]initWithImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
imageView.tintColor = [UIColor redColor];

Swift 3

let image = UIImage(named:"myImage.png")?.withRenderingMode(.alwaysTemplate)
let imageView = UIImageView(image:image)
imageView.tintColor = .red

这将使用单一颜色为整个图像着色并保留Alpha通道。

答案 3 :(得分:2)

我认为从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 ,如下图所示:

UIImageRenderingModeAlwaysTemplate in XCode

答案 4 :(得分:1)

好的,这是怎么回事?

在资产创建阶段(在应用程序运行时不动态),反转图像的颜色方案。现在是白色的部分 - >透明。现在透明的部分 - >无论页面的背景如何。

在每张图片下,放置相同尺寸的空白白色视图。如果要将图像变为红色,请将该空白白色视图的颜色更改为红色。

可行吗?

答案 5 :(得分:1)

@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(),或者如果你有当前上下文的实例。

希望有所帮助。

答案 6 :(得分:1)

简短,甜蜜,更好:)

- (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;
}

答案 7 :(得分:0)

如果将UIImageView的backgroundColor设置为[UIColor redColor],原始PNG中透明的部分将变为红色。或者,您可以尝试添加背景颜色为红色的半透明UIView作为imageview的子视图。这将为显示图像的视图添加红色雾度。

答案 8 :(得分:0)

首先绘制颜色,然后在其上绘制图像。除非图像部分透明,否则它将完全透过背景颜色。我建议先尝试绘制原始图像,然后使用kCGBlendModeHue在其上绘制红色。

我不确定你为什么要翻转和翻译你的背景。你的照片是颠倒了吗?