如何在Objective-C中使用UIImage作为蒙版

时间:2022-09-07 08:21:52

I have a UIImage that is all black with an alpha channel so some parts are grayish and some parts are completely see-through. I want to use that images as a mask over some other color (let's say white to make it easy), so the final product is now a white image with parts of it transparent.

我有一个UIImage,它全是黑色的带有alpha通道所以有些部分是灰色的有些部分是完全透明的。我想把这些图像作为其他颜色的遮罩(比方说白色,让它更简单),所以最终的产品现在是一个白色的图像,部分是透明的。

I've been looking around on the Apple documentation site here: http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_images/dq_images.html#//apple_ref/doc/uid/TP30001066-CH212-CJBHIJEB

我在这里浏览了苹果文档网站:http://developer.apple.com/library/mac/#文档/GraphicsImaging/概念/drawingwithquartz2d/dq_images/dq_image .html#//apple_ref/doc/uid/TP30001066-CH212-CJBHIJEB。

But I'm completely new to Quartz/Core Graphics, so I don't can't really make sense of those examples.

但是我对Quartz/Core图形完全陌生,所以我不太理解这些例子。

Does anyone know of a link to some full code samples that I could use to look at?

有人知道一些完整的代码示例的链接吗?

4 个解决方案

#1


50  

In iOS 7+ you should use UIImageRenderingModeAlwaysTemplate instead. See https://*.com/a/26965557/870313

在ios7 +中,应该使用UIImageRenderingModeAlwaysTemplate。参见https://*.com/a/26965557/870313


Creating arbitrarily-colored icons from a black-with-alpha master image (iOS).

创建任意颜色的图标,从黑-带-alpha主图像(iOS)。

// Usage: UIImage *buttonImage = [UIImage ipMaskedImageNamed:@"UIButtonBarAction.png" color:[UIColor redColor]];

+ (UIImage *)ipMaskedImageNamed:(NSString *)name color:(UIColor *)color
{
    UIImage *image = [UIImage imageNamed:name];
    CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, image.scale);
    CGContextRef c = UIGraphicsGetCurrentContext();
    [image drawInRect:rect];
    CGContextSetFillColorWithColor(c, [color CGColor]);
    CGContextSetBlendMode(c, kCGBlendModeSourceAtop);
    CGContextFillRect(c, rect);
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return result;
}

Credits to Ole Zorn: https://gist.github.com/1102091

奥立·佐恩:https://gist.github.com/1102091。

#2


3  

Translating Jano's answer into Swift:

将Jano的回答翻译成Swift:

func ipMaskedImageNamed(name:String, color:UIColor) -> UIImage {
    let image = UIImage(named: name)
    let rect:CGRect = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: image!.size.width, height: image!.size.height))
    UIGraphicsBeginImageContextWithOptions(rect.size, false, image!.scale)
    let c:CGContextRef = UIGraphicsGetCurrentContext()
    image?.drawInRect(rect)
    CGContextSetFillColorWithColor(c, color.CGColor)
    CGContextSetBlendMode(c, kCGBlendModeSourceAtop)
    CGContextFillRect(c, rect)
    let result:UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return result
}

Usage:

用法:

myButton.setImage(ipMaskedImageNamed("grayScalePNG", color: UIColor.redColor()), forState: .Normal)

Edit: According to this article, you can turn an image into a mask whose opaque areas are represented by the tint color. Within the asset catalog, under the Attributes Inspector of the image, change Render As to Template Image. No code necessary.

编辑:根据这篇文章,你可以把一个图像变成一个蒙版,它的不透明区域用色彩表示。在资产目录中,在映像的属性检查器下,将呈现更改为模板映像。没有必要的代码。

#3


1  

Here's a variation in Swift 3, written as an extension to UIImage:

这是Swift 3的一个变体,作为UIImage的扩展:

extension UIImage {
    func tinted(color:UIColor) -> UIImage? {
        let image = self
        let rect:CGRect = CGRect(origin: CGPoint(x: 0, y: 0), size: image.size)
        UIGraphicsBeginImageContextWithOptions(rect.size, false, image.scale)
        let context = UIGraphicsGetCurrentContext()!
        image.draw(in: rect)
        context.setFillColor(color.cgColor)
        context.setBlendMode(.sourceAtop)
        context.fill(rect)
        if let result:UIImage = UIGraphicsGetImageFromCurrentImageContext() {
            UIGraphicsEndImageContext()
            return result
        }
        else {
            return nil
        }
    }
}

// Usage
let myImage = #imageLiteral(resourceName: "Check.png") // any image
let blueImage = myImage.tinted(color: .blue)

#4


0  

I converted this for OSX here as a Category and copied below. Note this is for non-ARC projects. For ARC projects, the autorelease can be removed.

我将OSX转换为一个类别并复制到下面。注意,这是针对非arc项目的。对于ARC项目,可以删除autorelease。

