UIImage动画图像的色调颜色?

11

有没有办法给动画中的图像染色?

我知道可以像这样给单个图像染色:

var imageOne:UIImage = UIImage(named: "pullto_1.png")!;
    imageOne = imageOne.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
    refSequence.image = imageOne;
但是当我尝试这样做时,它就无法正常工作:
 var imageOne:UIImage = UIImage(named: "pullto_1.png")!;
    imageOne = imageOne.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)

    var image2:UIImage = UIImage(named: "pullto_2.png")!;
    image2 = image2.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)

    var image3:UIImage = UIImage(named: "pullto_3.png")!;
    image3 = image3.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)

    var image4:UIImage = UIImage(named: "pullto_4.png")!;
    image4 = image4.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)

    refSequence.animationImages = NSArray(objects: imageOne,
        image2,
        image3,
        image4

    );

    refSequence.animationDuration = 1.4;
    refSequence.animationRepeatCount = 99;
    refSequence.startAnimating();

我做错了什么吗?有没有一种方法可以给动画中的图像上色?

谢谢

6个回答

11

好的,我希望有一个更简单的解决方案,但这是我最终采取的方法:

此函数将创建一个具有所需颜色的新图像:

func imageWithColor(img:UIImage, color:UIColor)->UIImage{
    UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale);
    var context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0, img.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextSetBlendMode(context, kCGBlendModeNormal);
    var rect = CGRectMake(0, 0, img.size.width, img.size.height);
    CGContextClipToMask(context, rect, img.CGImage)
    color.setFill();
    CGContextFillRect(context, rect);
    var newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

然后你可以这样调用它:

var imageOne:UIImage = UIImage(named: "pullto_1.png")!;
    imageOne = imageWithColor(imageOne, color: UIColor.redColor());
    var image2:UIImage = UIImage(named: "pullto_2.png")!;
    image2 = imageWithColor(image2, color: UIColor.redColor());
    var image3:UIImage = UIImage(named: "pullto_3.png")!;
    image3 = imageWithColor(image3, color: UIColor.redColor());
    var image4:UIImage = UIImage(named: "pullto_4.png")!;
    image4 = imageWithColor(image4, color: UIColor.redColor());

    loaderS.animationImages = NSArray(objects: imageOne,
        image2,
        image3,
        image4

    );



    loaderS.animationDuration = 1.4;
    loaderS.animationRepeatCount = 99;
    loaderS.startAnimating();

5

有一份关于这个问题的rdar报告(http://www.openradar.me/23517334),并且这个问题在iOS 11上仍然存在。

我已将以上代码示例适应于Swift 4。

extension UIImage {
    func image(withTintColor color: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, scale)

        let context = UIGraphicsGetCurrentContext()
        context?.translateBy(x: 0, y: size.height)
        context?.scaleBy(x: 1.0, y: -1.0)
        context?.setBlendMode(.normal)

        let rect = CGRect(origin: .zero, size: size)
        context?.clip(to: rect, mask: cgImage!)
        color.setFill()
        context?.fill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image!
    }
}

4

这是一个方便的 UIImage 扩展:

import UIKit

extension UIImage {

    func imageWithTint(tint: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        let context = UIGraphicsGetCurrentContext()
        CGContextTranslateCTM(context, 0, size.height)
        CGContextScaleCTM(context, 1.0, -1.0)
        CGContextSetBlendMode(context, .Normal)
        let rect = CGRect(origin: .zero, size: size)
        CGContextClipToMask(context, rect, CGImage)
        tint.setFill()
        CGContextFillRect(context, rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image;
    }

}

1
对于Swift 5:使用以下函数创建所需颜色的图像。然后将这些图像设置为您的图像视图的动画属性:
extension UIImage {    
    func imageWithColor(_ color: UIColor) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale);
        guard let context = UIGraphicsGetCurrentContext(), let cgImage = self.cgImage else { return nil }

        context.translateBy(x: 0, y: self.size.height)
        context.scaleBy(x: 1.0, y: -1.0);
        context.setBlendMode(.normal)
        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        context.clip(to: rect, mask: cgImage)
        color.setFill()
        context.fill(rect)
        let  newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext();

        return newImage
    }
}


let animImages = [
    image0.imageWithColor(color),
    image1.imageWithColor(color),
    image2.imageWithColor(color),
].compactMap({ $0 })

imageView.animationImages = animImages
imageView.animationDuration = 0.7
imageView.animationRepeatCount = 0

0

这是更新的Swift 4代码,带有一些安全检查。

extension UIImage {
    func image(withTint tint: UIColor) -> UIImage? {
        guard let cgImage = cgImage else {
            return nil
        }

        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }

        let rect = CGRect(origin: .zero, size: size)

        context.translateBy(x: 0, y: size.height)
        context.scaleBy(x: 1.0, y: -1.0)
        context.setBlendMode(.normal)
        context.clip(to: rect, mask: cgImage)
        tint.setFill()
        context.fill(rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}

0

也许这个示例扩展可以帮助:

 extension UIImageView {

        func pulsingTintColor() {
            UIView.animate(withDuration: 2, delay: 0.0, options: [.repeat, .autoreverse], animations: {
                         self.tintColor = UIColor.red
                         self.tintColor = UIColor.green
                         self.tintColor = UIColor.blue
            }, completion: nil)
        }
    }

请确保您在资源目录中设置了呈现为:模板图像选项。这对于UIView也适用。只需将tintColor替换为backgroundColor

如果您需要参数化颜色:

func pulsingTintColor(with colors: [UIColor] = [UIColor.red, UIColor.green, UIColor.blue]) {
    UIView.animate(withDuration: 2, delay: 0.0, options: [.repeat, .autoreverse], animations: {
         colors.forEach({self.tintColor = $0})
    }, completion: nil)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接