Get file path of saved image to camera roll iOS (Obj-c) - ios

I used UIImageWriteToSavedPhotosAlbum to save image to Camera Roll, but I want to get a reference to get back to the same image. Is it possible? I have a link (albeit in Japanese) that says it's possible to get the file path, but as of what I understand this is during selection (using imagePicker) and not before/after taking a picture. What I want is to get the reference of the image, save it in CoreData, and the use it later to fetch the image.
Edit: It seems as if there is an answer already but in the comments it says that ALAssetsLibrary is already deprecated and we should use PHPhotoLibrary instead.

You Can Get All the Photos, Videos and Other Data With Using PHAsset Library. Here is Code to get All Videos in Array .
//For Video
allPhotosResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeVideo options:nil];
For Image you Can use this
//For Images
allPhotosResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];
and You can Display it Using PHAsset in UiTableview or Any Other Control.
Here is the URL of Demo ,
AVPlayer Demo (Fetch Video With PHAsset Library)

just pass the file name and extension to fetch the image
+(UIImage *)loadImage:(NSString *)fileName ofType:(NSString *)extension {
NSString * documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"%#/%#.%#", documentsDirectoryPath, fileName, extension]];
return result; }

Related

How can I retrieve the metadata of PHAsset?

I am getting the user selected image in PHAsset format. and I want to get the image path.
My goal is to upload the image to Firebase and based their docs, I need to have the image path.
I found from researching that I need to get the metadata of the image first and store it in local file and then I can retrieve the URL. Is it correct?
My question here is (If the above correct), how can I get the metadata of PHAsset image format?
If you want to retrive the image file Path from your PHAsset address then use this function:
[asset requestContentEditingInputWithOptions:[PHContentEditingInputRequestOptions new] completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
NSURL *imageURL = contentEditingInput.fullSizeImageURL;
}];
asset=PHAsset *asset

Show Photos in custom album but not in Camera Role/My Photo Stream

I am working on PHPhotoLibrary, where I create an album and save image to it. But, the image being saved to the album also appears in the Camera Roll as well as My Photo Stream.
I searched a lot, nothing substantial found.
I wrote a function as below, to remove the photos from camera role and my photo stream.
-(void)cleanUpCameraRoll:(NSString *)localID
{
PHFetchResult *newlyCreatedAssetFetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:#[localID] options:nil];
PHAsset *newlyCreatedAsset = [newlyCreatedAssetFetchResult firstObject];
//Get Camera Roll
PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum
subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary
options:nil];
PHAssetCollection *cameraRollCollection = result.firstObject;
//Get Photo Stream Album - PHAssetCollectionSubtypeAlbumMyPhotoStream
PHFetchResult *result2 = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum
subtype:PHAssetCollectionSubtypeAlbumMyPhotoStream
options:nil];
PHAssetCollection *photoStreamCollection = result2.firstObject;
//*********************************
PHFetchResult *assetsCameraRoll = [PHAsset fetchAssetsInAssetCollection:cameraRollCollection options:nil];
for (PHAsset *asset in assetsCameraRoll) {
if ([asset.localIdentifier isEqualToString:localID]) {
DebugLog(#"Got newly created asset in camera roll");
break;
}
}
PHFetchResult *assetsPhotoStream = [PHAsset fetchAssetsInAssetCollection:photoStreamCollection options:nil];
for (PHAsset *asset in assetsPhotoStream) {
if ([asset.localIdentifier isEqualToString:localID]) {
DebugLog(#"Got newly created asset in photo stream");
break;
}
}
//*********************************
NSError *error;
[[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
//Remove from Camera Roll
PHAssetCollectionChangeRequest *changeRequest1 = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:cameraRollCollection assets:newlyCreatedAssetFetchResult];
[changeRequest1 removeAssets:#[newlyCreatedAsset]];
PHAssetCollectionChangeRequest *changeRequest2 = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:photoStreamCollection assets:newlyCreatedAssetFetchResult];
[changeRequest2 removeAssets:#[newlyCreatedAsset]];
} error:&error];
}
This code executes well, but still i see the images at both the places.
So, I am coming to a conclusion, that Albums are just logical groupings of the photos, and everything lies within Camera Role and/or My Photo Stream. Is that so?
If yes, is there any way to (at least) make it hidden in the camera roll/Photo stream? I want to make photos visible only in my custom album.
Well, this is not an answer but a confirmation of your conclusion. I started writing this as a comment but the formatting is bad, so adding the answe here. Please don't mind.
There's only one way to add to the Photos gallery. All the asset creation requests save the photo in the camera roll. When you add it to an album, only the URL of the asset is added to a list (grouped under one album). The custom ablum picks all the required images from the camera roll.
You can also notice this in other ways:
-> If you delete a photo in the album, the photo remains in the camera roll but if you delete it from camera roll, then it is removed from all custom albums.
-> If you notice how an asset is added to an album, you will notice that it is basically retriving the asset from the camera roll. There are no APIs to direct add it to album
It is possible, after a fashion, but you'll need to expand the definition of "custom album". As previously noted, any picture added to a photo album via PhotoLibrary callls also gets added to the camera roll.
You can, however, create a directory in your app's document directory for photos, and save photos there. They will not be saved to the device camera roll. The album will also not show up in the photo app. The "custom album" in this instance is just the directory on disk and you would manipulate it (and it's contents) via NSFileManager.

iOS, how to keep Photo Sphere XMP Metadata while saving it to Camera Roll?

