CISpotLight过滤器和零结果

时间:2014-07-15 12:10:30

标签: ios objective-c core-image

我正在努力实现聚光效果。我写了一些基于的代码 the Apple CoreImageFilterReference然而它似乎无效。 filter对象为nil(显然outputImagenewImage也是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];

3 个答案:

答案 0 :(得分:1)

如果有人可能从中获得帮助,我会将此作为迟到的答案发布。

实际上对于Spotlight过滤器来说有点棘手。您需要将其Point设置为小心点亮。

        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

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

答案 1 :(得分:0)

据我所知,你的目标是iOS,根据文档:

Availability
Available in OS X v10.4 and later.

在iOS上无法使用。

答案 2 :(得分:0)

控制灯光位置和对焦区域有点困难,但是当您了解此滤镜的逻辑时,效果会很好。

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

例如,我们可以将它与平移手势一起使用来控制位置,首先为单独的控制光位置和光点创建枚举,称为模式和用于存储所有位置的结构,然后允许使用按钮选择模式并通过手势更改调用过滤器。我尝试使用 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]:https://i.stack.imgur.com/BiQNf.jpg