tom*_*lor 56 iphone gps cocoa-touch exif uiimagepickercontroller
众所周知,UIImagePickerController在选择后不会返回照片的元数据.但是,应用程序商店中的一些应用程序(Mobile Fotos,PixelPipe)似乎能够读取原始文件和存储在其中的EXIF数据,使应用程序能够从所选照片中提取地理数据.
他们似乎是通过从/ private/var/mobile/Media/DCIM/100APPLE /文件夹中读取原始文件并通过EXIF库运行它来完成此操作.
但是,我无法找到一种方法来匹配从UIImagePickerController返回的照片到磁盘上的文件.我已经探索了文件大小,但原始文件是JPEG,而返回的图像是原始UIImage,因此无法知道所选图像的文件大小.
我正在考虑制作一个哈希表并匹配每个图像的前x个像素.虽然这看起来有点过头了,但可能很慢.
有什么建议?
yon*_*nel 29
你看过这个exif iPhone库吗?
http://code.google.com/p/iphone-exif/
要试试我的一面.我想从UIImagePickerController拍摄的照片中获取GPS(地理标记)坐标:/
经过深入研究后,这个库似乎将NSData信息作为输入,UIImagePickerController在拍摄快照后返回UIImage.理论上,如果我们使用从UIkit类中选择的UIImage
NSData * UIImageJPEGRepresentation (
UIImage *image,
CGFloat compressionQuality
);
Run Code Online (Sandbox Code Playgroud)
然后我们可以将UIImage转换为NSData实例,然后将其与iPhone exif库一起使用.
更新:
我对上面提到的库进行了测试,似乎有效.但是由于我对EXIF格式的限制以及库中缺少高级API,我无法获得EXIF标签的值.这是我的代码,以防你们任何人可以走得更远:
#import "EXFJpeg.h"
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
NSLog(@"image picked %@ with info %@", image, editingInfo);
NSData* jpegData = UIImageJPEGRepresentation (image,0.5);
EXFJpeg* jpegScanner = [[EXFJpeg alloc] init];
[jpegScanner scanImageData: jpegData];
EXFMetaData* exifData = jpegScanner.exifMetaData;
EXFJFIF* jfif = jpegScanner.jfif;
EXFTag* tagDefinition = [exifData tagDefinition: [NSNumber numberWithInt:EXIF_DateTime]];
//EXFTag* latitudeDef = [exifData tagDefinition: [NSNumber numberWithInt:EXIF_GPSLatitude]];
//EXFTag* longitudeDef = [exifData tagDefinition: [NSNumber numberWithInt:EXIF_GPSLongitude]];
id latitudeValue = [exifData tagValue:[NSNumber numberWithInt:EXIF_GPSLatitude]];
id longitudeValue = [exifData tagValue:[NSNumber numberWithInt:EXIF_GPSLongitude]];
id datetime = [exifData tagValue:[NSNumber numberWithInt:EXIF_DateTime]];
id t = [exifData tagValue:[NSNumber numberWithInt:EXIF_Model]];
....
....
Run Code Online (Sandbox Code Playgroud)
检索标签定义是正常的,但所有标签值都返回nil:(
如果你想试试这个库,你需要定义一个全局变量来让它运行(如文档中所解释的那样但是哼..:/)
BOOL gLogging = FALSE;
更新2
在这里回答:iPhone - 从照片访问位置信息
UIImage没有封装元信息,因此我们陷入困境:当然,不会通过此界面提供EXIF信息.
最终更新
确定我设法让它工作,至少是对选择器返回的图片进行地理标记.
在触发UIImagePickerController之前,您可以使用CLLocationManager来检索当前的CLocation
一旦拥有它,您可以使用此方法使用exif-iPhone库从CLLocation对UIImage进行地理标记:
-(NSData*) geotagImage:(UIImage*)image withLocation:(CLLocation*)imageLocation { NSData* jpegData = UIImageJPEGRepresentation(image, 0.8); EXFJpeg* jpegScanner = [[EXFJpeg alloc] init]; [jpegScanner scanImageData: jpegData]; EXFMetaData* exifMetaData = jpegScanner.exifMetaData; // end of helper methods // adding GPS data to the Exif object NSMutableArray* locArray = [self createLocArray:imageLocation.coordinate.latitude]; EXFGPSLoc* gpsLoc = [[EXFGPSLoc alloc] init]; [self populateGPS: gpsLoc :locArray]; [exifMetaData addTagValue:gpsLoc forKey:[NSNumber numberWithInt:EXIF_GPSLatitude] ]; [gpsLoc release]; [locArray release]; locArray = [self createLocArray:imageLocation.coordinate.longitude]; gpsLoc = [[EXFGPSLoc alloc] init]; [self populateGPS: gpsLoc :locArray]; [exifMetaData addTagValue:gpsLoc forKey:[NSNumber numberWithInt:EXIF_GPSLongitude] ]; [gpsLoc release]; [locArray release]; NSString* ref; if (imageLocation.coordinate.latitude <0.0) ref = @"S"; else ref =@"N"; [exifMetaData addTagValue: ref forKey:[NSNumber numberWithInt:EXIF_GPSLatitudeRef] ]; if (imageLocation.coordinate.longitude <0.0) ref = @"W"; else ref =@"E"; [exifMetaData addTagValue: ref forKey:[NSNumber numberWithInt:EXIF_GPSLongitudeRef] ]; NSMutableData* taggedJpegData = [[NSMutableData alloc] init]; [jpegScanner populateImageData:taggedJpegData]; [jpegScanner release]; return [taggedJpegData autorelease]; }// Helper methods for location conversion -(NSMutableArray*) createLocArray:(double) val{ val = fabs(val); NSMutableArray* array = [[NSMutableArray alloc] init]; double deg = (int)val; [array addObject:[NSNumber numberWithDouble:deg]]; val = val - deg; val = val*60; double minutes = (int) val; [array addObject:[NSNumber numberWithDouble:minutes]]; val = val - minutes; val = val*60; double seconds = val; [array addObject:[NSNumber numberWithDouble:seconds]]; return array; } -(void) populateGPS:(EXFGPSLoc* ) gpsLoc :(NSArray*) locArray{ long numDenumArray[2]; long* arrPtr = numDenumArray; [EXFUtils convertRationalToFraction:&arrPtr :[locArray objectAtIndex:0]]; EXFraction* fract = [[EXFraction alloc] initWith:numDenumArray[0]:numDenumArray[1]]; gpsLoc.degrees = fract; [fract release]; [EXFUtils convertRationalToFraction:&arrPtr :[locArray objectAtIndex:1]]; fract = [[EXFraction alloc] initWith:numDenumArray[0] :numDenumArray[1]]; gpsLoc.minutes = fract; [fract release]; [EXFUtils convertRationalToFraction:&arrPtr :[locArray objectAtIndex:2]]; fract = [[EXFraction alloc] initWith:numDenumArray[0] :numDenumArray[1]]; gpsLoc.seconds = fract; [fract release]; }
nil
Ron*_*onC 23
这适用于iOS5(beta 4)和相机胶卷(你需要为.h中的块输入defs):
-(void) imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString*)kUTTypeImage]) {
NSURL *url = [info objectForKey:UIImagePickerControllerReferenceURL];
if (url) {
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset) {
CLLocation *location = [myasset valueForProperty:ALAssetPropertyLocation];
// location contains lat/long, timestamp, etc
// extracting the image is more tricky and 5.x beta ALAssetRepresentation has bugs!
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror) {
NSLog(@"cant get image - %@", [myerror localizedDescription]);
};
ALAssetsLibrary *assetsLib = [[ALAssetsLibrary alloc] init];
[assetsLib assetForURL:url resultBlock:resultblock failureBlock:failureblock];
}
}
Run Code Online (Sandbox Code Playgroud)
War*_*shi 17
有一种方法 iOS 8
不使用任何第三方EXIF库.
#import <Photos/Photos.h>
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *url = [info objectForKey:UIImagePickerControllerReferenceURL];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithALAssetURLs:@[url] options:nil];
PHAsset *asset = fetchResult.firstObject;
//All you need is
//asset.location.coordinate.latitude
//asset.location.coordinate.longitude
//Other useful properties of PHAsset
//asset.favorite
//asset.modificationDate
//asset.creationDate
}
Run Code Online (Sandbox Code Playgroud)
Apple在iOS4中添加了一个Image I/O Framework,可用于从图片中读取EXIF数据.我不知道是否UIImagePickerController返回嵌入了EXIF数据的图片.
编辑:在iOS4中,您可以通过获取UIImagePickerControllerMediaMetadata传递给UIImagePickerControllerDelegate委托的信息字典中的键值来获取EXIF数据.
tom*_*lor -2
执行此操作的顽皮方法是遍历 UIImagePickerViewController 的视图并在委托回调中挑选出选定的图像。
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
id thumbnailView = [[[[[[[[[[picker.view subviews]
objectAtIndex:0] subviews]
objectAtIndex:0] subviews]
objectAtIndex:0] subviews]
objectAtIndex:0] subviews]
objectAtIndex:0];
NSString *fullSizePath = [[[thumbnailView selectedPhoto] fileGroup] pathForFullSizeImage];
NSString *thumbnailPath = [[[thumbnailView selectedPhoto] fileGroup] pathForThumbnailFile];
NSLog(@"%@ and %@", fullSizePath, thumbnailPath);
}
Run Code Online (Sandbox Code Playgroud)
这将为您提供完整尺寸图像的路径,然后您可以使用您选择的 EXIF 库打开该图像。
但是,这会调用私有 API,如果您提交此应用程序,Apple将检测到这些方法名称。所以不要这样做,好吗?
| 归档时间: |
|
| 查看次数: |
44808 次 |
| 最近记录: |