How can I retrieve the metadata of PHAsset? - ios

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

Related

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

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; }

Swift PHAsset from NSURL

I am working on PHAsset and NSURL on Swift.
I have an image url, for example file:///var/mobile/Media/DCIM/100APPLE/IMG_0043.JPG.
How can i make a PHAsset from this NSURL in Swift?
A PHAsset object represents an image or video file that appears in the Photos app, including iCloud Photos content. To display or edit assets, use the PHAsset class to fetch asset objects for the photos or videos you want to work with. An asset object is immutable and contains only the metadata for the photo or video it represents.
Thus you can not make PHAsset object.
Here is only one constructor for making object.
let asset = PHAsset()
There is no constructor for NSURL :-
This is what we frequently use:-
let imgData = NSData(contentsOfURL: (NSURL(string: "file:///var/mobile/Media/DCIM/100APPLE/IMG_0043.JPG"))!)
let image = UIImage(data: imgData!)

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.

Upload Photo to server including location information (Lat/Long)

Why is it so hard to upload a photo with Location data in its exif to the server? I am breaking my head not being able to solve this. Whenever I am sending the photo to the server all of its location information is being stripped off from the photo.
I have tried getting UIImage from the UIImagePickerController using both
NSURL *url = [info objectForKey:UIImagePickerControllerReferenceURL];
and also UIImagePickerControllerOriginalImage.
Kindly someone help me
To preserve the exif info, you need to use the raw data, not just the UIImage. You can get it from the ALAsset's defaultRepresentation, something like this:
ALAssetRepresentation* representation = [myAsset defaultRepresentation];
int size = representation.size;
NSMutableData* data = [[NSMutableData alloc]initWithCapacity:size];
void* buffer = [data mutableBytes];
[representation getBytes:buffer fromOffset:0 length:size error:nil];
data = [NSMutableData dataWithBytes:buffer length:size];
I'm not near xcode to test it right now, but it should work.
You can use CLLocation to get the current location.
At the time of image upload to server you need to need to get the current location through CLLocationManager and update this location parameters to server with the captured image.
Please check the reference link for location update and how to upload photos

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