如何构造5x5矩阵以用作Swift中的颜色矩阵?
我需要一些帮助再次转换我的Android应用到iOS 正如我在其他帖子中提到的,这个应用程序是关于图像处理的,它基于ColorMatrix。问题是Swift只支持(据我所知…)4x4矩阵,对于亮度或对比度,我在Android中使用5x5矩阵 在Android中,这些是我的矩阵: 亮度:如何构造5x5矩阵以用作Swift中的颜色矩阵?,swift,xcode,matrix,cifilter,brightness,Swift,Xcode,Matrix,Cifilter,Brightness,我需要一些帮助再次转换我的Android应用到iOS 正如我在其他帖子中提到的,这个应用程序是关于图像处理的,它基于ColorMatrix。问题是Swift只支持(据我所知…)4x4矩阵,对于亮度或对比度,我在Android中使用5x5矩阵 在Android中,这些是我的矩阵: 亮度: float[] brightMatrix = { 1f, 0f, 0f, 0f, 32f, 0f, 1f, 0f, 0f, 32f,
float[] brightMatrix = {
1f, 0f, 0f, 0f, 32f,
0f, 1f, 0f, 0f, 32f,
0f, 0f, 1f, 0f, 32f,
0f, 0f, 0f, 1f, 0f,
0f, 0f, 0f, 0f, 1f};
对比度:
float[] contMatrix = {
1.190f, 0f, 0f, 0f, -12.065f,
0f, 1.190f, 0f, 0f, -12.065f,
0f, 0f, 1.190f, 0f, -12.065f,
0f, 0f, 0f, 1f, 0f,
0f, 0f, 0f, 0f, 1f};
但我真的不知道如何在Swift中获得相同的结果
对于亮度,我尝试使用此代码除以32/255得到值0.12549:
func zoeFilter() -> UIImage? {
let inImage = CIImage (image: self)
dynamic let brightFactor = CIFilter (name: "CIColorControls")
brightFactor?.setValue(inImage, forKey: kCIInputImageKey)
brightFactor?.setValue(0.12549, forKey: kCIInputBrightnessKey)
let brightImage = brightFactor?.outputImage
let cgImage = CIContext().createCGImage(brightImage!, from: brightImage!.extent)
return UIImage (cgImage: cgImage!)
}
但结果完全不一样。。。在iOS中,它就像一团白雾
说到对比度,我找到了下一个代码,但我不可能在这里仅用一个值来转换Android矩阵contFactor?.setValue(1,forKey:kciinputcanterskey)
只要知道1等于中性:
func chiaFilter() -> UIImage? {
let inImage = CIImage (image: self)
dynamic let contFactor = CIFilter (name: "CIColorControls")
contFactor?.setValue(inImage, forKey: kCIInputImageKey)
contFactor?.setValue(1, forKey: kCIInputContrastKey)
let contImage = contFactor?.outputImage
let cgImage = CIContext().createCGImage(contImage!, from: contImage!.extent)
return UIImage (cgImage: cgImage!)
}
另一方面,由于Android中的矩阵类似于:
float[] expMatrix = {
1.3f, 0f, 0f, 0f, 0f,
0f, 1.3f, 0f, 0f, 0f,
0f, 0f, 1.3f, 0f, 0f,
0f, 0f, 0f, 1f, 0f,
0f, 0f, 0f, 0f, 1f};
因此,在Swift中,我可以使用下一个代码获得完全相同的结果:
func liaFilter() -> UIImage? {
let inImage = CIImage (image: self)
dynamic let expoMatrix = CIFilter (name: "CIColorMatrix")
expoMatrix?.setDefaults()
expoMatrix?.setValue(inImage, forKey: kCIInputImageKey)
expoMatrix?.setValue(CIVector (x: 1.3, y: 0, z: 0, w: 0), forKey: "inputRVector")
expoMatrix?.setValue(CIVector (x: 0, y: 1.3, z: 0, w: 0), forKey: "inputGVector")
expoMatrix?.setValue(CIVector (x: 0, y: 0, z: 1.3, w: 0), forKey: "inputBVector")
expoMatrix?.setValue(CIVector (x: 0, y: 0, z: 0, w: 1), forKey: "inputAVector")
let expoImage = expoMatrix?.outputImage
let cgImage = CIContext().createCGImage(expoImage!, from: expoImage!.extent)
return UIImage (cgImage: cgImage!)
}
太混乱了。。。我知道。。。但如果有人能对如何解决安卓和iOS之间的这些问题有所了解,那就太好了
提前谢谢
弗兰克回答后的版本
以下是原始图像:
以下是使用Android应用过滤器后的情况:
float[] brightMatrix = {
1f, 0f, 0f, 0f, 32f,
0f, 1f, 0f, 0f, 32f,
0f, 0f, 1f, 0f, 32f,
0f, 0f, 0f, 1f, 0f,
0f, 0f, 0f, 0f, 1f};
以下是使用iOS应用过滤器的相同图片:
brightMatrix?.setValue(CIVector (x: 1, y: 0, z: 0, w: 0), forKey: "inputRVector")
brightMatrix?.setValue(CIVector (x: 0, y: 1, z: 0, w: 0), forKey: "inputGVector")
brightMatrix?.setValue(CIVector (x: 0, y: 0, z: 1, w: 0), forKey: "inputBVector")
brightMatrix?.setValue(CIVector (x: 0, y: 0, z: 0, w: 1), forKey: "inputAVector")
brightMatrix?.setValue(CIVector (x: 32.0/255.0, y: 32.0/255.0, z: 32.0/255.0, w: 0), forKey: "inputBiasVector")
弗兰克提议后的最终解决方案
您还可以通过如下方式设置
CIColorMatrix
过滤器的inputBiasVector
参数来使用亮度和对比度矩阵:
// the first 4 should actually be the default, so you probably don't need to set them explicitly
brightMatrix?.setValue(CIVector(x: 1, y: 0, z: 0, w: 0), forKey: "inputRVector")
brightMatrix?.setValue(CIVector(x: 0, y: 1, z: 0, w: 0), forKey: "inputGVector")
brightMatrix?.setValue(CIVector(x: 0, y: 0, z: 1, w: 0), forKey: "inputBVector")
brightMatrix?.setValue(CIVector(x: 0, y: 0, z: 0, w: 1), forKey: "inputAVector")
brightMatrix?.setValue(CIVector(x: 32.0/255.0, y: 32.0/255.0, z: 32.0/255.0, w: 0), forKey: "inputBiasVector")
但奇怪的是,您不能使用
CIColorControls
过滤器来实现相同的功能。也许你可以发布示例图片。谢谢弗兰克的回答!虽然结果与使用CIColorControl相同,但很高兴了解偏置矢量。。。我添加了一些图片。这可能是由于伽马校正(或缺乏校正)引起的问题。您的Android过滤器似乎是在sRGB伽马曲线上运行的,而核心图像通常使用线性分布。也许你可以试着在颜色矩阵之前添加一个CILinearToSRGBToneCurve
过滤器到你的管道中,然后再添加一个CISRGBToneCurveToLinear
(或者反过来,我不确定…)。伙计,你真是个天才!非常感谢你,因为这是钥匙。。。明天我将发布基于您的帮助的最终代码。再次感谢!最终代码添加为解决方案!再次感谢你,弗兰克!很高兴它成功了!两个补充:(1)如果您仍然设置了所有参数(或者过滤器没有任何参数),则无需对过滤器设置默认值。(2) 您可以使用快捷方式让SRGBImage=inImage.applyingFilter(“CILinearToSRGBToneCurve”)
来分别保存几行。我来学习这些技巧!
// the first 4 should actually be the default, so you probably don't need to set them explicitly
brightMatrix?.setValue(CIVector(x: 1, y: 0, z: 0, w: 0), forKey: "inputRVector")
brightMatrix?.setValue(CIVector(x: 0, y: 1, z: 0, w: 0), forKey: "inputGVector")
brightMatrix?.setValue(CIVector(x: 0, y: 0, z: 1, w: 0), forKey: "inputBVector")
brightMatrix?.setValue(CIVector(x: 0, y: 0, z: 0, w: 1), forKey: "inputAVector")
brightMatrix?.setValue(CIVector(x: 32.0/255.0, y: 32.0/255.0, z: 32.0/255.0, w: 0), forKey: "inputBiasVector")