Exif情報 と GPS情報を個別に取得してから1つにまとめて付与する
コードはこんな感じ。
MyViewController.h
#import <UIKit/UIKit.h>
// 各種ライブラリをインポート(プロジェクトへのライブラリ登録も忘れずに)
#import <ImageIO/ImageIO.h>
#import <CoreLocation/CoreLocation.h>
#import <AssetsLibrary/AssetsLibrary.h>
@interface MyViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate> {
CLLocationManager* locationManager_;
}
MyViewController.m
#import "MyViewController.h"
@implementation MyViewController
#pragma mark - View Life Cycle
- (void)viewDidLoad {
[super viewDidLoad];
if ( !locationManager_ ) {
locationManager_ = [CLLocationManager new];
}
if ( [CLLocationManager locationServicesEnabled] ) {
[locationManager_ setDelegate:self];
[locationManager_ setDistanceFilter:kCLDistanceFilterNone];
[locationManager_ setDesiredAccuracy:kCLLocationAccuracyBest];
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[locationManager_ startUpdatingLocation];
if ( ![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] ) {
return;
}
UIImagePickerController* ipc = [UIImagePickerController new];
[ipc setSourceType:UIImagePickerControllerSourceTypeCamera];
[ipc setDelegate:self];
[ipc setAllowsEditing:NO];
[ipc setCameraFlashMode:UIImagePickerControllerCameraFlashModeOff];
[UIView animateWithDuration:0.0f
animations:^{
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp
forView:[ipc view]
cache:NO];
}
completion:^(BOOL finished){
[self presentViewController:ipc animated:NO completion:^{}];
}
];
}
- (void)viewWillDisappear:(BOOL)animated {
[locationManager_ stopUpdatingLocation];
[super viewWillDisappear:animated];
}
#pragma mark - Delegate Methods
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = info[UIImagePickerControllerOriginalImage];
// 位置情報
CLLocation* location = locationManager_.location;
NSMutableDictionary* gpsDict = [NSMutableDictionary new];
// GPS日付(UTC)
NSDateFormatter* dfGPSDate = [NSDateFormatter new];
dfGPSDate.dateFormat = @"yyyy:MM:dd";
dfGPSDate.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];;
gpsDict[(NSString *)kCGImagePropertyGPSDateStamp] = [dfGPSDate stringFromDate:location.timestamp];
// GPS時刻(UTC)
NSDateFormatter* dfGPSTime = [NSDateFormatter new];
dfGPSTime.dateFormat = @"HH:mm:ss.SSSSSS";
dfGPSTime.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
gpsDict[(NSString *)kCGImagePropertyGPSTimeStamp] = [dfGPSTime stringFromDate:location.timestamp];
// 緯度
CGFloat latitude = location.coordinate.latitude;
NSString *gpsLatitudeRef;
if (latitude < 0) {
latitude = -latitude;
gpsLatitudeRef = @"S";
} else {
gpsLatitudeRef = @"N";
}
gpsDict[(NSString *)kCGImagePropertyGPSLatitudeRef] = gpsLatitudeRef;
gpsDict[(NSString *)kCGImagePropertyGPSLatitude] = @(latitude);
// 経度
CGFloat longitude = location.coordinate.longitude;
NSString *gpsLongitudeRef;
if (longitude < 0) {
longitude = -longitude;
gpsLongitudeRef = @"W";
} else {
gpsLongitudeRef = @"E";
}
gpsDict[(NSString *)kCGImagePropertyGPSLongitudeRef] = gpsLongitudeRef;
gpsDict[(NSString *)kCGImagePropertyGPSLongitude] = @(longitude);
// 標高
CGFloat altitude = location.altitude;
if (!isnan(altitude)){
NSString *gpsAltitudeRef;
if (altitude < 0) {
altitude = -altitude;
gpsAltitudeRef = @"1";
} else {
gpsAltitudeRef = @"0";
}
gpsDict[(NSString *)kCGImagePropertyGPSAltitudeRef] = gpsAltitudeRef;
gpsDict[(NSString *)kCGImagePropertyGPSAltitude] = @(altitude);
}
// Exif情報 にGPS情報を追加
NSMutableDictionary* exifDict = info[UIImagePickerControllerMediaMetadata];
exifDict[(NSString *)kCGImagePropertyGPSDictionary] = (NSDictionary*)gpsDict;
// GPS情報を追加したExif情報と共に画像をカメラロールに保存
ALAssetsLibrary* assetLibrary = [ALAssetsLibrary new];
[assetLibrary writeImageToSavedPhotosAlbum:image.CGImage metadata:exifDict completionBlock:^(NSURL *assetURL, NSError *error) {
if ( error ) {
NSLog(@"Save image failed. n%@", error);
}
}];
[self dismissViewControllerAnimated:YES completion:nil];
}
参考
こちらを参考にさせて頂きました。
(つか、例によってほぼまんまですな。)