iOS 8 Photos Framework. Access Photo Metadata

iOS 8 Photos framework. Access photo metadata

If you request a content editing input, you can get the full image as a CIImage, and CIImage has a property titled properties which is a dictionary containing the image metadata.

Sample Swift Code:

let options = PHContentEditingInputRequestOptions()
options.networkAccessAllowed = true //download asset metadata from iCloud if needed

asset.requestContentEditingInputWithOptions(options) { (contentEditingInput: PHContentEditingInput?, _) -> Void in
let fullImage = CIImage(contentsOfURL: contentEditingInput!.fullSizeImageURL)

print(fullImage.properties)
}

Sample Objective-C Code:

PHContentEditingInputRequestOptions *options = [[PHContentEditingInputRequestOptions alloc] init];
options.networkAccessAllowed = YES; //download asset metadata from iCloud if needed

[asset requestContentEditingInputWithOptions:options completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
CIImage *fullImage = [CIImage imageWithContentsOfURL:contentEditingInput.fullSizeImageURL];

NSLog(@"%@", fullImage.properties.description);
}];

You'll get the desired {Exif}, {TIFF}, {GPS}, etc dictionaries.

How to get image metadata in iOS 9 using Photos Framework

At first, you can get info[UIImagePickerControllerReferenceURL] from UIImagePickerController. Then you can do things like the following:

let assetURL = info[UIImagePickerControllerReferenceURL] as! NSURL
let asset = PHAsset.fetchAssetsWithALAssetURLs([assetURL], options: nil)
guard let result = asset.firstObject where result is PHAsset else {
return
}

let imageManager = PHImageManager.defaultManager()
imageManager.requestImageDataForAsset(result as! PHAsset, options: nil, resultHandler:{
(data, responseString, imageOriet, info) -> Void in
let imageData: NSData = data!
if let imageSource = CGImageSourceCreateWithData(imageData, nil) {
let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil)! as NSDictionary
//now you have got meta data in imageProperties, you can display PixelHeight, PixelWidth, etc.
}
})

Access metadata (exif tags) of image taken by UIImagePickerController - iOS/iPhone

Apparently, you can access the metadata of an image right after it has been taken. The protocol method that is called by the system after an image has been selected is:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

The NSDictionary argument, info, contains a key: UIImagePickerControllerMediaMetadata

Now if I can figure out how to get the exif tags or any exposure-level information from this to infer basic information about light-level I will be happy. :)

Loading/Retrieving an image from Photos Library based on metadata in iOS

If you already have a Core Data store, save all of the metadata and the asset URL (for the default representation). Then you can do all of your querying locally and access the assets only when required (though you should check they haven't been deleted before showing results).

When you have done your search to get the asset URL you can get the image using assetForURL:resultBlock:failureBlock: from the ALAssetsLibrary.

iOS8 Photos Framework: How to get the name(or filename) of a PHAsset?

If you want to get the image name (for example name of last photo in Photos) like IMG_XXX.JPG, you can try this:

PHAsset *asset = nil;
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) {
// get last photo from Photos
asset = [fetchResult lastObject];
}

if (asset) {
// get photo info from this asset
PHImageRequestOptions * imageRequestOptions = [[PHImageRequestOptions alloc] init];
imageRequestOptions.synchronous = YES;
[[PHImageManager defaultManager]
requestImageDataForAsset:asset
options:imageRequestOptions
resultHandler:^(NSData *imageData, NSString *dataUTI,
UIImageOrientation orientation,
NSDictionary *info)
{
NSLog(@"info = %@", info);
if ([info objectForKey:@"PHImageFileURLKey"]) {
// path looks like this -
// file:///var/mobile/Media/DCIM/###APPLE/IMG_####.JPG
NSURL *path = [info objectForKey:@"PHImageFileURLKey"];
}
}];
}

Hope it helps.

In Swift the code will look like this

PHImageManager.defaultManager().requestImageDataForAsset(asset, options: PHImageRequestOptions(), resultHandler:
{
(imagedata, dataUTI, orientation, info) in
if info!.keys.contains(NSString(string: "PHImageFileURLKey"))
{
let path = info![NSString(string: "PHImageFileURLKey")] as! NSURL
}
})

Swift 4:

    let fetchResult = PHAsset.fetchAssets(with: .image, options: nil)
if fetchResult.count > 0 {
if let asset = fetchResult.firstObject {
let date = asset.creationDate ?? Date()
print("Creation date: \(date)")
PHImageManager.default().requestImageData(for: asset, options: PHImageRequestOptions(),
resultHandler: { (imagedata, dataUTI, orientation, info) in
if let info = info {
if info.keys.contains(NSString(string: "PHImageFileURLKey")) {
if let path = info[NSString(string: "PHImageFileURLKey")] as? NSURL {
print(path)
}
}
}
})
}
}

Save and retrieve Photos with all their metadata locally on iOS using swift

Taking The image:

Take a look at the UIImagePickerController class and use it to take pictures. Taking pictures with this, will NOT save the images automatically to the iOS gallery.

The mentioned UIImagePickerController will notify a delegate UIImagePickerControllerDelegate and call the function func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]).

From the second parameter, the info dictionary, you can request most of the images metadata, livePhoto and so on. The necessary keys can be found inside the extension of UIImagePickerController called UIImagePickerController.InfoKey.

For example, here is how I then retrieve the images coordinate if available:

if let imageURL = info[UIImagePickerControllerReferenceURL] as? URL {
let result = PHAsset.fetchAssets(withALAssetURLs: [imageURL], options: nil)
if let asset = result.firstObject, let location = asset.location {
let lat = location.coordinate.latitude
let lon = location.coordinate.longitude
print("Here's the lat and lon \(lat) + \(lon)")
}
}

Saving the image onto the phone within your app?:

I use JSONEncoder. You can use this class to encode and then decode your custom image class again.

Your custom image class, which has the UIImage and all the other properties must then implement the Codable protocol.
Afterwards, use the JSONEncoder to create Data of the object via its encode() method and save it to an app private location with the help of a FileManager.
Later on, you may read all files from that location again with the FileManager, decode() with the JSONEncoder and voila you have all your images again in the form of your custom image class.

Saving the image to the users gallery "Exporting":

Here's an example of how I again save that image to the users gallery as a way of exporting it:

private static func saveImageToGallery(picture: UIImage, lat: Double?, lon: Double?) {
PHPhotoLibrary.shared().performChanges({
let request = PHAssetCreationRequest.creationRequestForAsset(from: picture)
if let _lat = lat, let _lon = lon {
request.location = CLLocation(latitude: _lat, longitude: _lon)
}
})
}

I hope this will be enough to guide you to the correct way.



Related Topics



Leave a reply



Submit