如何构造5x5矩阵以用作Swift中的颜色矩阵?

如何构造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,

我需要一些帮助再次转换我的Android应用到iOS

正如我在其他帖子中提到的,这个应用程序是关于图像处理的,它基于ColorMatrix。问题是Swift只支持(据我所知…)4x4矩阵,对于亮度或对比度,我在Android中使用5x5矩阵

在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};
对比度:

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")