iPhone - How do you color an image?

2020-01-24 03:58发布

I would love to know how to color an image (make a white .png red, for example). I have seen various suggestions but never any confirmation that this is actually possible. I have tried this:

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

But it doesn't work - the image is still white on the screen.

9条回答
The star\"
2楼-- · 2020-01-24 04:03

Short, sweet and better :)

- (UIImage *)colorizeImage:(UIImage *)image withColor:(UIColor *)color

Define UIColorFromRGB to use hex color codes then just call 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;
}
查看更多
闹够了就滚
3楼-- · 2020-01-24 04:05

@geek kid, let me know if this helps u dude...

// 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);

//replace "context" with UIGraphicsGetCurrentContext() or if u have an instance of the current context.

Hope that helps.

查看更多
叛逆
4楼-- · 2020-01-24 04:11

If you set the backgroundColor of an UIImageView to [UIColor redColor], the parts of the original PNG that were transparent will become red. Alternatively, you could try adding a semi-transparent UIView with background color red as subview of the imageview. This will add a red haze to the view displaying the image.

查看更多
甜甜的少女心
5楼-- · 2020-01-24 04:11

You're drawing the color first, and then drawing the image on top of it. Unless the image is partially transparent, it's going to completely overdraw the background color. I recommend trying to draw the original image first, and then drawing red over it using kCGBlendModeHue.

I'm not certain why you're flipping and translating your context. Is your picture upside down?

查看更多
\"骚年 ilove
6楼-- · 2020-01-24 04:14

Okay, how's this?

In your asset creation phase (NOT dynamically while the application is running), invert the color scheme of your images. Part that is now white -> transparent. Part that is now transparent -> whatever the background of the page is.

Under each image, place a blank white view of the same size. When you wish to turn the image to red, change the color of that blank white view to red.

Is that doable?

查看更多
不美不萌又怎样
7楼-- · 2020-01-24 04:26

Make this a UIImage category. It also takes into account the scale factor with 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;
}

UPDATE - Swift version:

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
}
查看更多
登录 后发表回答