【问题标题】:How can I apply a filters to ONE image?如何将过滤器应用于 ONE 图像?
【发布时间】:2020-01-21 21:17:39
【问题描述】:

我是 Swift 的初学者,并制作了一个应用程序“照片编辑器”。我有个问题。我需要对一个图像应用一些过滤器。我有四个滑块(棕褐色、对比度、亮度、饱和度)和一个图像。我想将所有这些过滤器应用于我的图像。

我尝试在代码中更改我的逻辑,但我遇到了同样的问题

@objc func sliderValueDidChange(sender: UISlider!) 

    if sender.tag == 0 {
            let originalCIImage = CIImage(image: self.image!)
            let value = sender.value
            self.sepiaLabelValue.text = String(Int(value*100))
            if  let sepiaCIImage = sepiaFilter(originalCIImage!, intensity: Double(value)) {
                filteredImage = sepiaCIImage
                self.imageView.image = UIImage(ciImage: sepiaCIImage)
            }

        } else if sender.tag == 1 {
            let originalCIImage = CIImage(image: self.image!)
            let value = sender.value
            self.brightnessValue.text = String(Int(value*100))
            if let brightnessCIImage = brightnessFilter(originalCIImage!, intensity: Double(value)) {
                filteredImage = brightnessCIImage
                self.imageView.image = UIImage(ciImage:brightnessCIImage)
            }

        } else if sender.tag == 2 {
            let originalCIImage = CIImage(image: self.image!)
            let value = sender.value
            self.contrastLabel.text = String(Int(value*100))
            let contrastCIImage = contrastFilter(originalCIImage!, intensity: Double(value))
            self.imageView.image = UIImage(ciImage:contrastCIImage!)

        } else if sender.tag == 3 {
            let originalCIImage = CIImage(image: self.image!)
            let value = sender.value
            self.saturationValue.text = String(Int(value*100))
            let saturationCIImage = saturationFilter(originalCIImage!, intensity: Double(value))
            self.imageView.image = UIImage(ciImage:saturationCIImage!)
        }
}


func sepiaFilter(_ input: CIImage, intensity: Double) -> CIImage?
    {
        let sepiaFilter = CIFilter(name:"CISepiaTone")
        sepiaFilter?.setValue(input, forKey: kCIInputImageKey)
        sepiaFilter?.setValue(intensity, forKey: kCIInputIntensityKey)
        return sepiaFilter?.outputImage
    }

    func brightnessFilter(_ input: CIImage, intensity: Double) -> CIImage? {
        let brightnessFilter = CIFilter(name: "CIColorControls")
        brightnessFilter?.setValue(input, forKey: kCIInputImageKey)
        brightnessFilter?.setValue(intensity, forKey: kCIInputBrightnessKey)
        return brightnessFilter?.outputImage
    }

    func contrastFilter(_ input: CIImage, intensity: Double) -> CIImage? {
        let contrastFilter = CIFilter(name: "CIColorControls")
        contrastFilter?.setValue(input, forKey: kCIInputImageKey)
        contrastFilter?.setValue(intensity, forKey: kCIInputContrastKey)
        return contrastFilter?.outputImage
    }

    func saturationFilter(_ input: CIImage, intensity: Double) -> CIImage? {
        let saturationFilter = CIFilter(name: "CIColorControls")
        saturationFilter?.setValue(input, forKey: kCIInputImageKey)
        saturationFilter?.setValue(intensity, forKey: kCIInputSaturationKey)
        return saturationFilter?.outputImage
    }

当我应用第一个过滤器然后下一个过滤器时,第一个过滤器的值被建立为开始状态。如何将所有过滤器应用于我的图像?

【问题讨论】:

  • 使用switch 而不是else if。它更容易理解并且工作原理相同。
  • 好吧。我改变了这个,但它并没有解决我的问题(((
  • 好的,谢谢您的信息!但这对我来说很难,因为我不知道它如何应用于我的代码。大体理解了链的意思,但是不知道怎么重写代码

标签: ios swift uiimageview uikit cifilter


【解决方案1】:

正如 Gigi 所说,诀窍是在值更改时始终将两个过滤器应用于图像。这应该可以解决问题:

let colorControlsFilter = CIFilter(name: "CIColorControls")!
let sepiaFilter = CIFilter(name:"CISepiaTone")!


@objc func sliderValueDidChange(sender: UISlider!) {
    switch sender.tag {
    case 0: 
        let value = sender.value
        self.sepiaLabelValue.text = String(Int(value*100))
        self.sepiaFilter.setValue(value, forKey: kCIInputIntensityKey)
    case 1:
        let value = sender.value
        self.brightnessValue.text = String(Int(value*100))
        self.colorControlsFilter.setValue(value, forKey: kCIInputBrightnessKey)
    case 2:
        let value = sender.value
        self.contrastLabel.text = String(Int(value*100))
        self.colorControlsFilter.setValue(value, forKey: kCIInputContrastKey)
    case 3:
        let value = sender.value
        self.saturationValue.text = String(Int(value*100))
        self.colorControlsFilter.setValue(value, forKey: kCIInputSaturationKey)
    default: pass
    }

    self.updateImage()
}

func updateImage() {
    let originalCIImage = CIImage(image: self.image!)
    // first apply color controls (contrast, brightness, saturation), then sepia
    self.colorControlsFilter.setValue(originalCIImage, forKey: kCIInputImageKey)
    self.sepiaFilter.setValue(self.colorControlsFilter.outputImage, forKey: kCIInputImageKey)
    self.imageView.image = UIImage(ciImage: self.sepiaFilter.outputImage!)
} 

【讨论】:

  • 您好!我可以应用此过滤器,但使用 kCIInputSharpnessKey 而不是“棕褐色”过滤器,因为我想创建一个新的视图控制器,其中只有像“棕褐色”这样的过滤器。但是在这个视图控制器上,我只想留下一个标准的过滤器,比如“对比度”、“亮度”等等。
  • 当然,您可以随意更换任何过滤器。只要您将它们“链接”在updateImage 中(使用一个过滤器的输出作为下一个过滤器的输入),它应该可以工作。
  • 好吧。但是当你初始化一个棕褐色过滤器时,我如何初始化一个锐度过滤器。让Sharp = CIFilter(名称:“kCIInputSharpnessKey”)!它不起作用((
  • kCIInputSharpnessKey 不是滤镜名称,而是某些滤镜使用的锐度参数的名称。您正在寻找的是 CISharpenLuminance 过滤器:cifilter.io/CISharpenLuminance
  • 您好!我的应用程序工作有问题。可能你知道,如何解决它? stackoverflow.com/questions/58092349/…
猜你喜欢
  • 2021-11-11
相关资源
最近更新 更多