[Objective-C] UIImagePickerController で撮影した画像にExif 情報とGPS情報を付与して保存する

投稿者: | 2014/01/04

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];
}

 

参考

こちらを参考にさせて頂きました。
(つか、例によってほぼまんまですな。)


 



 

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください