如何從UIImage中選擇從UIImagePickerController獲取Exif信息?從UIImage獲取Exif數據 - UIImagePickerController
我爲此做了很多R & D並得到了很多答覆,但仍未能實現這一點。
請幫我解決這個問題了。
在此先感謝..
如何從UIImage中選擇從UIImagePickerController獲取Exif信息?從UIImage獲取Exif數據 - UIImagePickerController
我爲此做了很多R & D並得到了很多答覆,但仍未能實現這一點。
請幫我解決這個問題了。
在此先感謝..
我已經找到了解決方案,並得到了答案從here
從這裏我們可以得到GPS信息以及..
驚人的,感謝所有幫助我解決這個問題。
UPDATE
這是我創造了自己的另一個功能,也返回的Exif數據以及GPS數據和這個功能,我們不需要任何第三方庫..但是你必須把爲此提供位置服務。並使用當前的經度和緯度。所以必須使用CoreLocation.framework
//FOR CAMERA IMAGE
-(NSMutableData *)getImageWithMetaData:(UIImage *)pImage
{
NSData* pngData = UIImagePNGRepresentation(pImage);
CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)pngData, NULL);
NSDictionary *metadata = (NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
NSMutableDictionary *metadataAsMutable = [[metadata mutableCopy]autorelease];
[metadata release];
//For GPS Dictionary
NSMutableDictionary *GPSDictionary = [[[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyGPSDictionary]mutableCopy]autorelease];
if(!GPSDictionary)
GPSDictionary = [NSMutableDictionary dictionary];
[GPSDictionary setValue:[NSNumber numberWithDouble:currentLatitude] forKey:(NSString*)kCGImagePropertyGPSLatitude];
[GPSDictionary setValue:[NSNumber numberWithDouble:currentLongitude] forKey:(NSString*)kCGImagePropertyGPSLongitude];
NSString* ref;
if (currentLatitude <0.0)
ref = @"S";
else
ref [email protected]"N";
[GPSDictionary setValue:ref forKey:(NSString*)kCGImagePropertyGPSLatitudeRef];
if (currentLongitude <0.0)
ref = @"W";
else
ref [email protected]"E";
[GPSDictionary setValue:ref forKey:(NSString*)kCGImagePropertyGPSLongitudeRef];
[GPSDictionary setValue:[NSNumber numberWithFloat:location.altitude] forKey:(NSString*)kCGImagePropertyGPSAltitude];
//For EXIF Dictionary
NSMutableDictionary *EXIFDictionary = [[[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyExifDictionary]mutableCopy]autorelease];
if(!EXIFDictionary)
EXIFDictionary = [NSMutableDictionary dictionary];
[EXIFDictionary setObject:[NSDate date] forKey:(NSString*)kCGImagePropertyExifDateTimeOriginal];
[EXIFDictionary setObject:[NSDate date] forKey:(NSString*)kCGImagePropertyExifDateTimeDigitized];
//add our modified EXIF data back into the image’s metadata
[metadataAsMutable setObject:EXIFDictionary forKey:(NSString *)kCGImagePropertyExifDictionary];
[metadataAsMutable setObject:GPSDictionary forKey:(NSString *)kCGImagePropertyGPSDictionary];
CFStringRef UTI = CGImageSourceGetType(source);
NSMutableData *dest_data = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((CFMutableDataRef)dest_data, UTI, 1, NULL);
if(!destination)
dest_data = [[pngData mutableCopy] autorelease];
else
{
CGImageDestinationAddImageFromSource(destination, source, 0, (CFDictionaryRef) metadataAsMutable);
BOOL success = CGImageDestinationFinalize(destination);
if(!success)
dest_data = [[pngData mutableCopy] autorelease];
}
if(destination)
CFRelease(destination);
CFRelease(source);
return dest_data;
}
//FOR PHOTO LIBRARY IMAGE
-(NSMutableData *)getImagedataPhotoLibrary:(NSDictionary *)pImgDictionary andImage:(UIImage *)pImage
{
NSData* data = UIImagePNGRepresentation(pImage);
CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)data, NULL);
NSMutableDictionary *metadataAsMutable = [[pImgDictionary mutableCopy]autorelease];
CFStringRef UTI = CGImageSourceGetType(source);
NSMutableData *dest_data = [NSMutableData data];
//For Mutabledata
CGImageDestinationRef destination = CGImageDestinationCreateWithData((CFMutableDataRef)dest_data, UTI, 1, NULL);
if(!destination)
dest_data = [[data mutableCopy] autorelease];
else
{
CGImageDestinationAddImageFromSource(destination, source, 0, (CFDictionaryRef) metadataAsMutable);
BOOL success = CGImageDestinationFinalize(destination);
if(!success)
dest_data = [[data mutableCopy] autorelease];
}
if(destination)
CFRelease(destination);
CFRelease(source);
return dest_data;
}
,我們會找回這樣
//FOR CAMERA IMAGE
NSData *originalImgData = [self getImageWithMetaData:imgOriginal];
//FOR PHOTO LIBRARY IMAGE
[self getImagedataPhotoLibrary:[[myasset defaultRepresentation] metadata] andImage:imgOriginal];
對於這一切,你應該有導入AssetsLibrary.framework
和ImageIO.framework
數據。
哪裏是currentLatitude來自哪裏?您是在調用UIImagePicker之前從標準CoreLocation調用中設置它,還是直接從返回的圖像中讀取它? – 2012-04-24 14:55:14
CoreLoation在調用UIImagePickerController – 2012-04-25 04:17:33
之前調用ahhh,那麼它可能不準確。您可以調用CoreLocation,調用UIImagePicker,然後在拍攝圖像前將設備物理移動一段距離。您現在將有不準確的經度和緯度。 Drat ... – 2012-04-25 08:48:08
有趣的問題!我想出了以下解決方案的圖像時,從你的照片庫中挑選(注意我的代碼使用ARC):
導入AssetsLibrary.framework
和ImageIO.framework
。
然後包括你的.h文件內所需的類:
#import <AssetsLibrary/ALAsset.h>
#import <AssetsLibrary/ALAssetRepresentation.h>
#import <ImageIO/CGImageSource.h>
#import <ImageIO/CGImageProperties.h>
,並把這個你imagePickerController:didFinishPickingMediaWithInfo:
委託方法內:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library assetForURL:[info objectForKey:UIImagePickerControllerReferenceURL]
resultBlock:^(ALAsset *asset) {
ALAssetRepresentation *image_representation = [asset defaultRepresentation];
// create a buffer to hold image data
uint8_t *buffer = (Byte*)malloc(image_representation.size);
NSUInteger length = [image_representation getBytes:buffer fromOffset: 0.0 length:image_representation.size error:nil];
if (length != 0) {
// buffer -> NSData object; free buffer afterwards
NSData *adata = [[NSData alloc] initWithBytesNoCopy:buffer length:image_representation.size freeWhenDone:YES];
// identify image type (jpeg, png, RAW file, ...) using UTI hint
NSDictionary* sourceOptionsDict = [NSDictionary dictionaryWithObjectsAndKeys:(id)[image_representation UTI] ,kCGImageSourceTypeIdentifierHint,nil];
// create CGImageSource with NSData
CGImageSourceRef sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef) adata, (__bridge CFDictionaryRef) sourceOptionsDict);
// get imagePropertiesDictionary
CFDictionaryRef imagePropertiesDictionary;
imagePropertiesDictionary = CGImageSourceCopyPropertiesAtIndex(sourceRef,0, NULL);
// get exif data
CFDictionaryRef exif = (CFDictionaryRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyExifDictionary);
NSDictionary *exif_dict = (__bridge NSDictionary*)exif;
NSLog(@"exif_dict: %@",exif_dict);
// save image WITH meta data
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSURL *fileURL = nil;
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(sourceRef, 0, imagePropertiesDictionary);
if (![[sourceOptionsDict objectForKey:@"kCGImageSourceTypeIdentifierHint"] isEqualToString:@"public.tiff"])
{
fileURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@.%@",
documentsDirectory,
@"myimage",
[[[sourceOptionsDict objectForKey:@"kCGImageSourceTypeIdentifierHint"] componentsSeparatedByString:@"."] objectAtIndex:1]
]];
CGImageDestinationRef dr = CGImageDestinationCreateWithURL ((__bridge CFURLRef)fileURL,
(__bridge CFStringRef)[sourceOptionsDict objectForKey:@"kCGImageSourceTypeIdentifierHint"],
1,
NULL
);
CGImageDestinationAddImage(dr, imageRef, imagePropertiesDictionary);
CGImageDestinationFinalize(dr);
CFRelease(dr);
}
else
{
NSLog(@"no valid kCGImageSourceTypeIdentifierHint found …");
}
// clean up
CFRelease(imageRef);
CFRelease(imagePropertiesDictionary);
CFRelease(sourceRef);
}
else {
NSLog(@"image_representation buffer length == 0");
}
}
failureBlock:^(NSError *error) {
NSLog(@"couldn't get asset: %@", error);
}
];
有一件事我就是注意到了,那iOS會要求的用戶允許定位服務 - 如果他否認,您將無法獲取圖像數據...
編輯
添加代碼以保存圖像,包括其元數據。這是一個快速的方法,所以也許有更好的方法,但它的工作原理!
你能告訴我如何保存圖像後獲得exif數據? – 2012-03-19 09:40:52
+1很酷的答案.. – 2012-03-19 09:44:01
@Marvin查看我的編輯:P – dom 2012-03-19 10:54:10
您需要ALAssetsLibrary才能從圖像中實際檢索EXIF信息。僅當EXIF保存到照片庫時纔會將EXIF添加到圖像中。即使您使用ALAssetLibrary從庫中獲取圖像資源,如果將其設置爲UIImage,它也會丟失所有EXIF信息。
我曾嘗試將GPS座標插入由iPad相機拍攝的圖像元數據中,正如Mehul所建議的那樣。它工作,感謝您的職位。
P.S. 誰打算使用該代碼,只需分別代替兩個geolocations在函數的頂部 - (NSMutableData *)getImageWithMetaData:(*的UIImage)pImage {
double currentLatitude = [locationManager location].coordinate.latitude;
double currentLongitude = [locationManager location].coordinate.longitude;
...
通過假設你已經在你的代碼的某個地方的LocationManager initializied,像這樣:
locationManager = [[CLLocationManager alloc] init];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager setDelegate:self]; // Not necessary in this case
[locationManager startUpdatingLocation]; // Not neccessary in this case
,並通過導入CoreLocation/CoreLocation.h和ImageIO的/ ImageIO.h頭以及相關的框架。
這些答案似乎都非常複雜。如果圖像已保存到相機膠捲,和你有ALAsset(無論是從UIImagePicker或ALAssetLibrary)即可獲得元數據,像這樣:
asset.defaultRepresentation.metadata;
如果您想保存從相機膠捲到另一圖像位置(在沙盒/文件說)只是做:
CGImageDestinationRef imageDestinationRef = CGImageDestinationCreateWithURL((__bridge CFURLRef)urlToSaveTo, kUTTypeJPEG, 1, NULL);
CFDictionaryRef imagePropertiesRef = (__bridge CFDictionaryRef)asset.defaultRepresentation.metadata;
CGImageDestinationAddImage(imageDestinationRef, asset.defaultRepresentation.fullResolutionImage, imagePropertiesRef);
if (!CGImageDestinationFinalize(imageDestinationRef)) NSLog(@"Failed to copy photo on save to %@", urlToSaveTo);
CFRelease(imageDestinationRef);
這是一個比2012年答案要好得多的方法。 – broughten 2013-10-18 06:13:12
它還會返回**更多**信息,而不是其他方式:它們不會返回信息存儲在{TIFF}中,如模型,製作,版權,藝術家等。這**應該被標記爲答案! – 2013-12-07 17:02:37
我已經使用這個方法從圖像獲取exifdata字典,我希望這也會爲你工作
-(void)getExifDataFromImage:(UIImage *)currentImage
{
NSData* pngData = UIImageJPEGRepresentation(currentImage, 1.0);
CGImageSourceRef mySourceRef = CGImageSourceCreateWithData((CFDataRef)pngData, NULL);
//CGImageSourceRef mySourceRef = CGImageSourceCreateWithURL((__bridge CFURLRef)myURL, NULL);
if (mySourceRef != NULL)
{
NSDictionary *myMetadata = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(mySourceRef,0,NULL);
NSDictionary *exifDic = [myMetadata objectForKey:(NSString *)kCGImagePropertyExifDictionary];
NSDictionary *tiffDic = [myMetadata objectForKey:(NSString *)kCGImagePropertyTIFFDictionary];
NSLog(@"exifDic properties: %@", myMetadata); //all data
float rawShutterSpeed = [[exifDic objectForKey:(NSString *)kCGImagePropertyExifExposureTime] floatValue];
int decShutterSpeed = (1/rawShutterSpeed);
NSLog(@"Camera %@",[tiffDic objectForKey:(NSString *)kCGImagePropertyTIFFModel]);
NSLog(@"Focal Length %@mm",[exifDic objectForKey:(NSString *)kCGImagePropertyExifFocalLength]);
NSLog(@"Shutter Speed %@", [NSString stringWithFormat:@"1/%d", decShutterSpeed]);
NSLog(@"Aperture f/%@",[exifDic objectForKey:(NSString *)kCGImagePropertyExifFNumber]);
NSNumber *ExifISOSpeed = [[exifDic objectForKey:(NSString*)kCGImagePropertyExifISOSpeedRatings] objectAtIndex:0];
NSLog(@"ISO %ld",[ExifISOSpeed integerValue]);
NSLog(@"Taken %@",[exifDic objectForKey:(NSString*)kCGImagePropertyExifDateTimeDigitized]);
}
}
看到這個答案。 [解決方案** iOS 8 **](http://stackoverflow.com/a/33672661/1378447) – 2015-11-12 13:42:15