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).
Related
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?
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.
I'm really new to programming, I apologize in advance if this is a very simple question. I am trying to write a code to use UIImagePickerController to select two different images from my imageGallery and put it into two UIImageViews. Then, click a button to upload the images to Parse.
I'm having difficulty using UIImagePickerController twice and I can't seem to find an answer anywhere. Also, I'm having trouble linking it to the upload code. I've only learnt how to upload a file already in a folder, but I cant seem to work out how to link that to the UIImagePickerController. If you can help, it will be so much appreciated. My code so far...
- (IBAction)choosePhotoA:(id)sender {
UIImagePickerController *imagePickerControllerA = [[UIImagePickerController alloc] init];
imagePickerControllerA.modalPresentationStyle = UIModalPresentationCurrentContext;
imagePickerControllerA.delegate =self;
imagePickerControllerA.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imagePickerControllerA animated:NO completion:nil];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
UIImage *imageA = [info valueForKey:UIImagePickerControllerOriginalImage];
self.imageViewA.image = imageA;
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)uploadPhotoA:(id)sender {
PFObject *newImage = [PFObject objectWithClassName:#"photos"];
NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed:#"newImage.png"]);
PFFile *newImageFile = [PFFile fileWithName:#"testPhoto.png" data:imageData];
[newImage setObject:newImageFile forKey:#"photoUploadOne"];
[newImage saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error){
NSLog(#"upload success!");
}
}];
}
When the image is picked and didFinishPickingMediaWithInfo: is called, you need to know which image was being picked (1 or 2). To do this, save a flag when the button is pressed which calls choosePhotoA:. Then, in didFinishPickingMediaWithInfo: you can use that flag to decide where to put the image (imageViewA or imageViewB). This would allow the user to change their mind and replace an image they already chose.
You can also save the images to disk if you want to, or use #propertys to hold references to them (you don't really want to go and get the images back from the image views).
Now, when you want to upload, get the images (from the properties, image views or disk) and upload (basically this just changes your current use of UIImage imageNamed:). And you need to run the code twice to process each image.
Iphone app, IOS 5 and up.
There are similar questions to this one on SO but I haven't encountered this exact scenario so I'll ask. I'm editing an existing app that allows lets you take a photo which it resizes and sends to a web service.
I need to add the ability to take 3 photos, resize each and send to the same service. I thought it would be just a matter of repeating what was already in the app but it uses the UIImagePickerController which apparently only allows one photo per use.
So the way it works is that there's a 'Take Photo' button which calls the method below. Once that photo is taken another button appears that says 'Take another photo' (I added this button) and I have it calling the same method but it is just copying over the previous photo, which is to be expected really. How should I best alter this to accommodate 3 photos?
This is the takephoto method that I'm calling.
- (IBAction)takePhoto:(id)sender
{
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:NULL];
}
check this https://developer.apple.com/library/ios/samplecode/photopicker/Introduction/Intro.html
, check the take photo part of this demo project.
Eventually figured out how to do this. I added a tag to the button calling the method, through IB.
Then in the takephoto method I assigned the imagePickerController a tag based on the tag of the button that tapped. Like this:
- (IBAction)takePhoto:(id)sender
{
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
if([sender tag] == 2)
{
imagePickerController.view.tag = 2;
}
//And so on...
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:NULL];
}
Then in the ImagePickerController didFinishedPickingMediaWithInfo method:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
if(picker.view.tag == 2)
{
//Do stuff here
}
}
So, I'll probably have to create three different buttons for each of the three possible photos, I'm sure there's a better way than that but it should work.
I use standart image picker to make some camera photo.
When user makes photo image picker shows him the Preview screen with 2 buttons "Retake" and "Use".
How to detect that Preview screen is active now or "Retake" button pressed? Is it possible ? Are the useful properties or events? Something like when image source is library the is property - allows editing, which shows similar screen .
UIImagePickerController * imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
A bit after the fact, but maybe someone is still seeking this answer like I was. If you want continue using the native camera controls, you can check the subviews of the ImagePickerController to determine if the post-record view is showing.
BOOL videoTaken = NO;
for (UIView *aView in self.imagePickerController.view.subviews[0].subviews[0].subviews[0].subviews)
{
if ([aView isKindOfClass:NSClassFromString(#"PLTileContainerView")])
{
videoTaken = YES;
break;
}
}
The "PLTileContainerView" is the subview that contains the editing slider that lets you view your video frame by frame, so if it's present, that means your video has already recorded.
For use:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissModalViewControllerAnimated:NO];
NSString *type = [info objectForKey:#"UIImagePickerControllerMediaType"];
if ([type isEqualToString:#"public.movie"]) {
} else {
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
}
}
For Cancel you don't have a way of detecting it (other than subclassing UIImagePickerController, which may be prohibited, or other way that I'm not aware), but for sure the second cancel is detectable :
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissModalViewControllerAnimated:YES];
}