I want to display image metadata using ios. Meta data like Aperture, Shutterspeed, Exposure Compensation, ISO, Lens Focal Length, etc. So please help me if anybody has idea
Answering my own question. The memory-effective and fast way to get a GPS metadata is
let options = [kCGImageSourceShouldCache as String: kCFBooleanFalse]
if let data = NSData(contentsOfURL: url), imgSrc = CGImageSourceCreateWithData(data, options) {
let metadata = CGImageSourceCopyPropertiesAtIndex(imgSrc, 0, options) as Dictionary
let gpsData = metadata[kCGImagePropertyGPSDictionary] as? [String : AnyObject]
}
The second option is
if let img = CIImage(contentsOfURL: url), metadata = img.properties(),
gpsData = metadata[kCGImagePropertyGPSDictionary] as? [String : AnyObject] { … }
it looks nicer in Swift but uses more memory (tested via Profiler).
updated to iOS 11 with photos framework
Objective - C:
#import <Photos/Photos.h>
- (void)imagePickerController:(UIImagePickerController *)imagePicker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
PHAsset* asset = info[UIImagePickerControllerPHAsset];
[asset requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
CIImage *fullImage = [CIImage imageWithContentsOfURL:contentEditingInput.fullSizeImageURL];
NSLog(@"%@", fullImage.properties.description);
}];
[imagePicker dismissViewControllerAnimated:YES completion:nil];
}
You also need the permission of Photo library Usage (NSPhotoLibraryUsageDescription) and then can add the following code to view did load or view did appear
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
switch (status) {
case PHAuthorizationStatusAuthorized:
NSLog(@"PHAuthorizationStatusAuthorized");
break;
case PHAuthorizationStatusDenied:
NSLog(@"PHAuthorizationStatusDenied");
break;
case PHAuthorizationStatusNotDetermined:
NSLog(@"PHAuthorizationStatusNotDetermined");
break;
case PHAuthorizationStatusRestricted:
NSLog(@"PHAuthorizationStatusRestricted");
break;
}
}];
Here is what I'm using to get the image size:
+ (CGSize) sizeOfImage:(NSString *) fileName withPath: (NSURL *) fullDirectoryPath;
{
NSURL *imageNameWithPath = [NSURL URLWithString:fileName relativeToURL:fullDirectoryPath];
CGImageSourceRef source = CGImageSourceCreateWithURL( (CFURLRef) imageNameWithPath, NULL);
if (!source) return CGSizeZero;
CFDictionaryRef dictRef = CGImageSourceCopyPropertiesAtIndex(source,0,NULL);
NSDictionary* metadata = (__bridge NSDictionary *)dictRef;
NSLog(@"metadata= %@", metadata);
CGSize result = CGSizeZero;
CGFloat width = [metadata[@"PixelWidth"] floatValue];
CGFloat height = [metadata[@"PixelHeight"] floatValue];
NSLog(@"width= %f, height= %f", width, height);
// The orientation in the metadata does *not* map to UIImageOrientation. Rather, see: https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGImageProperties_Reference/index.html#//apple_ref/doc/constant_group/Individual_Image_Properties
// This idea of orientation seems a little odd to me, but it seems it translates to even numbers need to be switched in width/height, odd numbers do not.
NSUInteger orientation = [metadata[@"Orientation"] integerValue];
switch (orientation) {
// Comments give "Location of the origin of the image"
case 1: // Top, left
case 3: // Bottom, right
case 5: // Left, top
case 7: // Right, bottom
result = CGSizeMake(width, height);
break;
case 2: // Top, right
case 4: // Bottom, left
case 6: // Right, top
case 8: // Left, bottom
result = CGSizeMake(height, width);
break;
default:
NSAssert(NO, @"Should not get to here!");
break;
}
CFRelease(source);
NSLog(@"size: %@, orientation: %d", NSStringFromCGSize(result), orientation);
return result;
}
/* Example meta data:
ColorModel = RGB;
Depth = 8;
Orientation = 6;
PixelHeight = 1936;
PixelWidth = 2592;
"{Exif}" = {
ColorSpace = 1;
PixelXDimension = 2592;
PixelYDimension = 1936;
};
"{JFIF}" = {
DensityUnit = 0;
JFIFVersion = (
1,
1
);
XDensity = 1;
YDensity = 1;
};
"{TIFF}" = {
Orientation = 6;
};
}
*/