I am making a face detection app. I have written some code for detection but I am getting an error. Kindly suggest me an alternate solution.
Here is the code, and the error is at line number 3.
import UIKit
import CoreImage
class ViewController: UIViewController ,UIAlertViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var imageView: UIImageView!
#IBAction func Moodify(_ sender: UIButton) {
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
picker.sourceType = .camera
self.present(picker, animated: true, completion: { _ in })
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [AnyHashable: Any]) {
let chosenImage = info[UIImagePickerControllerEditedImage]
self.imageView!.image = chosenImage as? UIImage
picker.dismiss(animated: true, completion: { _ in })
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: { _ in })
}
}
func detect() {
guard let personciImage = CIImage(image: personPic.image!) else {
return
}
let accuracy = [CIDetectorAccuracy: CIDetectorAccuracyHigh]
let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: accuracy)
let faces = faceDetector.featuresInImage(personciImage)
for face in faces as! [CIFaceFeature] {
print("Found bounds are \(face.bounds)")
let faceBox = UIView(frame: face.bounds)
faceBox.layer.borderWidth = 3
faceBox.layer.borderColor = UIColor.redColor().CGColor
faceBox.backgroundColor = UIColor.clearColor()
personPic.addSubview(faceBox)
if face.hasLeftEyePosition {
print("Left eye bounds are \(face.leftEyePosition)")
}
if face.hasRightEyePosition {
print("Right eye bounds are \(face.rightEyePosition)")
}
}
}
override func viewDidLoad() {
let alert = UIAlertController(title: "Error", message: "Device has no camera", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
/* if !UIImagePickerController.isSourceTypeAvailable(.camera) {
let myAlertView = UIAlertView (title: "Error", message: "Device has no camera", delegate: nil, cancelButtonTitle: "OK", otherButtonTitles: "")
myAlertView.show()
} */
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You need to declare it and connect to a UIImageView in storyboard.
#IBOutlet weak var personPic: UIImageView!
This is basic of programming. How can you use something that you haven't declared, right? Ok good luck in your project.
Related
I already worked on UIImagePickerController. This code was already works fine in Xcode 11.3. But when I run on Xcode 12 Image picker delegate is not calling in Xcode12.
/// Picked Image
struct PickedImage {
var image: UIImage?
var api: String?
}
/// Image picker
class ImagePicker: NSObject {
typealias ImagePickerHandler = ((_ selected: PickedImage) -> ())
private weak var presentationController: UIViewController?
let pickerController: UIImagePickerController = UIImagePickerController()
var apiKey: String?
private var handler: ImagePickerHandler? = nil
private func action(for type: UIImagePickerController.SourceType, title: String) -> UIAlertAction? {
guard UIImagePickerController.isSourceTypeAvailable(type) else {
return nil
}
return UIAlertAction(title: title, style: .default) { (action) in
DispatchQueue.main.async {
self.pickerController.mediaTypes = ["public.image"]
self.pickerController.sourceType = type
self.pickerController.delegate = self
self.presentationController?.present(self.pickerController, animated: true, completion: {
})
}
}
}
/// Present source view
/// - Parameter sourceView: view
func present(presentationController: UIViewController, completed: ImagePickerHandler? = nil) {
self.handler = completed
self.presentationController = presentationController
// self.delegate = delegate
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
if let action = self.action(for: .camera, title: "Take photo") {
alertController.addAction(action)
}
if let action = self.action(for: .savedPhotosAlbum, title: "Camera roll") {
alertController.addAction(action)
}
if let action = self.action(for: .photoLibrary, title: "Photo library") {
alertController.addAction(action)
}
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
// if UIDevice.current.userInterfaceIdiom == .pad {
// alertController.popoverPresentationController?.sourceView = sourceView
// alertController.popoverPresentationController?.sourceRect = sourceView.bounds
// alertController.popoverPresentationController?.permittedArrowDirections = [.down, .up]
// }
self.presentationController?.present(alertController, animated: true)
}
private func pickerController(didSelect image: UIImage?, imageURL: URL?) {
pickerController.dismiss(animated: true, completion: nil)
// self.delegate?.imagePicker(picker: self, didSelected: image, apikey: apiKey)
handler?(PickedImage(image: image, api: apiKey))
}
}
/// ImagePicker controller delegate
extension ImagePicker: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.pickerController(didSelect: nil, imageURL: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
self.pickerController(didSelect: info[.originalImage] as? UIImage, imageURL: info[.imageURL] as? URL)
}
}
When I check delegate is applied or not using breakpoint. like in console means
po imagepicker.delegate
there after image picker delegate was working fine. But when I remove breakpoint its delegate is not calling.
I don't know what is the reason. Why its not working. May I know how to fix this problem.
is there any reason to not put pickerController.delegate = self before self.presentationController?.present(pickerController, animated: true, completion: {})'?
if no, maybe you can put pickerController.delegate = self before that, and try again.
This is most likely because you're not retaining your picker controller in a variable. As soon as your function finishes, it gets deallocated.
For example I have something like this:
class MyClass: UIImagePickerControllerDelegate {
let imagePicker = UIImagePickerController()
}
func pickImageFromGallery() {
self.imagePicker.delegate = self
self.imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
self.imagePicker.allowsEditing = false
self.present(self.imagePicker, animated: true, completion: nil)
}
... and the delegate methods as well
You code was always wrong; it's just lucky if it ever worked:
let pickerController: UIImagePickerController = UIImagePickerController()
pickerController.mediaTypes = ["public.image"]
pickerController.sourceType = "Photo library"
self.presentationController?.present(pickerController, animated: true, completion: {
pickerController.delegate = self
})
Change to:
let pickerController: UIImagePickerController = UIImagePickerController()
pickerController.mediaTypes = ["public.image"]
pickerController.sourceType = .photoLibrary
pickerController.delegate = self
self.present(pickerController, animated: true)
I think you are doing a silly mistake. just change a few lines of code and then you are good to go.
just follow my Steps
=> Here ProfileViewController is my UIViewController where I am going to pick Image from Gallery and Set image to UIImageView. You have to use your UIViewController where you want to Pick an Image.
ProfileViewController: UIViewController{
let pickerController = UIImagePickerController()
viewDidLoad(){
}
#IBAction func pickImageAction(sender: UIButton){
self.openImagePicker()
}
func openImagePicker()
{
pickerController.delegate = self
pickerController.allowsEditing = true
pickerController.mediaTypes = ["public.image", "public.movie"]
pickerController.sourceType = .photoLibrary // Pick image from PhotoLibrary
//pickerController.sourceType = .savedPhotosAlbum // Pick Saved Images
//pickerController.sourceType = .camera // Click Image using Camera
self.present(pickerController, animated: true)
} //End of setupImagePicker
} // End of ProfileViewController
// MARK:- Delegate method for UIImagePicker
extension ProfileViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let image = info[.editedImage] as? UIImage else { return }
// image is your image which you picked from Image Gallery or using Camera.
// you can set this image directly to your UIImageView.
// self.yourImageView.image = image
// or you can compress this image, converting to JPG image type.
// compressionQuality will reduce your image quality and Image Size.
if let jpegData = image.jpegData(compressionQuality: 0.8) {
// you can use this compressed image.
}
self.dismiss(animated: true)
}// End of didFinishPickingMediaWithInfo
} // End of Extension
Hello i am using UIImagePicker to take images but while picking images i want to CROP that image.. How to do that
i am able to pick images from gallery to imageview but while selecting image i need to crop the image.
I have tried below code:
class AddNewEventViewController: UIViewController, UIPickerViewDelegate,UIImagePickerControllerDelegate, UIPickerViewDataSource,UINavigationControllerDelegate {
#IBOutlet weak var imgPick: UIImageView!
var picker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
hideKeyboardWhenTappedAround()
picker.delegate = self
picker.allowsEditing = true
}
#IBAction func addProfileBtnAction(_ sender: Any) {
let actionSheetController: UIAlertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
actionSheetController.popoverPresentationController?.sourceView = self.contentView
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in
}
actionSheetController.addAction(cancelAction)
let takePictureAction: UIAlertAction = UIAlertAction(title: "TakePhoto", style: .default) { action -> Void in
self.openCameraPicker()
}
actionSheetController.addAction(takePictureAction)
let choosePictureAction: UIAlertAction = UIAlertAction(title: "ChooseFromLibrary", style: .default) { action -> Void in
self.openPhotoGallery()
}
actionSheetController.addAction(choosePictureAction)
//Present the
self.present(actionSheetController, animated: true, completion: nil)
}
func openCameraPicker() {
picker.sourceType = UIImagePickerController.SourceType.camera
picker.cameraCaptureMode = .photo
picker.allowsEditing = true
picker.modalPresentationStyle = .fullScreen
present(picker,animated: true,completion: nil)
}
func openPhotoGallery() {
picker.sourceType = .photoLibrary
picker.allowsEditing = true
picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
present(picker, animated: true, completion: nil)
}
// MARK: - UIImagePickerControllerDelegate Methods
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let img = info[UIImagePickerController.InfoKey.editedImage] as? UIImage{
imgPick.image = img
}
else if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
self.imgPick.image = image
}
dismiss(animated: true, completion: nil)
}
}
like this i am getting.. no crop
here i am getting images from gallery to imageview but not getting crop.
How to crop the images, please help me with the code.
I check with your code and i found you are missing to set delegate of UIImagePickerController
I try with photoLibrary for now
class ImagePickerViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var imageView:UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.openPhotoGallery()
}
func openPhotoGallery() {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .photoLibrary
picker.allowsEditing = true
picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
present(picker, animated: true, completion: nil)
}
// MARK: - UIImagePickerControllerDelegate Methods
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let img = info[UIImagePickerController.InfoKey.editedImage] as? UIImage{
imageView.image = img
}
dismiss(animated: true, completion: nil)
}
}
I have a slight problem. I'm trying to make a camera in Swift Xcode, however, I've run into one problem and that is that "ImagePicked.image = image" keeps showing error. I have no idea why it does this. Photo of the interface of the app
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var ImagePicked: UIImageView!
#IBAction func openCamera(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(.camera) { //Is the camera an available source type?
let imagePicker = UIImagePickerController() //Declare variable imagePicker
imagePicker.delegate = self
imagePicker.sourceType = .camera;
imagePicker.allowsEditing = false //Tell Image Pickr not to edit camptured photo
self.present(imagePicker, animated: true, completion: nil) //Show the photo to the user
}
func openLibrary(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) { //Check if device has access to photo library
let imagePicker = UIImagePickerController() //Set up variable imagePicker
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary; //Set the source type to library
imagePicker.allowsEditing = true //Allow editing, so the user can move and crop their photo
self.present(imagePicker, animated: true, completion: nil) //Show UIImagePickerController to the user
}
}
func saveImage(_ sender: Any) {
let ImageData = ImagePicked.image!.jpegData(compressionQuality: 0.6)
let compressedJPGImage = UIImage(data: ImageData!)
UIImageWriteToSavedPhotosAlbum(compressedJPGImage!, nil, nil, nil)
let alertController = UIAlertController(title: "Complete", message: "Your image has been saved.", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default); alertController.addAction(okAction); self.present(alertController, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard (info[.originalImage] as? UIImage) != nil else {
fatalError ("Expected a dictionary containtaining an image, but was provided with the following: \(info)")
ImagePicked.image = image //PROBLEM
dismiss(animated: true, completion: nil)
}
}
func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
}
Update didFinishPickingMediaWithInfo as below,
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let image = info[.originalImage] as? UIImage else { return }
ImagePicked.image = image
picker.dismiss(animated: true, completion: nil)
}
As #rmaddy commented, you should rearrange the methods as below,
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var ImagePicked: UIImageView!
#IBAction func openCamera(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(.camera) { //Is the camera an available source type?
let imagePicker = UIImagePickerController() //Declare variable imagePicker
imagePicker.delegate = self
imagePicker.sourceType = .camera;
imagePicker.allowsEditing = false //Tell Image Pickr not to edit camptured photo
self.present(imagePicker, animated: true, completion: nil) //Show the photo to the user
}
}
func openLibrary(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) { //Check if device has access to photo library
let imagePicker = UIImagePickerController() //Set up variable imagePicker
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary; //Set the source type to library
imagePicker.allowsEditing = true //Allow editing, so the user can move and crop their photo
self.present(imagePicker, animated: true, completion: nil) //Show UIImagePickerController to the user
}
}
func saveImage(_ sender: Any) {
let ImageData = ImagePicked.image!.jpegData(compressionQuality: 0.6)
let compressedJPGImage = UIImage(data: ImageData!)
UIImageWriteToSavedPhotosAlbum(compressedJPGImage!, nil, nil, nil)
let alertController = UIAlertController(title: "Complete", message: "Your image has been saved.", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default); alertController.addAction(okAction); self.present(alertController, animated: true, completion: nil)
}
func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
I am trying to record video and then save it on an IOS device, I am able to record it but I am wondering how to save it on the device?
import UIKit
import AVKit
import MobileCoreServices
class ViewController: UIViewController , UIImagePickerControllerDelegate , UINavigationControllerDelegate {
#IBOutlet weak var RecordButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func RecordAction(_ sender: UIButton) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) {
print("Camera Available")
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.mediaTypes = [kUTTypeMovie as String]
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
} else {
print("Camera UnAvaialable")
}
}
}
First make sure to add below Privacies to info.plist :
Privacy - Photo Library Additions Usage Description
Privacy - Camera Usage Description
Privacy - Microphone Usage Description
and add below functions under ViewDidLoad
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any]) {
dismiss(animated: true, completion: nil)
guard
let mediaType = info[UIImagePickerControllerMediaType] as? String,
mediaType == (kUTTypeMovie as String),
let url = info[UIImagePickerControllerMediaURL] as? URL,
UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(url.path)
else {
return
}
// Handle a movie capture
UISaveVideoAtPathToSavedPhotosAlbum(
url.path,
self,
#selector(video(_:didFinishSavingWithError:contextInfo:)),
nil)
}
#objc func video(_ videoPath: String, didFinishSavingWithError error: Error?, contextInfo info: AnyObject) {
let title = (error == nil) ? "Success" : "Error"
let message = (error == nil) ? "Video was saved" : "Video failed to save"
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil))
present(alert, animated: true, completion: nil)
}
Would please review my code, I do not have any errors, but when I open my view controller, the camera doesn't start there is only a black screen, even the buttons do not appear.
import UIKit
import AVFoundation
class CameraViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
let picker = UIImagePickerController()
#IBOutlet weak var myImageView: UIImageView!
#IBOutlet weak var cameraView: UIView!
#IBAction func photoLibrary(_ sender: UIBarButtonItem) {
picker.allowsEditing = false
picker.sourceType = .photoLibrary
picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
picker.modalPresentationStyle = .popover
present(picker, animated: true, completion: nil)
picker.popoverPresentationController?.barButtonItem = sender
}
#IBAction func shootPhoto(_ sender: UIBarButtonItem) {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.camera
picker.cameraCaptureMode = .photo
picker.modalPresentationStyle = .fullScreen
present(picker,animated: true,completion: nil)
} else {
noCamera()
}
}
func noCamera(){
let alertVC = UIAlertController(
title: "No Camera",
message: "Sorry, this device has no camera",
preferredStyle: .alert)
let okAction = UIAlertAction(
title: "OK",
style:.default,
handler: nil)
alertVC.addAction(okAction)
present(
alertVC,
animated: true,
completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
picker.delegate = self
}
//MARK: - Delegates
private func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject])
{
var chosenImage = UIImage()
chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage //2
myImageView.contentMode = .scaleAspectFit //3
myImageView.image = chosenImage //4
dismiss(animated:true, completion: nil) //5
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
}
I only get completely black screen, even no hints from Swift. I do not know what to do now.
This happens when you have not set an initial viewcontroller. Please make sure the viewcontroller you want to load first is set as initial viewcontroller in your storyboard.