【问题标题】:Using CIColorMatrix filter in Swift在 Swift 中使用 CIColorMatrix 过滤器
【发布时间】:2015-05-02 03:14:11
【问题描述】:

以下 Swift 函数应该使用指定的 'tintColor' 为灰度图像 'greyImage' 着色:

import UIKit

func colorizeImage(greyImage : UIImage, tintColor : UIColor) -> UIImage? {

    let colorMatrixFilter = CIFilter(name: "CIColorMatrix")

    var r:CGFloat = 0
    var g:CGFloat = 0
    var b:CGFloat = 0
    var a:CGFloat = 0
    tintColor.getRed(&r, green:&g, blue:&b, alpha:&a)

    colorMatrixFilter.setDefaults()
    colorMatrixFilter.setValue(greyImage, forKey:"inputImage") //kCIInputImageKey)
    colorMatrixFilter.setValue(CIVector(x:r, y:0, z:0, w:0), forKey:"inputRVector")
    colorMatrixFilter.setValue(CIVector(x:0, y:g, z:0, w:0), forKey:"inputGVector")
    colorMatrixFilter.setValue(CIVector(x:0, y:0, z:b, w:0), forKey:"inputBVector")
    colorMatrixFilter.setValue(CIVector(x:0, y:0, z:0, w:a), forKey:"inputAVector")

    if let ciImage =  colorMatrixFilter.outputImage {
        return UIImage(CIImage: ciImage);
    }

    return nil;
}

颜色为UIColor.orangeColor() (r=1,g=0.5,b=0,a=1),灰度图可以,输入ImageView时显示正常。

看起来提供了所有必要的键并且键分配顺利(顺便说一句,过滤器检查键的有效性,还是获取所有内容?),但是读取 'outputImage' 属性会产生 SIGABRT 和以下控制台消息:

2015-05-02 13:04:07.319 MyApp[436:8241] -[UIImage _internalRepresentation]: unrecognized selector sent to instance 0x7fd5b3ca82b0
2015-05-02 13:04:07.629 MyApp[436:8241] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIImage _internalRepresentation]: unrecognized selector sent to instance 0x7fd5b3ca82b0'
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001087abf35 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010a56cbb7 objc_exception_throw + 45
    2   CoreFoundation                      0x00000001087b304d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x000000010870b27c ___forwarding___ + 988
    4   CoreFoundation                      0x000000010870ae18 _CF_forwarding_prep_0 + 120
    5   CoreImage                           0x0000000108bd30fe -[CIColorMatrix outputImage] + 885
    6   MyApp                            0x00000001085c182d _TF8MyApp13colorizeImageFTCSo7UIImageCSo7UIColor_GSqS0__ + 4733
    7   MyApp                            0x00000001085c2b59 

【问题讨论】:

    标签: ios swift colormatrixfilter


    【解决方案1】:

    问题在于CIColorMatrix 期望参数 inputImage 应该是 CIImage 对象而不是 UIImage (greyImage)。

    更新:Swift 3 或更高版本

    extension UIColor {
        var rgba: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)? {
            var (r,g,b,a): (CGFloat,CGFloat,CGFloat,CGFloat) = (0,0,0,0)
            return getRed(&r, green: &g, blue: &b, alpha: &a) ? (r,g,b,a) : nil
        }
    }
    

    extension CIImage {
        var image: UIImage { .init(ciImage: self) }
        func colorized(with color: UIColor) -> CIImage? {
            guard
                let (r,g,b,a) = color.rgba,
                let colorMatrix = CIFilter(name: "CIColorMatrix",
                    parameters: ["inputImage":  self,
                                 "inputRVector": CIVector(x: r, y: 0, z: 0, w: 0),
                                 "inputGVector": CIVector(x: 0, y: g, z: 0, w: 0),
                                 "inputBVector": CIVector(x: 0, y: 0, z: b, w: 0),
                                 "inputAVector": CIVector(x: 0, y: 0, z: 0, w: a)])
            else { return nil }
            return colorMatrix.outputImage
        }
    }
    

    extension UIImage {
        var coreImage: CIImage? { CIImage(image: self) }
        func colorized(with color: UIColor) -> UIImage? {
            coreImage?.colorized(with: color)?.image
        }
    }
    

    游乐场测试:

    let profilePicture = UIImage(data: try! Data(contentsOf: URL(string: "http://i.stack.imgur.com/Xs4RX.jpg")!))!
    profilePicture.colorized(with: .orange)
    

    【讨论】:

    • 谢谢伦纳德,你真是个天才。为您的努力保留奖励积分!现在我有另一个问题。为了克服 ColorMatrix 的问题,我制作了一个使用混合进行着色的函数:CGContextSetBlendMode(context, kCGBlendModeMultiply)... 这种混合技术没有保持透明度,ColorMatrix 做到了,这很棒。但是,当我使用 UIColor(patternImage: image) 从 ColorMatrix 结果制作图块时,我得到它完全黑色,而在混合图块后效果非常好!有什么解释吗?
    • @cyanide 打开另一个问题会更容易,如果可能的话,添加一个仅重现问题的示例项目
    猜你喜欢
    • 2013-09-26
    • 2020-08-12
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多