【问题标题】:How to change Brightness and Contrast with one UISlider with Swift如何使用一个带有 Swift 的 UISlider 更改亮度和对比度
【发布时间】:2021-08-04 19:07:11
【问题描述】:

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

 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,事情就会变得草率。

有什么想法吗?

【问题讨论】:

  • 我认为您使用了两个滑块但其中一个动作是对还是错?
  • 不,一个滑块。但我忘记了更新slider.tag 以控制当时应用哪种效果的行。
  • 您可以使用两个变量来跟踪亮度和对比度的值,然后您就可以使用它了。或者第二种方法是对两个操作继续使用相同的 CIFilter,而不是为每个操作创建不同的。
  • 感谢您的建议,但仅使用相同的 CIFilter 似乎不起作用:(
  • 那么最好使用两个 var 并使用滑块值设置和更新这两个 var。当您移动滑块时,任何一个都应用带有轨道值的过滤键。

标签: ios swift core-graphics cifilter


【解决方案1】:

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

这里是演示代码。

注意:由于这只是一个演示,我使用了强制展开。你需要处理 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!)
    }
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 谢谢,这完全有道理。我试图创建一个全局 CIFilter 而不是每次都创建。但我仍然有同样的问题。请问我输出和显示图片的时候是不是做错了什么?
    • 好像没问题。 ?
    猜你喜欢
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 2014-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多