色调正在反转 swift 中的颜色

Tint is inverting colors in swift

我正在尝试使用此代码为 UIImage 着色,但它似乎在反转颜色 - 为背景着色并将黑色描边变为白色。

我如何让它为图像的黑色笔划线着色并保留白色背景?这是一个游乐场示例,我在其中尝试了一种技术以及第一个答案建议的另一种技术。

游乐场代码

 extension UIImage {

    func tint(color: UIColor, blendMode: CGBlendMode = CGBlendMode.Normal) -> UIImage
    {
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale);
        let context = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(context, 0, self.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextSetBlendMode(context, blendMode);
        let rect = CGRectMake(0, 0, self.size.width, self.size.height);
        CGContextClipToMask(context, rect, self.CGImage);
        color.setFill()
        CGContextFillRect(context, rect);
        let newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
    }

    func tint2(color: UIColor, blendMode: CGBlendMode) -> UIImage
    {
        let drawRect = CGRectMake(0.0, 0.0, size.width, size.height)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        let context = UIGraphicsGetCurrentContext()
        CGContextClipToMask(context, drawRect, CGImage)
        color.setFill()
        UIRectFill(drawRect)
        drawInRect(drawRect, blendMode: blendMode, alpha: 1.0)
        let tintedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return tintedImage
    }

}

let stringUrl = "https://s3.amazonaws.com/neighbor-chat-assets/icons/avatar1000.png"

let url = NSURL(string: stringUrl)

let data = NSData(contentsOfURL: url!)

var originalimage = UIImage(data: data!)

var image = originalimage!.imageWithRenderingMode(.AlwaysTemplate).tint(UIColor.blueColor(), blendMode:.Normal)
var image2 = originalimage!.imageWithRenderingMode(.AlwaysTemplate).tint2(UIColor.blueColor(), blendMode:.Normal)

这应该可以,我刚刚用 png 和透明背景测试了它

func tint(color: UIColor, blendMode: CGBlendMode = CGBlendMode.Normal) -> UIImage
{
    UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale);
    let context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0, self.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextSetBlendMode(context, blendMode);
    let rect = CGRectMake(0, 0, self.size.width, self.size.height);
    CGContextClipToMask(context, rect, self.CGImage);
    color.setFill()
    CGContextFillRect(context, rect);
    let newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

另请参阅 this post 了解更多信息。另一种方法是将图像包装在具有 UIImageRenderingMode.AlwaysTemplate 渲染模式的 UIImageView 中,然后设置 tintColor 属性.

编辑

所以如果图像中没有 alpha 通道,您可以使用这个函数来首先屏蔽掉某些颜色

func tint(color: UIColor, blendMode: CGBlendMode = CGBlendMode.Normal, colorToMask: UIColor = UIColor.blackColor()) -> UIImage
{
    var fRed : CGFloat = 0
    var fGreen : CGFloat = 0
    var fBlue : CGFloat = 0
    var fAlpha: CGFloat = 0
    colorToMask.getRed(&fRed, green: &fGreen, blue: &fBlue, alpha: &fAlpha)

    let rect = CGRectMake(0, 0, self.size.width, self.size.height);
    var colorMasking : [CGFloat] = [fRed,fRed,fGreen,fGreen,fBlue,fBlue]
    let newImageRef = CGImageCreateWithMaskingColors(self.CGImage!, &colorMasking)

    UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale);
    let context = UIGraphicsGetCurrentContext();

    CGContextTranslateCTM(context, 0, self.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextSetBlendMode(context, blendMode);
    CGContextClipToMask(context, rect, newImageRef!);
    color.setFill()
    CGContextFillRect(context, rect);

    let newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

这个函数首先根据指定的颜色创建一个遮罩,并将上下文裁剪到这个遮罩上。

编辑 #2

正如评论中所述,我也没有设法屏蔽掉白色,我尝试了 UInt8 值(即 255)和浮点值(即 1.0),但仍然没有用。所以我能想到的唯一解决办法就是反转图像。这是函数:

func negativeImage() -> UIImage {

    let coreImage = MYImage(CGImage: self.CGImage!)
    let filter = CIFilter(name: "CIColorInvert", withInputParameters: ["inputImage" : coreImage])!
    let result = filter.outputImage!
    let context = CIContext(options:nil)
    let cgimg : CGImageRef = context.createCGImage(result, fromRect: result.extent)

    let bmpcontext = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height), 8, Int(self.size.width)*4, CGColorSpaceCreateDeviceRGB(),CGImageAlphaInfo.NoneSkipLast.rawValue)
    CGContextDrawImage(bmpcontext, CGRectMake(0, 0, self.size.width, self.size.height), cgimg)
    let newImgRef = CGBitmapContextCreateImage(bmpcontext)!
    return UIImage(CGImage: newImgRef)
}

你可以这样使用它

var image : UIImage = ...
image = image.negativeImage()
image = image.tint(UIColor.redColor())

这里有一些一般注意事项

  • CGImageCreateWithMaskingColors 需要带有 NO alpha 通道的 CGImage,这就是为什么我在 negativeImage 函数中使用标志 CGImageAlphaInfo.NoneSkipLast 以删除 alpha 通道再次
  • 这里绝对没有错误检查,您至少应该使用 CGImageGetAlphaInfo
  • 检查 tint 函数中是否包含 alpha 通道
  • 您可以使被遮盖的部分(在我们的示例中为白色)透明(通过在 tint 函数中的 UIGraphicsBeginImageContextWithOptions 命令中设置 false),或者通过设置 true 来设置特定颜色,即黑色默认(您需要在裁剪到蒙版之前进行绘画)。