简体   繁体   English

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

[英]How to change Brightness and Contrast with one UISlider with Swift

I am working on a Photo Filter App.我正在开发照片过滤器应用程序。 I want to change Brightness and Contrast with a single slider.我想用一个 slider 改变亮度和对比度。 I can change them but when I jump to Contrast I loose Brightness changes.我可以改变它们,但是当我跳到对比度时,我失去了亮度变化。 Wow can I keep the Brightness applied image and then continue with Contrast change.哇,我可以保留应用亮度的图像,然后继续更改对比度。

 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


        }

and the following code controls the button and what to change下面的代码控制按钮和改变什么

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
        
        
    } 

I am aware of it is caused by the fact that I use originalImage everytime I change Brightness or Contrast.我知道这是由于我每次更改亮度或对比度时都使用 originalImage 造成的。 But if I change it to imageToFilter things get sloppy.但是,如果我将其更改为 imageToFilter,事情就会变得草率。

Any ideas?有任何想法吗?

You are creating a new CIFilter every time the value changes.每次值更改时,您都会创建一个新的CIFilter The new filter doesn't know the previous setting.新过滤器不知道以前的设置。 So the easiest way to solve this is to only create one CIFilter instance outside of the method (for instance as an instance variable) and only change the filter's brightness or contrast value in your slider callback.所以解决这个问题的最简单方法是只在方法之外创建一个CIFilter实例(例如作为实例变量),并且只在 slider 回调中更改过滤器的亮度或对比度值。 It should remember previous values this way.它应该以这种方式记住以前的值。

As you have to keep reference and track for both filter key-value and apply both key filters at the same time while slider value changes.因为您必须保留两个过滤器键值的参考和跟踪,并在 slider 值更改时同时应用两个键过滤器。

Here is the demo code.这是演示代码。

Note: As this is just a demo I used force unwrapping.注意:由于这只是一个演示,我使用了强制展开。 You need to handle nil value.您需要处理 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!)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM