I have an app that launches the camera:
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = NO;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
And I implement the delegate to get the image taken by the camera:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
...
}
Inside that delegate I would like to save the image with the GPS exif data if possible.
The info object after taking the picture has the following keys:
UIImagePickerControllerMediaType
UIImagePickerControllerOriginalImage
UIImagePickerControllerMediaMetadata
The metadata key seems promising, but it seems the GPS exif data is either not included or stripped.
{
DPIHeight = 72;
DPIWidth = 72;
Orientation = 6;
"{Exif}" = {
...
};
"{MakerApple}" = {
...
};
"{TIFF}" = {
...
};
};
I have searched through a ton of content talking about grabbing the url for the image and extracting the exif data, however I belive that this is only possible if the photo is picked from the gallery, not taken from the camera.
I also have CoreLocation turned on to 'Always', however that does not seem to make a difference.
If I take a photo from the photo app I know that the GPS exif data is included. I can even add that photo from gallery into my app and it has the exif data. However if I launch the camera from my app, seems I cannot get the GPS exif data.
Is this possible in iOS 11?
Related
I know its not a good question to be ask but i am stuck. How can i detect when user pick image from library not from camera and this library image saved via front camera or back camera? Like
if (library image from front camera)
{
// Do something here
}
else {
// Do something here
}
Your code checks for available cameras on the device. What you need to do is read the metadata for the image after you have taken the picture, that will include info on the camera.
Use this solution to read the Exif data that comes with the image to find out which camera obtained it: Exif Data from Image
You can check the image EXIF data in the info dictionary UIImagePicker passes in it's callback.
- (IBAction) handleTakePhoto:(UIButton *)sender {
UIImagePickerController* picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:nil];
}
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
__block NSDictionary* metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"%#", [metadata valueForKeyPath:#"{Exif}.LensModel"]);
[picker dismissViewControllerAnimated:YES completion:nil];
});
}
The above snippet outputs
iPhone 6 Plus back camera 4.15mm f/2.2
You would have to parse out the "front" or "back" parts of the string.
Relying on parsing something that is parsed out of a string raises some red flags -- there is probably a better and more stable way of doing it.
After testing my app on an iPhone 6S+, I noticed the videos it produced were only 1080p, despite the fact that it should be capable of recording in 4K. My UIImagePickerController is set up like so:
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.mediaTypes = #[(NSString *)kUTTypeMovie];
imagePickerController.videoMaximumDuration = 3600.f;
imagePickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
[self presentViewController:imagePickerController animated:YES completion:nil];
I thought that perhaps there would be a new UIImagePickerControllerQualityType key for selecting 'very high' quality, but 'high' still seems to be the best quality available. Is there a way to enable 4K recording using UIImagePickerController, or do I have to roll my own solution using AVFoundation?
In some iOS version this was solved and now, doing
picker.videoQuality = .typeHigh
my iPhone is taking 4k videos.
Hi is it possible to capture an Image with out saving to ios device .This is a question that is worrying me.
Can any please give me an idea how to achieve it.
Yes it is possible:
- (void)takePhoto
{
UIImagePickerController * pc = [[UIImagePickerController alloc] init];
pc.sourceType = UIImagePickerControllerSourceTypeCamera;
pc.delegate = self;
pc.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
pc.allowsEditing = YES;
[self presentViewController:pc animated:YES completion:^{
}];
}
#pragma mark - UIImagePickerController Delegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:^{
UIImage * image = [info valueForKey:#"UIImagePickerControllerOriginalImage"];
self.imageView.image = image;
}];
}
Edit:
If you want to save the image you can simply save it to the Caches directory (see the apple docs for NSFileManager for info on how to do this, or other stack overflow questions. This is preferred to NSUserDefaults although that would work too.
If you want to simply send it (via email, share, or API upload) you dont have to save it first. You can use the in-memory version that resides in the self.imageView.image property above.
I'm working on an app that gives the user the option to take a photo for their profile picture, but can't seem to figure out how to:
Get the photo to save to the users library
Get that photo to replace a default photo when they press "use" (that is there when the user first loads the app)
Any suggestions? This code might be completely off but here is what I was starting to use:
- (void)takePhoto {
UIImagePickerController *takePhotoPicker = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) {
takePhotoPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
takePhotoPicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
} else {
takePhotoPicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
}
[self presentViewController:takePhotoPicker animated:YES completion:nil];
}
What you need to do is register your viewController as a UIImagePickerControllerDelegate, and then do:
takePhotoPicker.delegate = self;
Then, you need to add the method:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {}
which you can use to get the image.
To get the image from the camera or photo album you need to get the value from the correct key from the info dictionary.
For example, to get the Edited image (resized by user):
UIImage *image = [info valueForKey:UIImagePickerControllerEditedImage];
And to get the original image:
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
The original image is the full screen image that the user took with the camera.
You can then use this image to set an image view or upload to the server, etc.
Also, you shouldn't set the source type based on whether or not the camera is available, but you should let the user select (in case they want to choose from the photo album even if they have a camera).
I am trying to implement a feature of taking X amount of pictures programmatically after entering a UIViewController for both the iPhone and iPad. I looked into UIImagePickerController but I do not want to present the camera controls and have the user hit a button to capture only one photo. Is there a way to capture X amount of photos once entering a UIViewController and storing all the photos in the end for future reference in one go?
Edit:
-(void)viewDidAppear:(BOOL)animated
{
// Create image picker controller
picker = [[UIImagePickerController alloc] init];
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
[picker setSourceType:UIImagePickerControllerSourceTypeCamera];
}
else
{
[picker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
}
// Set source to the camera
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
// Delegate is self
picker.delegate = self;
// Allow editing of image ?
picker.allowsEditing = NO;
//picker.showsCameraControls = NO;
// Show image picker
[picker animated:YES completion:nil];
}
straight away with takePicture you can not take multiple snaps, for that you have to use some video recording and get snap out of it for particular frame or time, for you more reference you can use this apple documentation for bulk snaps AVFoundation Programming Guide
You can try something like this:
int numberOfPhotos = 3; // Number of photos you want to take.
for ( int i = 0; i < numberOhPhotos; i++ )
{
// Note that you should use some sort of a pause in between each photo.
[picker takePicture];
}