如何使用 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!)
}
}
我正在开发一个照片滤镜应用程序。我想用一个滑块更改亮度和对比度。我可以更改它们,但是当我跳转到对比度时,我会松开亮度更改。哇,我可以保留应用了亮度的图像,然后继续更改对比度吗?
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!)
}
}