在 Swift 中使用 CIColorMatrix 滤镜
Using CIColorMatrix filter in Swift
以下 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),灰度图是OK的,输入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
问题是 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)
以下 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),灰度图是OK的,输入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
问题是 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)