- (NSImage *)cdsMaskedWithColor:(NSColor *)color
{
    CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);

    NSImage *result = [[NSImage alloc] initWithSize:self.size];
    [result lockFocusFlipped:self.isFlipped];

    NSGraphicsContext *context = [NSGraphicsContext currentContext];
    CGContextRef c = (CGContextRef)[context graphicsPort];

    [self drawInRect:NSRectFromCGRect(rect)];

    CGContextSetFillColorWithColor(c, [color CGColor]);
    CGContextSetBlendMode(c, kCGBlendModeSourceAtop);
    CGContextFillRect(c, rect);

    [result unlockFocus];

    return [result autorelease];
}
+ (NSImage *)cdsMaskedImageNamed:(NSString *)name color:(NSColor *)color
{
    NSImage *image = [NSImage imageNamed:name];
    return [image cdsMaskedWithColor:color];
}

#1


50  

In iOS 7+ you should use UIImageRenderingModeAlwaysTemplate instead. See https://*.com/a/26965557/870313

在ios7 +中,应该使用UIImageRenderingModeAlwaysTemplate。参见https://*.com/a/26965557/870313


Creating arbitrarily-colored icons from a black-with-alpha master image (iOS).

创建任意颜色的图标,从黑-带-alpha主图像(iOS)。

// Usage: UIImage *buttonImage = [UIImage ipMaskedImageNamed:@"UIButtonBarAction.png" color:[UIColor redColor]];

+ (UIImage *)ipMaskedImageNamed:(NSString *)name color:(UIColor *)color
{
    UIImage *image = [UIImage imageNamed:name];
    CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, image.scale);
    CGContextRef c = UIGraphicsGetCurrentContext();
    [image drawInRect:rect];
    CGContextSetFillColorWithColor(c, [color CGColor]);
    CGContextSetBlendMode(c, kCGBlendModeSourceAtop);
    CGContextFillRect(c, rect);
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return result;
}

Credits to Ole Zorn: https://gist.github.com/1102091

奥立·佐恩:https://gist.github.com/1102091。

#2


3  

Translating Jano's answer into Swift:

将Jano的回答翻译成Swift:

func ipMaskedImageNamed(name:String, color:UIColor) -> UIImage {
    let image = UIImage(named: name)
    let rect:CGRect = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: image!.size.width, height: image!.size.height))
    UIGraphicsBeginImageContextWithOptions(rect.size, false, image!.scale)
    let c:CGContextRef = UIGraphicsGetCurrentContext()
    image?.drawInRect(rect)
    CGContextSetFillColorWithColor(c, color.CGColor)
    CGContextSetBlendMode(c, kCGBlendModeSourceAtop)
    CGContextFillRect(c, rect)
    let result:UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return result
}

Usage:

用法:

myButton.setImage(ipMaskedImageNamed("grayScalePNG", color: UIColor.redColor()), forState: .Normal)

Edit: According to this article, you can turn an image into a mask whose opaque areas are represented by the tint color. Within the asset catalog, under the Attributes Inspector of the image, change Render As to Template Image. No code necessary.

编辑:根据这篇文章,你可以把一个图像变成一个蒙版,它的不透明区域用色彩表示。在资产目录中,在映像的属性检查器下,将呈现更改为模板映像。没有必要的代码。

#3


1  

Here's a variation in Swift 3, written as an extension to UIImage:

这是Swift 3的一个变体,作为UIImage的扩展:

extension UIImage {
    func tinted(color:UIColor) -> UIImage? {
        let image = self
        let rect:CGRect = CGRect(origin: CGPoint(x: 0, y: 0), size: image.size)
        UIGraphicsBeginImageContextWithOptions(rect.size, false, image.scale)
        let context = UIGraphicsGetCurrentContext()!
        image.draw(in: rect)
        context.setFillColor(color.cgColor)
        context.setBlendMode(.sourceAtop)
        context.fill(rect)
        if let result:UIImage = UIGraphicsGetImageFromCurrentImageContext() {
            UIGraphicsEndImageContext()
            return result
        }
        else {
            return nil
        }
    }
}

// Usage
let myImage = #imageLiteral(resourceName: "Check.png") // any image
let blueImage = myImage.tinted(color: .blue)

#4


0  

I converted this for OSX here as a Category and copied below. Note this is for non-ARC projects. For ARC projects, the autorelease can be removed.

我将OSX转换为一个类别并复制到下面。注意,这是针对非arc项目的。对于ARC项目,可以删除autorelease。

- (NSImage *)cdsMaskedWithColor:(NSColor *)color
{
    CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);

    NSImage *result = [[NSImage alloc] initWithSize:self.size];
    [result lockFocusFlipped:self.isFlipped];

    NSGraphicsContext *context = [NSGraphicsContext currentContext];
    CGContextRef c = (CGContextRef)[context graphicsPort];

    [self drawInRect:NSRectFromCGRect(rect)];

    CGContextSetFillColorWithColor(c, [color CGColor]);
    CGContextSetBlendMode(c, kCGBlendModeSourceAtop);
    CGContextFillRect(c, rect);

    [result unlockFocus];

    return [result autorelease];
}
+ (NSImage *)cdsMaskedImageNamed:(NSString *)name color:(NSColor *)color
{
    NSImage *image = [NSImage imageNamed:name];
    return [image cdsMaskedWithColor:color];
}