如何使用 Swift 使用一个 UISlider 更改亮度和对比度

How to change Brightness and Contrast with one UISlider with Swift

我正在开发一个照片滤镜应用程序。我想用一个滑块更改亮度和对比度。我可以更改它们,但是当我跳转到对比度时,我会松开亮度更改。哇,我可以保留应用了亮度的图像,然后继续更改对比度吗?

 if sender.tag == 0 {
        
       
        self.coreImage = CIImage(image: (originalImage.image!))!
        
        
        let filter2 = CIFilter(name: "CIColorControls" )
        filter2!.setValue(coreImage, forKey: kCIInputImageKey)
        filter2?.setValue(sender.value, forKey: kCIInputBrightnessKey)
        
        brightnessValue = sender.value
        
        
        filter2!.setValue(coreImage, forKey: kCIInputImageKey)
        let filteredImageData2 = filter2!.value(forKey: kCIOutputImageKey) as! CIImage
        
        let filteredImageRef = ciContext.createCGImage(filteredImageData2, from: filteredImageData2.extent)
        let imageForButton = UIImage(cgImage: filteredImageRef!)
        
        
        
        originalImage.isHidden = true
        imageToFilter.image = imageForButton
    }
    
    else if sender.tag == 1 {

        
        self.coreImage = CIImage(image: (originalImage.image!)) ?? CIImage()
        
        let filter2 = CIFilter(name: "CIColorControls" )
        filter2!.setValue(coreImage, forKey: kCIInputImageKey)
        filter2?.setValue(sender.value, forKey: kCIInputContrastKey)
        
        filter2!.setValue(coreImage, forKey: kCIInputImageKey)
        let filteredImageData2 = filter2!.value(forKey: kCIOutputImageKey) as! CIImage
        
        let filteredImageRef = ciContext.createCGImage(filteredImageData2, from: filteredImageData2.extent)
        let imageForButton = UIImage(cgImage: filteredImageRef!)
        
        
        
        originalImage.isHidden = true
        imageToFilter.image = imageForButton


        }

下面的代码控制按钮以及要更改的内容

if (Lb == "Brightness") {
        sliderColor.tag = 0
        sliderColor.minimumValue = -1.0
        sliderColor.maximumValue = 1.0
        sliderColor.value = 0.0
        
    
        
    } else if (Lb == "Contrast") {
        sliderColor.tag = 1

        
        sliderColor.minimumValue = 0.0
        sliderColor.maximumValue = 4.0
        sliderColor.value = 1.0
        
        
    } 

我知道这是因为我每次更改亮度或对比度时都使用 originalImage。但是,如果我将其更改为 imageToFilter,事情就会变得草率。

有什么想法吗?

每次值更改时,您都在创建一个新的 CIFilter。新过滤器不知道以前的设置。因此,解决此问题的最简单方法是仅在方法外部创建一个 CIFilter 实例(例如作为实例变量),并且仅在滑块回调中更改滤镜的亮度或对比度值。它应该以这种方式记住以前的值。

因为您必须保留两个过滤器键值的参考和跟踪,并在滑块值更改时同时应用两个键过滤器。

这是演示代码。

注意:因为这只是一个演示,所以我使用了强制展开。您需要处理 nil 值。

class ViewController: UIViewController {
    
    @IBOutlet weak var imageToFilter: UIImageView!
    
    public var brightness : Float = 0.0
    public var contrast : Float = 1.0
    
    var filter: CIFilter? = CIFilter(name: "CIColorControls")
    var originalImage = UIImage(named: "image_name")
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    func applyImageFilter(for image: UIImage) -> UIImage? {
        
        guard let sourceImage = CIImage(image: image),
              let filter = self.filter else { return nil }
        
        filter.setValue(sourceImage, forKey: kCIInputImageKey)
        
        filter.setValue(self.contrast, forKey: kCIInputContrastKey)
        filter.setValue(self.brightness, forKey: kCIInputBrightnessKey)
        
        
        guard let output = filter.outputImage else { return nil }
        
        guard let outputCGImage = CIContext().createCGImage(output, from: output.extent) else { return nil }
        
        let filteredImage = UIImage(cgImage: outputCGImage, scale: image.scale, orientation: image.imageOrientation)
        
        return filteredImage
    }
    
    @IBAction func sliderValueChangeAction(_ sender: UISlider) {
        if sender.tag == 0 {
            self.brightness = sender.value
        
        } else if sender.tag == 1 {
            self.contrast = sender.value
        }
        
        imageToFilter.image = self.applyImageFilter(for: originalImage!)
    }
}