I am trying to get picture taken date while choosing picture from Photo Library in iPhone. I am using below code to do the same.
NSDictionary* fileAttribs = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
NSDate *result = [fileAttribs fileCreationDate]; //or fileModificationDate
But it is showing current date and time.
Is there any way to get picture taken date while choosing picture from Photo library.
You can do it checking the metadata of the picture with ALAsset
Look for the key ALAssetPropertyDate
EDIT, complete code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *url = [info objectForKey:#"UIImagePickerControllerReferenceURL"];
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:url
resultBlock:^(ALAsset *asset) {
NSDate *myDate = [asset valueForProperty:ALAssetPropertyDate];
NSLog(#"Date: %#", myDate);
} failureBlock:^(NSError *error) {
NSLog(#"Error");
}];
[picker dismissViewControllerAnimated:YES completion:nil];
}
ALAssetsLibrary is deprecated, so with PHAsset:
#import <Photos/PHAsset.h>
Then:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
PHAsset *phAsset = [[PHAsset fetchAssetsWithALAssetURLs:#[imageURL] options:nil] lastObject];
NSDate *date = [phAsset creationDate];
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
}
Related
How can I save an image (like using UIImageWriteToSavedPhotosAlbum() method) with a filename of my choice to the private/var folder?
Kenny, you had the answer! For illustration I always think code is more helpful.
//I do this in the didFinishPickingImage:(UIImage *)img method
NSData* imageData = UIImageJPEGRepresentation(img, 1.0);
//save to the default 100Apple(Camera Roll) folder.
[imageData writeToFile:#"/private/var/mobile/Media/DCIM/100APPLE/customImageFilename.jpg" atomically:NO];
UIImageWriteToSavedPhotosAlbum() is only used for saving to the photos camera roll. To save to a custom folder, you need to convert the UIImage into NSData with UIImageJPEGRepresentation() or UIImagePNGRepresentation(), then save this NSData to anywhere you like.
You can use below code, without use of ALAssetsLibrary...
NSString *fileName;
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:^{
if( [picker sourceType] == UIImagePickerControllerSourceTypeCamera )
{
UIImageWriteToSavedPhotosAlbum(image,nil, nil, nil);
[self performSelector:#selector(GetImageName) withObject:nil afterDelay:0.5];
}
else
{
NSURL *refURL = [info valueForKey:UIImagePickerControllerReferenceURL];
PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:#[refURL] options:nil];
fileName = [[result firstObject] filename];
}
}];
-(void)GetImageName
{
NSString *str =#"";
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
if (fetchResult != nil && fetchResult.count > 0) {
str = [[fetchResult lastObject] filename];
}
fileName = str;
}
I've implemented the delegate method and can get access to the picked UIImage, like this:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *pickedImage = [info valueForKey:UIImagePickerControllerOriginalImage];
I want to save it to a directory, but I need a file name. So rather than just picking a random file name it would make sense to pick the same file name as the image.
Is there a way to retrieve it from that info dictionary?
You could use the UIImagePickerControllerReferenceURL value of the info dictionary instead of the UIImagePickerControllerOriginalImage. This should give you the URL to the original media item.
This would return you a NSURL object which you then can use to build your new filename from.
Use ALA Assets library framework
Use the code below
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)image.imageOrientation completionBlock:^(NSURL *assetURL, NSError *error )
{
[library assetForURL:assetURL resultBlock:^(ALAsset *asset )
{
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *imageAsset)
{
ALAssetRepresentation *imageRep = [imageAsset defaultRepresentation];
NSLog(#"reference image filename picking from camera: %#", [imageRep filename]);
};
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:assetURL resultBlock:resultblock failureBlock:nil];
}
failureBlock:^(NSError *error )
{
NSLog(#"Error loading asset");
}];
}];
imageView.image = [info objectForKey:UIImagePickerControllerEditedImage];
imageView.contentMode = UIViewContentModeScaleAspectFit;
I am trying to save a recorded video to the library using the UIImagePickerController delegate. It works fine for pictures but it doesn't save if it's a video, plus after trying to save a video if I open the Photos app, I get a message "Please wait. Updatring library", and a progress bar with the label "Rebuilding library". My photo library is restored but the video was not added to it.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:#"public.image"]){
UIImage *picture = [info objectForKey:UIImagePickerControllerOriginalImage];
UIImageWriteToSavedPhotosAlbum(picture, nil, nil, nil);
}
else if ([mediaType isEqualToString:#"public.movie"]){
NSString* m_objMediaURL= [info objectForKey:UIImagePickerControllerMediaURL];
NSLog(#"URL is %#", m_objMediaURL);
UISaveVideoAtPathToSavedPhotosAlbum(m_objMediaURL, nil, nil, nil);
}
[self dismissModalViewControllerAnimated:YES];
}
The NSLog above outputs the following:
URL is
file://localhost/private/var/mobile/Applications/3800A5FB-2A96-4A7A-85DF-B635E8D9A66C/tmp/capture-T0x1061f0.tmp.JMdxHq/capturedvideo.MOV
Has anyone implemented such method and can point me to the right direction please?
Thank you.
I think I see an issue.
NSString* m_objMediaURL= [info objectForKey:UIImagePickerControllerMediaURL];
Is the wrong type. My properly working code uses:
NSURL *url = [[[info objectForKey:UIImagePickerControllerMediaURL] copy] autorelease];
I copy it instead of retaining it because of some issues I have had in low memory situations after the picker view is dismissed. Although the save method you use might work, I use the newer and better (because of the callback block):
ALAssetsLibrary* library = [[[ALAssetsLibrary alloc] init] autorelease];
[library writeVideoAtPathToSavedPhotosAlbum:url
completionBlock:^(NSURL *assetURL, NSError *error){/*notify of completion*/}];
Also, you should be using kUTTypeMovie and kUTTypeImage instead of hard coding #"public.image.
I found the problem thanks to Peter's help. Turns out that [info objectForKey:UIImagePickerControllerMediaURL] returns a NSURL and not a NSString. So in the end here's how my method looks like
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSURL *videoURL= [info objectForKey:UIImagePickerControllerMediaURL];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:videoURL])
{
[library writeVideoAtPathToSavedPhotosAlbum:videoURL
completionBlock:^(NSURL *assetURL, NSError *error){}
];
}
[library release];
This method uses the new ALAssetsLibrary framework. The whole method, which supports saving a picture or movie, follows:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:#"public.image"]){
UIImage *picture= [info objectForKey:UIImagePickerControllerOriginalImage];
NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
[library writeImageToSavedPhotosAlbum:[picture CGImage] metadata:metadata
completionBlock:^(NSURL *assetURL, NSError *error){}
];
}
else if ([mediaType isEqualToString:#"public.movie"]){
NSURL *videoURL= [info objectForKey:UIImagePickerControllerMediaURL];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:videoURL])
{
[library writeVideoAtPathToSavedPhotosAlbum:videoURL
completionBlock:^(NSURL *assetURL, NSError *error){}
];
}
}
[library release];
[self dismissModalViewControllerAnimated:YES];
}
Why are you passing nil, nil, nil into the method - if you pass in more options, it will tell you the error ;)
Try something like this instead :
UISaveVideoAtPathToSavedPhotosAlbum(m_objMediaURL, self, #selector(video:didFinishSavingWithError:contextInfo:), nil);
and later on in your class put this method
- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
// Let's see what happened
NSLog(#"path : %#", path);
NSLog(#:error : %#", error);
}
Hope the output of that helps you :)
EDIT :
Reading the docs a bit more, have you run this method to check that it's a valid video?
BOOL isVideoOK = UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(m_objMediaURL);
if (NO == isVideoOK)
NSLog(#"Video at %# is not compatible", m_objMediaURL);
Is there anyway to display a image in a UIWebview from the iphone photo storage
May be this is the suitable code in the upload image,
- (BOOL)webView:(UIWebView*)webViewRef shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
//we are listening out for links being click
if (navigationType == UIWebViewNavigationTypeLinkClicked)
{
NSURL *URL = [request URL]; //Get the URL
if ( [[URL scheme] isEqualToString:#"objc"] ) {
webView = webViewRef;
SEL method = NSSelectorFromString( [URL host] );
if ([self respondsToSelector:method])
{
[self performSelector:method withObject:nil afterDelay:0.1f];
}
return NO;
}
}
return YES;
}
-(void)takePicture
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.delegate = self;
id delegate = [[UIApplication sharedApplication] delegate];
[[delegate viewController] presentModalViewController:imagePicker animated:YES];
[imagePicker release];
}
#pragma mark - Image Picker
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSData *flatImage = UIImageJPEGRepresentation(image, 0.1f);
NSString *image64 = [flatImage base64EncodedString];
NSString *js = [NSString stringWithFormat: #"processImage('data:image/jpeg;base64,%#')", image64];
[webView stringByEvaluatingJavaScriptFromString:js];
[picker dismissModalViewControllerAnimated:YES];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissModalViewControllerAnimated:YES];
}
in your image picker delegate, save the file locally, basic code snippet, not complete
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *path = [[NSBundle mainBundle] bundlePath];
NSData *data = UIImageJPEGRepresentation( [info objectForKey:#"UIImagePickerControllerOriginalImage"] , 1.0);
NSString *fullPath = [path stringByAppendingPathComponent:#"image_tmp.jpg"];
if ([[NSFileManager defaultManager] createFileAtPath:fullPath contents:data attributes:nil] ) {
NSLog([NSString stringWithFormat:#"file successfully written to path %#",fullPath],nil);
}
}
the in your webview, set the base path of the HTML page you are going to load to the same path used for saving the image file.
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString baseURL:baseURL];
If you just wanted to display the image, the code below works just fine (using the UIImagePickerDelegate)
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
[_youWebView loadData:UIImagePNGRepresentation([info objectForKey:UIImagePickerControllerEditedImage]) MIMEType:#"image/jpeg" textEncodingName:#"utf-8" baseURL:nil];
}
hope this helps.
Yes, you first must use the UIImagePickerController. It will cause a new window from the iPhone to appear and the user will be requested to pick a photo.
When they pick the photo, you can get access to this photo, you can either dismiss the picker or the user can continue picking photos.
You are not allowed direct access to users photos and wont be able to access their photos with asking the user first. This makes total sense, as a user I would not want developers sneaking into my photo library and uploading my photos in the background.
To add these to a UIWebView, you will nee to set the [UIWebView basePath] to your (document directory where you saved the photo from the above process), I have got this working, search stackoverflow for UIWebView Basepath, or check documentation.
Cheers, John.
How can I save an image (like using UIImageWriteToSavedPhotosAlbum() method) with a filename of my choice to the private/var folder?
Kenny, you had the answer! For illustration I always think code is more helpful.
//I do this in the didFinishPickingImage:(UIImage *)img method
NSData* imageData = UIImageJPEGRepresentation(img, 1.0);
//save to the default 100Apple(Camera Roll) folder.
[imageData writeToFile:#"/private/var/mobile/Media/DCIM/100APPLE/customImageFilename.jpg" atomically:NO];
UIImageWriteToSavedPhotosAlbum() is only used for saving to the photos camera roll. To save to a custom folder, you need to convert the UIImage into NSData with UIImageJPEGRepresentation() or UIImagePNGRepresentation(), then save this NSData to anywhere you like.
You can use below code, without use of ALAssetsLibrary...
NSString *fileName;
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:^{
if( [picker sourceType] == UIImagePickerControllerSourceTypeCamera )
{
UIImageWriteToSavedPhotosAlbum(image,nil, nil, nil);
[self performSelector:#selector(GetImageName) withObject:nil afterDelay:0.5];
}
else
{
NSURL *refURL = [info valueForKey:UIImagePickerControllerReferenceURL];
PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:#[refURL] options:nil];
fileName = [[result firstObject] filename];
}
}];
-(void)GetImageName
{
NSString *str =#"";
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
if (fetchResult != nil && fetchResult.count > 0) {
str = [[fetchResult lastObject] filename];
}
fileName = str;
}