LanK
LanK

Reputation: 76

unrecognized selector sent to instance - How to fix: Error Loading picture from photo album

I get the following error when trying to load picture from photo album, I'm not sure why: unrecognized selector sent to instance Below is my code and below is part of my error stack:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFNumber extent]: unrecognized selector sent to instance 0x60000022d440' *** First throw call stack: ( 0 CoreFoundation 0x000000010efe21e6 __exceptionPreprocess + 294 1 libobjc.A.dylib 0x000000010d1e9031 objc_exception_throw + 48 2 CoreFoundation 0x000000010f063784 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132 3 CoreFoundation 0x000000010ef64898 ___forwarding_ + 1432 4 CoreFoundation 0x000000010eff5d28 forwarding_prep_1_ + 120 5 CoreImage 0x000000010daecf17 -[CISepiaTone outputImage] + 152

Please find my source code below:

import UIKit
import CoreImage

class ViewController: UIViewController,  UINavigationControllerDelegate {
    //outlet for image to be filtered
    @IBOutlet weak var imageToFilter: UIImageView!

    //outlet for slider to manipulate intensity as slider is dragged
    @IBOutlet weak var filterIntensity: UISlider!

    //property to store UIImage containing the image selected by user from photo album
    var currentImage: UIImage!

    //context from CoreImage Framework to handle rendering of the image for Wakanda Filter
    var imageContext: CIContext!

    //CoreImage Filter to store filters selected by the user
    var currentImageFilters: CIFilter!

    override func viewDidLoad() {
        super.viewDidLoad()

        //objects of coreContext and coreFilterd
        imageContext = CIContext()
        currentImageFilters = CIFilter(name: "CISepiaTone")

        //title to appear on nav
        title = "Wakanda Filter"
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(importPictureFromAlbum))
    }

    //action to update UI when user increases or decreases intensity
    @IBAction func intensityValueChanged(_ sender: UISlider) {
        processImageWithFilter()
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo  info: [String : Any]) {
        guard let imageSelected = info[UIImagePickerControllerEditedImage] as? UIImage else {
            return
        }

        dismiss(animated: true)

        currentImage = imageSelected

        //setting imported image as value to Filter object then manipulating
        let initialImageForFilters = CIImage(image: currentImage)
        currentImageFilters.setValue(initialImageForFilters, forKey: kCIInputImageKey)

        //calling on method to process the image
        processImageWithFilter()
    }

    func processImageWithFilter(){
        currentImageFilters.setValue(filterIntensity.value, forKey: kCIInputImageKey)
        if let computerGeneratedImage = imageContext.createCGImage(currentImageFilters.outputImage!, from: currentImageFilters.outputImage!.extent){
            let processedImage = UIImage(cgImage: computerGeneratedImage)
            self.imageToFilter.image = processedImage
        }
    }
}

extension ViewController: UIImagePickerControllerDelegate {
    //objective c method to control method for selector how to import picture from album
    @objc func importPictureFromAlbum(){
        //creating an object of UIImagePickerController class (will allow editing of images too by modifying Info.plist
        let imagePicker = UIImagePickerController()

        //allow editing of the image
        imagePicker.allowsEditing = true

        //assigning delegate
        imagePicker.delegate = self

        present(imagePicker, animated: true)
    }
}

Upvotes: 2

Views: 1594

Answers (2)

Hardik Bar
Hardik Bar

Reputation: 1760

import UIKit
import CoreImage

class ViewController: UIViewController {
    //outlet for image to be filtered
    @IBOutlet weak var imageToFilter: UIImageView!
    //outlet for slider to manipulate intensity as slider is dragged
    @IBOutlet weak var filterIntensity: UISlider!

    //property to store UIImage containing the image selected by user from photo album
    var currentImage: UIImage!
    let imagePicker = UIImagePickerController()
    //context from CoreImage Framework to handle rendering of the image for Wakanda Filter
    var imageContext: CIContext!

    //CoreImage Filter to store filters selected by the user
    var currentImageFilters: CIFilter!

    override func viewDidLoad() {
        super.viewDidLoad()

        //objects of coreContext and coreFilterd
        imageContext = CIContext()
        currentImageFilters = CIFilter(name: "CISepiaTone")

        //title to appear on nav
        title = "Wakanda Filter"
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(importPictureFromAlbum))
    }

    //action to update UI when user increases or decreases intensity
    @IBAction func intensityValueChanged(_ sender: UISlider) {
        processImageWithFilter()
    }


@objc func importPictureFromAlbum(){
        //creating an object of UIImagePickerController class (will allow editing of images too by modifying Info.plist

        //allow editing of the image
        imagePicker.allowsEditing = true

        //assigning delegate
        imagePicker.delegate = self

        present(imagePicker, animated: true)
    }

    func processImageWithFilter(){
        currentImageFilters.setValue(filterIntensity.value, forKey: kCIInputIntensityKey)
        if let computerGeneratedImage = imageContext.createCGImage(currentImageFilters.outputImage!, from: currentImageFilters.outputImage!.extent){
            let processedImage = UIImage(cgImage: computerGeneratedImage)
            self.imageToFilter.image = processedImage
        }
    }
}

extension ViewController: UIImagePickerControllerDelegate ,UINavigationControllerDelegate  {
         func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo  info: [String : Any]) {
        guard let imageSelected = info[UIImagePickerControllerEditedImage] as? UIImage else {
            return
        }

        dismiss(animated: true)

        self.currentImage = imageSelected

        //setting imported image as value to Filter object then manipulating
        let initialImageForFilters = CIImage(image: currentImage)
        currentImageFilters.setValue(filterIntensity.value, forKey: kCIInputIntensityKey)

        //calling on method to process the image
        self.processImageWithFilter()
    }


func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    dismiss(animated: true, completion: nil)
}

}

Upvotes: 0

rmaddy
rmaddy

Reputation: 318774

The CISepiaTone filter expects two parameters:

inputImage: A CIImage object whose display name is Image.

inputIntensity: An NSNumber object whose attribute type is CIAttributeTypeScalar and whose display name is Intensity.

Your error is from this line:

currentImageFilters.setValue(filterIntensity.value, forKey: kCIInputImageKey)

Either change the value to be the image or change the key to kCIInputIntensityKey.

Given that you set the image earlier, you probably want to change the key on this line.

currentImageFilters.setValue(filterIntensity.value, forKey: kCIInputIntensityKey)

Upvotes: 4

Related Questions