How to change Brightness, Contrast and Saturation using CIColorControls via UISlider with Swift
You problem is that every time you slide the slider you are applying the filter to the resulting image of the previous filter instead of applying it to the original image. Btw you can make your filter a lot more responsive when sliding the UISlider if you just create a CGImage once the user is finished. Your code should look like this:
let displayinPercentage = Int((sender.value/200) * 10000)
brightnessValueLabel.text = String(displayinPercentage)
let beginImage = CIImage(image: originalImage)
filter.setValue(beginImage, forKey: kCIInputImageKey)
filter.setValue(sender.value, forKey: kCIInputBrightnessKey)
if let ciimage = filter.outputImage {
filteredImage = ciimage
selectedPictureImageView.image = UIImage(ciImage: filteredImage)
}
How to change Brightness and Contrast with one UISlider with Swift
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.
Here is the demo code.
Note: As this is just a demo I used force unwrapping. You need to handle nil value.
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!)
}
}
CIColorControls wrong brightness
The "Brightness" slider in Photos is not mapped to the "traditional" brightness value (that is used in CIColorControls
). Apple uses more sophisticated algorithms under the hood that, among others, take the image's content into account. I'm afraid there's no single core image filter that can reproduce that result. But it looks like Photos also increased the contrast when reducing the brightness, so you could try that.
Is there a setting for CIColorControls that leaves an image unaffected?
These are the values that should return the original image
kCIInputSaturationKey: 1.0
kCIInputBrightnessKey: 0.0
kCIInputContrastKey: 1.0
Brightness, saturation and contrast with ColorMatrix in Swift
The colorMatrix property is nil
because you never initialized it properly.
Delete dynamic var colorMatrix: CIFilter?
from your controller and use the code below.
class editionViewController: UIViewController {
@IBOutlet weak var editionImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
if let image = UIImage(named: "myImage.png") {
editionImageView.image = image.liaFilter()
}
}
}
extension UIImage {
//Lia filter
func liaFilter() -> UIImage {
let inImage = CIImage(image: self)
let rgbVector = CIVector(x: 0, y: 1, z: 0, w: 0)
let aVector = CIVector(x: 0, y: 0, z: 0, w: 1)
dynamic let colorMatrix = CIFilter(name: "CIColorMatrix")
if colorMatrix != nil {
colorMatrix?.setDefaults()
colorMatrix?.setValue(inImage, forKey: kCIInputImageKey)
colorMatrix?.setValue(rgbVector, forKey: "inputRVector")
colorMatrix?.setValue(rgbVector, forKey: "inputGVector")
colorMatrix?.setValue(rgbVector, forKey: "inputBVector")
colorMatrix?.setValue(aVector, forKey: "inputAVector")
if let output = colorMatrix?.outputImage, let cgImage = CIContext().createCGImage(output, from: output.extent) {
return UIImage(cgImage: cgImage)
}
}
return self
}
}
I fixed your UIImage extension method.
I put the initializer for CIFilter in the Extension method so you don't have to hold a reference for it.
Hope this help.
How to adjust brightness and contrast of CGImageRef
You want Core Image. The filter for your purpose is CIColorControls.
Change filter intensity like brightness from 0 to 100 via slider control in gpuimage2 swift
Every time your slider value changes, you're creating a new ContrastAdjustment filter instance and attaching it to the picture. Your old filter instance is still there, and the RenderView will ignore any inputs beyond the first one that goes into it. In fact, you should have been seeing warnings on the console telling you about that fact that you're adding too many inputs to the RenderView.
Instead of creating a whole new ContrastAdjustment filter each time, simply save your contrast filter as an instance variable and adjust its contrast
property when the slider changes.
Related Topics
Applying Different Attributes for Different Portions of an Nsattributedstring
Save Scrollviews Position and Scroll Back to It Later (Offset to Position)
What Exactly Does ': Class' Do in a Protocol Declaration
How to Print Name of The Day of The Week
Force UIsplitviewcontroller to Always Show Master (Only) in Landscape (On iPhone 6 Plus)
Rgba to Abgr: Inline Arm Neon Asm for iOS/Xcode
How to Remove "Optional" from String
Preventing Erasure of User Data While Upgrading iOS Application via Itunes
Swift (Beta 3) "Nsdictionary? Does Not Conform to Protocol 'Equatable'"
Two Button Simultaneous Press Input
Swift Compiler Error: Use of Unresolved Identifier 'Name'
Mpvolumeview Does Not Show Route Button on Launch
Why [Uiscreen Mainscreen].Bounds] Is Not Returning Full Screen Size
Form Nspredicate from String That Contains Id's
How to Switch Programmatically to Dark Mode Swift
iOS Getting My Location Regularly and Setting Button to Get My Location - Google Map Not Working