強火で進め このページをアンテナに追加 RSSフィード

整理された情報は こちら へどうぞ。

2010年07月17日

[]JPEGファイルのExif情報を読み書きする

※このプログラムはiOS 4以降対応です。それ以前のOSでは正しく動作しません。

(2013/12/16 追記)

iOS SDK 7だと不具合が発生しています。ご注意を!!

iOS SDK 7でImageIO Frameworkを使ってExif情報にユーザコメントを書き込む時は注意が必要 - 強火で進め

http://d.hatena.ne.jp/nakamura001/20131215/1387125345

(追記ここまで)

Exif情報の読み書きには ImgageIO.framework を使用しますのでこちらを追加してプログラムの先頭に

#import <ImageIO/ImageIO.h>

を追加します。

Exif情報を書き込んだJPEGファイルを書き出す場合は以下の様にします。

- (IBAction)exifExport {
	NSString *imgPath = [NSString stringWithFormat:@"%@/sample.jpg", [[NSBundle mainBundle] resourcePath]];
	CGImageSourceRef cgImage = CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:imgPath], nil);
	NSMutableDictionary* exifDict = [[[NSMutableDictionary alloc] init] autorelease];

	[exifDict setObject:@"テストabc123" forKey:(NSString*)kCGImagePropertyExifUserComment];
	NSMutableData* imageData = [[[NSMutableData alloc] init] autorelease];
	CGImageDestinationRef dest = CGImageDestinationCreateWithData((CFMutableDataRef)imageData, CGImageSourceGetType(cgImage), 1, nil);
	CGImageDestinationAddImageFromSource(dest, cgImage, 0, 
										 (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
														   exifDict, (NSString*)kCGImagePropertyExifDictionary, nil]);
	CGImageDestinationFinalize(dest);
	NSString *exportPath = [NSString stringWithFormat:@"%@/export.jpg", [[NSBundle mainBundle] resourcePath]];
	NSLog(@"exportPath : %@", exportPath);
	[imageData writeToFile:exportPath atomically:YES];
	CFRelease(cgImage);
	CFRelease(dest);
}

ここではアプリにの同梱した sample.jpg にコメント「テストabc123」を書き込んで export.jpg というファイル名で出力しています。

シミュレータで実行してコンソールに出力されたパスの export.jpg をMacの標準アプリ「プレビュー」で確認して下さい。プレビューでExif情報を確認する為には cmd+I でインスペクタを表示し、以下の部分を選択すると確認できます。

※シミュレータ上で作成したファイルの確認方法はこちらを参照下さい。

f:id:nakamura001:20100717231907p:image

Exif情報を読み込む場合は以下の様になります。

- (IBAction)exifImport {
	NSString *imgPath = [NSString stringWithFormat:@"%@/sample.jpg", [[NSBundle mainBundle] resourcePath]];
	CGImageSourceRef cgImage = CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:imgPath], nil);
	NSDictionary *metaDataDict = (NSDictionary *)CGImageSourceCopyPropertiesAtIndex(cgImage, 0, nil);
	if (metaDataDict) {
		NSDictionary *exifDict;
		exifDict = [metaDataDict objectForKey:(NSString *)kCGImagePropertyExifDictionary];
		if (exifDict && [exifDict count] > 0) {
			NSString *commentStr = [exifDict objectForKey:(NSString *)kCGImagePropertyExifUserComment];
			if (commentStr) {
				textView_.text = [NSString stringWithFormat:@"ユーザコメント : %@", commentStr];
			}
		}
	} else {
		textView_.text = [NSString stringWithString:@"Exif情報無し"];
	}
	[metaDataDict release];
	CFRelease(cgImage);
}

ここで使ったサンプルはこちらからDLできます。

参考サイト

こちらのプロジェクトの

BathyScaphe プロジェクト日本語トップページ - SourceForge.JP

http://sourceforge.jp/projects/bathyscaphe/

こちらのソース

View of /bathyscaphe/trunk/application/subproj/previewer/BSIPIToken.m - BathyScaphe - SourceForge.JP

http://sourceforge.jp/projects/bathyscaphe/svn/view/bathyscaphe/trunk/application/subproj/previewer/BSIPIToken.m?view=markup&root=bathyscaphe&pathrev=1177

Cocoa Wiki » CoreGraphicsでExifを扱う

http://cocoawiki.aerial.st/index.php?CoreGraphics%E3%81%A7Exif%E3%82%92%E6%89%B1%E3%81%86

Exif情報を保ったままカメラロールに保存する方法。

[AssetsLibrary] フォトライブラリの写真にExif情報を付けて保存する - Ni chicha, ni limona - 平均から抜けられない僕 - iPhoneアプリ開発グループ

http://iphone-dev.g.hatena.ne.jp/paella/20101014/1287070858

drjirodrjiro 2013/12/14 15:14 いつも参考にさせていただいております。
Exifのサンプルですが、iOS6.1ではOKですが、iOS7だと文字が途中で切れてしまいますね。
文字数+2のASCII文字をパッディングすれば、文字自体は書き込めるのですが、パディングした文は0x00が埋め込まれてしまいます。
どなたか対処方法をご存じないでしょうか?

nakamura001nakamura001 2013/12/16 01:14 コメントを頂いたのでこちらでも確認してみましたが英語のみの場合や日本語のみの場合は大丈夫ですが英語と日本語が混在していると途中で途切れるバグがiOS SDK 7だと有るみたいですね。

こちらでも事前にUnicode(UTF-16)に変換してから渡すなども試してみましたが残念ながら上手く行きませんでした。

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト

コメントを書くには、なぞなぞ認証に回答する必要があります。