I am developing in Swift with iPhone camera.
I using the following code to check the camera:
if UIImagePickerController.isSourceTypeAvailable(.Camera) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = UIImagePickerControllerSourceType.Camera
picker.allowsEditing = true
self.presentViewController(picker, animated: true)
} else {
print("can't find camera")
}
}
And I use the following code to open the camera.
presentViewController(imagePicker, animated: true, completion: nil)
I have reference the following link and call takePicture() , but it seems did not working.
But I always need to manually take the picture by tapping the shutter button. Is programmatically taking the picture possible in Swift?
Thanks in advance.
1) Check if you have these delegates in your view controller class:
UIImagePickerControllerDelegate, UINavigationControllerDelegate
2) Check if your plist have the permissions with YES
Privacy - Photo Library Usage Description
Privacy - Camera Usage Description
If you want, I use this code (swift 3):
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .photoLibrary
imagePicker.delegate = self
self.present(imagePicker, animated: true, completion: nil)
For camera, just change "photoLibrary"
imagePicker.sourceType = .camera
3) In order to get the picture, you must implement the delegate didFinishPickingMediaWithInfo:
extension YourViewController:
UIImagePickerControllerDelegate,
UINavigationControllerDelegate
{
func imagePickerController(
_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any])
{
imagePicker.dismiss(animated: true, completion: nil)
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
print("picture taken: \(image)")
}
}
var imagePicker:UIImagePickerController = UIImagePickerController()
//Set delegate to imagePicker
imagePicker.delegate = self
//Allow user crop or not after take picture
imagePicker.allowsEditing = false
//set what you need to use "camera or photo library"
imagePicker.sourceType = .camera
//Switch flash camera
imagePicker.cameraFlashMode = .off
//Set camera Capture Mode photo or Video
imagePicker.cameraCaptureMode = .photo
//set camera front or rear
imagePicker.cameraDevice = .rear
//Present camera viewcontroller
self.present(imagePicker, animated: true, completion: nil)
and don't forget implement two protocol: UIImagePickerControllerDelegate,UINavigationControllerDelegate
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let imagePicked = info[UIImagePickerControllerOriginalImage] as? UIImage {
UIImageWriteToSavedPhotosAlbum(imagePicked, nil, nil, nil)
dismiss(animated: true, completion: nil)
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
Because you want to take picture fully automatically, you don't need UIImagePickerController at all. Instead use AVFoundation directly.
This article will be very helpful: Camera Capture on iOS.
Related
I am having an issue while displaying camera captured image in an image view where delegates are set and being called "didFinishPickingMediaWithInfo".
I have two buttons for the user interaction (camera picture & from gallery), once I take picture from camera and then select any other image from gallery; the camera picture taken earlier is shown for a second. I tried searching a lot but no luck so far.
Can anyone please advise what am I missing. Following is the code for reference.
#IBAction func cameraButtonPressed(_ sender: UIButton) {
self.openCamera()
}
#IBAction func galleryButtonPressed(_ sender: UIButton) {
self.openGallary()
}
override func viewDidLoad() {
super.viewDidLoad()
initialLayout()
}
override func viewWillAppear(_ animated: Bool) {
self.lblPreview.isHidden = true
self.imageTake.isHidden = true
self.uploadButtonOutlet.isHidden = true
}
//
//MARK: - Internal Methods
func initialLayout() {
self.cameraButtonOutlet.layer.cornerRadius = 20
self.galleryButtonOutlet.layer.cornerRadius = 20
self.uploadButtonOutlet.layer.cornerRadius = 20
}
//MARK: - Open the camera
func openCamera(){
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerController.SourceType.camera)){
imagePicker.sourceType = UIImagePickerController.SourceType.camera
//If you dont want to edit the photo then you can set allowsEditing to false
imagePicker.allowsEditing = true
imagePicker.delegate = self
imagePicker.cameraCaptureMode = .photo
imagePicker.cameraDevice = .rear
self.present(imagePicker, animated: true, completion: nil)
}
else{
let alert = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
//MARK: - Choose image from camera roll
func openGallary(){
imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
imagePicker.allowsEditing = true
imagePicker.delegate = self
self.present(imagePicker, animated: true, completion: nil)
}
extension UploadTimesheetViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let editedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage{
self.lblPreview.isHidden = false
self.imageTake.isHidden = false
self.uploadButtonOutlet.isHidden = false
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
self.imageTake.image = editedImage
self.imageTake.setNeedsLayout()
})
// self.imageTake.image = editedImage
}
//Dismiss the UIImagePicker after selection
picker.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.isNavigationBarHidden = false
self.dismiss(animated: true, completion: nil)
}
}
Update your delegate method like this,
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
var finalImage:UIImage?
if let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
finalImage = image
}else {
finalImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
}
self.lblPreview.isHidden = false
self.imageTake.isHidden = false
self.uploadButtonOutlet.isHidden = false
self.imageTake.image = finalImage
//Dismiss the UIImagePicker after selection
picker.dismiss(animated: true, completion: nil)
}
Sorry for the delayed response. Just updating the answer so if anyone is having the same issue should know what was the actual problem.
Once picker is dismissed a viewwillappear will be called where I have hid the image view and hence the reason it was not displaying it for the first time.
If I remove the code from viewwillappear and add that properties code to viewedload then all works fine.
The issue was once the picker is dismissed , viewillapear was called and that was creating the issue.
Within my app I can take a picture
I have a button to access the camera (with all the permission and all)
it works, I can take a picture or close it if i wanted to
but after doing either of the activity
the camera button wont open the camera again
I have to exit the view controller and go back again for it to work
#IBAction func cameraButton(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(.camera) && !pickedImage {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = .camera
self.present(imagePickerController, animated: true, completion: nil)
pickedImage = true
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
imageView.image = image
self.dismiss(animated: true, completion: nil)
}
After taking a picture there is a UIImageView for it to display taken picture.
I need to two things
1. In the camera access i can also select pictures from the gallery and make it display on the UIImageView
2. To have the camera button reopen the camera after using it
To select pictures from gallery, you will have to set sourceType as .photoLibrary .
I think your pickedImage variable is never set to false, hence the second time, it doesn't get inside that if condition.
I'm presenting an UIImagePickerController to take a photo, the problem is if I take a photo, or cancel the UIImagePickerController I'll return on a white screen and not on my previous ViewController. Only my navigation bar still here. If I click to an other view (with the navigation bar) it's ok, and if I return on the tab where the UIImagePickerController is called it still white.
let picker = UIImagePickerController();
picker.delegate = self;
picker.mediaTypes = [swiftString];
picker.allowsEditing = true
picker.sourceType = UIImagePickerControllerSourceType.camera;
picker.cameraCaptureMode = .photo
self.present(picker, animated:true, completion:nil);
dismiss :
picker.dismiss(animated: true, completion:nil);
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion:nil);
}
If someone have an idea thank's !
Update :
White screen appears always when i call a view with present method. So i think it's conflict with the navigation controller (hierarchy...)
This solve my problem :
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
appDelegate.navigationController.present(picker, animated: true, completion: nil)
If someone have an other alternative to solve it !
Use picker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext before presenting the imagepicker.
Here's the code I use for the camera:
func openCameraApp() {
if UIImagePickerController.availableCaptureModes(for: .rear) != nil {
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)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage // do you have this line in your code?
image = chosenImage
self.performSegue(withIdentifier: "ShowEditView", sender: self)
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: false, completion: nil)
}
I notice a couple of things different.
You set .allowsEditing to true. I don't believe that is making a difference.
I'm checking for a camera, but you probably didn't put that code in your question.
I'm setting .modalPresentationStyle to full screen. This could be your issue.
I don't see the imagePickerController(picker: didFinishPickingMediaWithInfo) call. But since it shouldn't build, that definitely isn't the issue.
Inside that call I unwrap the image from info. I believe this is your issue. I've placed a comment on that specific line, asking you to check for this.
Finally, I'm executing a segue to another view controller. (My app is basically a "select" then "edit".)
Set the .modalPresentationStyle to fullScreen
I am using UIImagePickerController to pick images from both Camera and Library. When i get the image from the library the picture is OK. However, when i get the picture from the camera its rotating 90 degrees to the right. My app works just in portrait mode. Here is the code where i get the image
#IBAction func camPhoto(sender: AnyObject) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
imagePicker.allowsEditing = false
self.presentViewController(imagePicker, animated: true, completion: nil)
}
#IBAction func importPhoto(sender: AnyObject) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
imagePicker.allowsEditing = false
self.presentViewController(imagePicker, animated: true, completion: nil)
}
my Function importPhoto works fine but the other one doesn't.
func imagePickerController(picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let selectedPhoto = info[UIImagePickerControllerOriginalImage] as! UIImage
img.image = selectedPhoto
dismissViewControllerAnimated(true, completion: {
self.convBtn.hidden = false
})
}
Any ideas?
You can try like :
func imagePickerController(picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let selectedPhoto = info[UIImagePickerControllerOriginalImage] as! UIImage
**selectedPhoto.withHorizontallyFlippedOrientation()**
img.image = selectedPhoto
dismissViewControllerAnimated(true, completion: {
self.convBtn.hidden = false
})
}
So far I have the camera working fine, it opens up in the regular format. But I want the only option to be square format.
Here is my code so far.
#IBAction func takePhoto(sender: AnyObject) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .Camera
presentViewController(picker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
imageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
dismissViewControllerAnimated(true, completion: nil)
}
I don't think you can open camera in square format using UIImagePickerController. What you can do is set UIImagePickerController allowEditing to YES and from the result dict use the key UIImagePickerControllerEditedImage then you will have the squared image so you code becomes .
#IBAction func takePhoto(sender: AnyObject) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .Camera
picker.allowsEditing = true
presentViewController(picker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
imageView.image = info[UIImagePickerControllerEditedImage] as? UIImage
dismissViewControllerAnimated(true, completion: nil)
}
Another way around is mentioned in this answer .
You can use the logic from answer to write the code in swift.
But if you want to look in details and try out doing some more have a look into
AVFoundation,
AVCaptureConnection,
AVCaptureDevice
AVCaptureDeviceInput
AVCaptureSession
AVCaptureStillImageOutput
AVCaptureVideoDataOutput
AVCaptureVideoPreviewLayer
CoreImage
Also look at apple sample.