I am able to add the Photo Sphere XMP Metadata to an equirectangular photo.
I uploaded the photo with the XMP metadata to Google Photos, and the Google Photos is able to be recognized as a sphere photo.
Then, I tried to save the photo with the XMP metadata to camera roll.
I shared the photo to Google Photos from camera roll, but Google Photos does not know it's a sphere photo.
I tried to download the photo and analyze it, and found the XMP metadata are all gone.
It seems iOS will edit the metadata while the photo is saving to camera roll.
Is there any way to preserve the photo's XMP metadata while saving it to camera roll?
// raw jpg data to NSData
NSString *img = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"equirectangular_orig.jpg"];
NSData* imgData = [[NSFileManager defaultManager] contentsAtPath:img];
NSMutableData *newImgData = [NSMutableData dataWithData:imgData];
// writing XMP metadata to newImgData
// ...
// ...
// saving the newImgData to new jpg file
NSString *path = [[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] stringByAppendingPathComponent:#"equirectangular_xmp.jpg"];
NSURL *url = [NSURL fileURLWithPath:path];
[[NSFileManager defaultManager] removeItemAtPath:[url absoluteString] error:nil];
[newImgData writeToURL:url atomically:YES];
// saving the new jpg file to camera roll
UIImage *newImg = [UIImage imageWithData:newImgData];
UIImageWriteToSavedPhotosAlbum(newImg, self, nil, nil);
Key point: using
[PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL: url]
instead of
[PHAssetChangeRequest creationRequestForAssetFromImage:image]
since UIImage will break the original file, just use a temp url to save your original image raw data, and using creationRequestForAssetFromImageAtFileURL api.

Video thumbnail image from directory

I am a newbie in iOS.I want to show a video thumbnail in image view such that by clicking a Button it should open a gallery and by selecting a video it should display the video thumbnail...... please help me...
There are videos and images that stored on photo library, firstly you want to get all videos from the library, prior to iOS 8, this post shows you how to fetch pictures using AssetsLibrary library. You can filter videos out when doing it, then you get an ALAsset, which can represent a image or video, suppose when you select a video, you get a ALAsset named asset, using the below function will get you a thumbnail image for that video.
If you use ALAsset.
UIImage *thumbnail = [UIImage imageWithCGImage:[asset thumbnail]];
For iOS 8, apple introduces a new Photos library,you can fetch all videos from the library as above, a video or images is represented by PHAsset, suppose you have a PHAsset ivar named asset, you can use the following method to get a UIImage from this asset. Take a look at requestImageForAsset:targetSize:contentMode:options:resultHandler:, you can set the target size to the size of the thumb image you want,in the resultHandler,you get the UIImage.
I am using below code to get thumbnail of video which is downloaded in document directory,
- (UIImage *)thumbnailFromVideoAtURL:(NSURL *)url
{
AVURLAsset *aImgAsset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetImageGenerator *aImgGenerator = [[AVAssetImageGenerator alloc] aImgAsset];
aImgGenerator.appliesPreferredTrackTransform = YES;
NSError *err = NULL;
CMTime time = CMTimeMake(1, 2);
CGImageRef aImgRef = [aImgGenerator copyCGImageAtTime:time actualTime:NULL error:&err];
UIImage *aImgThumb = [[UIImage alloc] initWithCGImage:aImgRef];
return aImgThumb;
}

How can I keep track of media created/chosen by UIImagePickerController?

I'm building an iOS app that allows the user to upload videos from UIImagePickerController, either by recording or choosing them from the Camera Roll, as well as also play the chosen video. My question is, how would I go about keeping a reference to the videos that have been chosen this way? I want to do this so that if the video is still present on the device, I can use the local file rather than streaming the uploaded file.
When
imagePickerController:didFinishPickingMediaWithInfo:
returns, the URL in:
[info objectForKey:UIImagePickerControllerMediaURL];
Is in the format of: "file://localhost/private/var/mobile/Applications/ /tmp//trim.z2vLjx.MOV"
I'm lead to believe that the "/tmp/" directory is temporary, and therefore not suitable to save the URL for that location.
I can get all of the videos on the device through ALAssetsLibrary, but because I don't have a way of distinguishing them, this doesn't help me. I've been attempting to use:
[result valueForProperty:ALAssetPropertyDate];
To distinguish the videos, but I need a way of getting the creation date from UIImagePickerController for this to be useful.
I've finally managed to find a solution:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if(CFStringCompare((CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo)
{
//Dismiss the media picker view
[picker dismissModalViewControllerAnimated:YES];
//Get the URL of the chosen content, then get the data from that URL
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSData *webData = [NSData dataWithContentsOfURL:videoURL];
//Gets the path for the URL, to allow it to be saved to the camera roll
NSString *moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (moviePath))
{
ALAssetsLibrary *lib = [[ALAssetsLibrary alloc] init];
//The key UIImagePickerControllerReferenceURL allows you to get an ALAsset, which then allows you to get metadata (such as the date the media was created)
[lib assetForURL:[info objectForKey:UIImagePickerControllerReferenceURL] resultBlock:^(ALAsset *asset) {
NSLog(#"created: %#", [asset valueForProperty:ALAssetPropertyDate]);
} failureBlock:^(NSError *error) {
NSLog(#"error: %#", error);
}];
}
}
As per usual, the solution was found by reading the documentation a little more thoroughly. Hopefully this'll help someone else out at some point.
You can easily keep a record of the videos you have on the device. Either by keeping a data base (which I think would be too much) or just a file with a list of your videos. In that list, you could have the URL of the assets.

Resources