Hello, I have set up 16 CIFilter effects and for each effect I have created methods with identical functionality and due to the repetition I've been going through performance issues. The build time takes around 10-13 seconds. I have created a method called "applyFilterTo" to integrate the CIFilters under this method but then the filters started not to work anymore. Could you please give me some insight about how I can increase the performance of the app ?
func effectsSliderSepiaTone() {
sliderControl.addTarget(self, action: #selector(sliderSepiaToneDidChange(_:image:_:)), for: .allTouchEvents)
sliderControl.translatesAutoresizingMaskIntoConstraints = false
sliderControl.minimumValue = 0
sliderControl.maximumValue = 1
sliderControl.isContinuous = true
sliderControl.tintColor = UIColor.blue
view.addSubview(sliderControl)
NSLayoutConstraint.activate([
sliderControl.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
sliderControl.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30),
sliderControl.bottomAnchor.constraint(equalTo: resetConfirmCollectionView.topAnchor, constant: -50)])
}
func imageSepiaTone(imgView: UIImageView, sliderValue: CGFloat, image: UIImage){
let aCGImage = image.cgImage
let aCIImage = CIImage(cgImage: aCGImage!)
let sepiaToneFilter = CIFilter(name: "CISepiaTone")
sepiaToneFilter!.setDefaults()
sepiaToneFilter?.setValue(aCIImage, forKey: kCIInputImageKey)
sepiaToneFilter?.setValue(sliderValue - 0.5, forKey: kCIInputIntensityKey)
let outputImage = sepiaToneFilter?.outputImage!
let cgimg = context.createCGImage(outputImage!, from: outputImage!.extent)
let newUIImage = UIImage(cgImage: cgimg!, scale: image.scale, orientation: image.imageOrientation)
imgView.image = newUIImage
}
@objc private func sliderSepiaToneDidChange(_ sender: UISlider!, image: UIImage,_ event: UIEvent) {
if let touchEvent = event.allTouches?.first {
switch touchEvent.phase {
case .moved:
labelControl.text = String(displayInPercentage)
if updatedImage == nil {
photoImageView.image = pickedImage
imageSepiaTone(imgView: photoImageView, sliderValue: CGFloat(sender.value), image: pickedImage!)
} else {
photoImageView.image = updatedImage
imageSepiaTone(imgView: photoImageView, sliderValue: CGFloat(sender.value), image: updatedImage!)
}
case .ended:
updatedImage = photoImageView.image
UserDefaults.standard.setValue(sliderControl.value, forKey: "slider_sepiatone")
default:
break
}
}
labelControl.textAlignment = .center
labelControl.numberOfLines = 0
labelControl.textColor = UIColor.gray
labelControl.font = UIFont.systemFont(ofSize: 16)
labelControl.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(labelControl)
NSLayoutConstraint.activate([labelControl.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
labelControl.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30),
labelControl.bottomAnchor.constraint(equalTo: resetConfirmCollectionView.topAnchor, constant: -80)])
}
class Effects {
var context: CIContext! = CIContext(options: [.workingColorSpace: NSNull(), .outputColorSpace: NSNull()])
var currentFilter: CIFilter!
struct Filter {
let filterName: String
var filterEffectValue: Any?
var filterEffectValueName: String?
init(filterName: String, filterEffectValue: Any?, filterEffectValueName: String?) {
self.filterName = filterName
self.filterEffectValue = filterEffectValue
self.filterEffectValueName = filterEffectValueName
}
func applyFilterTo(image: UIImage, filterEffect: Filter, sliderValue: CGFloat?) -> UIImage? {
guard let cgImage = image.cgImage else { return nil }
// let context = CIContext(options: nil)
let ciImage = CIImage(cgImage: cgImage)
currentFilter = CIFilter(name: filterEffect.filterName)
currentFilter!.setDefaults()
if currentFilter == CIFilter(name: "CIUnsharpMask") {
currentFilter?.setValue(ciImage, forKey: kCIInputImageKey)
currentFilter?.setValue(sliderValue! - 0.5, forKey: kCIInputIntensityKey)
}
else if currentFilter == CIFilter(name: "CIGaussianBlur") {
// currentFilter!.setDefaults()
currentFilter?.setValue(ciImage, forKey: kCIInputImageKey)
currentFilter?.setValue(sliderValue! - 0.5, forKey: kCIInputRadiusKey)
}
else if currentFilter == CIFilter(name: "CICMYKHalftone") {
// currentFilter!.setDefaults()
currentFilter?.setValue(ciImage, forKey: kCIInputImageKey)
currentFilter?.setValue(sliderValue! - 0.5, forKey: kCIInputWidthKey)
}
else {
currentFilter?.setValue(ciImage, forKey: kCIInputImageKey)
if let filterEffectValue = filterEffect.filterEffectValue, let filterEffectValueName = filterEffect.filterEffectValueName {
currentFilter?.setValue(filterEffectValue, forKey: filterEffectValueName)
}
}
var filteredImage: UIImage?
if let output = currentFilter?.value(forKey: kCIOutputImageKey) as? CIImage,
let cgiImageResult = context.createCGImage(output, from: output.extent) {
filteredImage = UIImage(cgImage: cgiImageResult, scale: image.scale, orientation: image.imageOrientation)
}
return filteredImage
}
}