Ios CISpotLight过滤器和nil结果

Ios CISpotLight过滤器和nil结果,ios,objective-c,core-image,Ios,Objective C,Core Image,我试图达到聚光灯的效果。我写了一些基于 然而,这似乎不起作用filter对象是nil(显然outputImage,newImage也是nil),但是ciImage是可以的 CIVector *inputLightPointsAt = [CIVector vectorWithX:20.f Y:20.f Z:5.f]; CIColor *inputColor = [[CIColor alloc] initWithColor:[UIColor redColor]]; CIImage *ciImage

我试图达到聚光灯的效果。我写了一些基于 然而,这似乎不起作用
filter
对象是
nil
(显然
outputImage
newImage
也是
nil
),但是
ciImage
是可以的

CIVector *inputLightPointsAt = [CIVector vectorWithX:20.f Y:20.f Z:5.f];
CIColor *inputColor = [[CIColor alloc] initWithColor:[UIColor redColor]];
CIImage *ciImage = [CIImage imageWithCGImage:[UIImage imageNamed:@"image"].CGImage];

CIFilter *filter = [CIFilter filterWithName:@"CISpotLight" keysAndValues:
                                            kCIInputImageKey, ciImage,
                                            @"inputBrightness", @1.5f,
                                            @"inputConcentration", @0.5f,
                                            @"inputColor", inputColor,
                                            @"inputLightPosition", inputLightPointsAt,
                                            @"inputLightPointsAt", inputLightPointsAt,
                                            nil];
CIImage *outputImage = [filter outputImage];
UIImage *newImage = [UIImage imageWithCIImage:outputImage];
有人知道我做错了什么吗?如何让它工作

顺便说一句:当我把过滤器换成像乌贼墨之类的东西时,一切都很好

CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone" keysAndValues:
                        kCIInputImageKey, ciImage,
                        @"inputIntensity", @0.8,
                        nil];

据我在您的标签中看到的,您的目标是iOS,根据文档:

Availability
Available in OS X v10.4 and later.

它在iOS上不可用。

我将此作为延迟答复发布,以防有人从中获得帮助

事实上,聚光灯过滤器有点棘手。您需要小心地将其点设置为位置灯

        let filter = CIFilter(name: "CISpotLight")
        filter?.setDefaults()
        filter?.setValue(inputImage, forKey: kCIInputImageKey)
        filter?.setValue(CIVector(x: inputImage!.extent.size.width/2, y: inputImage!.extent.size.height/2, z: 60), forKey: "inputLightPointsAt")
        filter?.setValue(2.5, forKey: kCIInputBrightnessKey)
        filter?.setValue(0.1, forKey: "inputConcentration")
        outputImage = filter?.outputImage

在这里,我传递输入图像,并在应用过滤器后获得输出图像。

控制灯光位置和聚焦区域有点困难,但当您理解此过滤器的逻辑时,它工作得很好

名为“
”inputLightPosition“
的参数将控制聚光投影仪的位置,
”inputLightPointsAt“
参数用于控制灯光焦点位置,两者都使用CIVector(x,y,z)3D
x
应为最大输入图像宽度,
y
应为最大输入图像高度,
z
也用于聚光投影仪与图像的距离

例如,我们可以将其与平移手势一起使用来控制位置,首先为单独的控制灯光位置和灯光点创建枚举,称为mode和struct,用于存储所有位置,然后允许使用按钮选择模式,并在手势更改时调用过滤器。我尝试使用7个滑块控制参数,代码如下:

struct Spotlight {
  var posiX1: CGFloat = .zero
  var posiY1: CGFloat = .zero
  var posiZ1: CGFloat = .zero
  var posiX2: CGFloat = .zero
  var posiY2: CGFloat = .zero
  var posiZ2: CGFloat = .zero
  var lightColor: UIColor = .yellow
  var brightness: CGFloat = 1.0
  var concentration: CGFloat = 0.1
}

public enum EffectType: String {
    case SpotLight = "CISpotLight"
}

private func getCoreImage() -> CIImage? {
    return CIImage(image: self.inputImage)
}

private func adjustSpotlightFilterWith(spotlight: Spotlight) {
    // Create a filter
    let filter = CIFilter(name: EffectType.SpotLight.rawValue)
    // Create core image and assign it to filter as input image
    let coreImage = getCoreImage()
    filter?.setValue(coreImage, forKey: kCIInputImageKey)
    // Here adjust spot projector positions
    filter?.setValue(CIVector(x: spotlight.posiX1, y: spotlight.posiY1, z: spotlight.posiZ1), forKey: "inputLightPosition")
    // And here direction of light
    filter?.setValue(CIVector(x: spotlight.posiX2, y: spotlight.posiY2, z: spotlight.posiZ2), forKey: "inputLightPointsAt")
    filter?.setValue(spotlight.brightness, forKey: kCIInputBrightnessKey)
    // This parameter used for size of the spotlight.
    filter?.setValue(spotlight.concentration[![enter image description here][1]][1], forKey: "inputConcentration")
    // Change color of light with this parameter 
    filter?.setValue(CIColor(cgColor: spotlight.lightColor.cgColor), forKey: kCIInputColorKey)
    guard let outputImage = filter?.outputImage else {
        print("Cannot get 'outputImage' from filter!")
        return
    }
    let context = CIContext(mtlDevice: MTLCreateSystemDefaultDevice()!)
    guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else {
        print("Cannot convert 'outputImage' to core graphic image!")
        return
    }
    // The image will be reversed thats why you can rotate it as you want
    let finalImage = UIImage(cgImage: cgImage, scale: originalImage.scale, orientation: .upMirrored)
    // Use your result image
    mainImageView.image = finalImage
}



@IBAction func sliderValueChanged(_ sender: UISlider) {
    let value = CGFloat(sender.value)
    switch sender.tag {
    case 0:
        spotlight.posiX1 = value
        break
    case 1:
        spotlight.posiY1 = value
        break
    case 2:
        spotlight.posiZ1 = value
        break
    case 3:
        spotlight.posiX2 = value
        break
    case 4:
        spotlight.posiX2 = value
        break
    case 5:
        spotlight.posiZ1 = value
        break
    case 6:
        spotlight.brightness = value
    case 7:
        spotlight.consantration = value
        break
    default:
        break
    }
    
    adjustSpotlightFilterWith(spotlight: spotlight)
}
截图:
[1] :

@MidhunMP好吧,当我打印
ciImage
时,我得到了
,所以它肯定不是零。我还向工作区添加了
CoreImage
框架,并将其导入到类中。还有其他想法吗?另外请看我的编辑,修改后的过滤器输出和过滤器不是零。如果问题出在
ciImage
上,两个过滤器的结果都是nil。这是错误的信息。在这里,我从苹果的文档中发现:可以在OS X v10.4及更高版本和iOS 9及更高版本中使用。@AbdulYasin 2014年7月15日,最新的系统是iOS 7.X。2014年9月18日,苹果发布了iOS 8。他们从iOS9(2016年)开始增加了对西斯波特效应的支持。三年多前,答案是正确的。现在不是了。谢谢你指出这一点。