我正在努力实现聚光效果。我写了一些基于的代码
the Apple CoreImageFilterReference然而它似乎无效。 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];
答案 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)
}