元の問題
元のEXIF/JFIFデータをすべて保持しながら、画像をカメラロールに保存しようとしています。カメラロールに保存された画像を元のファイルと同じバイト単位で表示したいのですが。を介して画像を保存する[ALAssetsLibrary writeImageDataToSavedPhotosAlbum:metadata:completionBlock:]
と、元のEXIFデータは保持されますが、JFIFは削除されます。
ALAssetsLibrary *library = [[[ALAssetsLibrary alloc] init] autorelease];
[library writeImageDataToSavedPhotosAlbum:imageData metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
[self imageDidFinishSavingToCameraRollWithError:error];
}];
iphone-exifプロジェクトを使用してJFIFデータを解析し、メタデータパラメーターを介して明示的に渡してみました。
EXFJpeg *jpegScanner = [[EXFJpeg alloc] init];
[jpegScanner scanImageData:imageData];
EXFJFIF *jfif = [jpegScanner jfif];
NSMutableDictionary *jfifMetadata = [[NSMutableDictionary alloc] init];
[jfifMetadata setObject:[jfif version] forKey:(NSString *)kCGImagePropertyJFIFVersion];
...
NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init];
[metadata setObject:jfifMetadata forKey:(NSString*)kCGImagePropertyJFIFDictionary];
ただし、これを行うと、メタデータディクショナリを渡すのと同じファイルがバイト単位で生成nil
されます。つまり、JFIFデータはiOSによって引き続き削除されます。
ウィキペディアによると:
正式には、Exif標準とJFIF標準には互換性がありません。これは、両方が特定のアプリケーションセグメント(JFIFの場合はAPP0、Exifの場合はAPP1)がイメージファイルの最初である必要があることを指定しているためです。実際には、多くのプログラムとデジタルカメラは、両方のアプリケーションセグメントが含まれるファイルを生成します。これはほとんどのデコーダーの画像デコードには影響しませんが、設計が不十分なJFIFまたはExifパーサーはファイルを正しく認識しない場合があります。
元のファイルをバイト単位でカメラロールに保存する方法はありますか、またはEXIFが存在する場合、iOSは常にJFIFデータを無視しますか?
更新:2013年2月26日
私は<rdar://13291591>
Appleに提出しました。この問題を示すサンプルプロジェクトも作成しました:http ://spolet.to/3J0l1u3w0R2e
サンプルアプリには3つのボタンがあります。1つはJFIFデータを含むJPEG用、もう1つはJFIFデータを含まないJPEG用、もう1つはPNG用です。ボタンをタップすると、対応する画像がハッシュされてフォトライブラリに保存されます。結果のALAssetもハッシュされます。
結果:
- 保存されたPNGのALAssetには、元のファイルと同じハッシュがあります。
- 保存されたJPEGのALAssetsには、元のJPEGと同じハッシュがありません。
これを掘り下げると、ALAsset EXIFデータ内の「BrightnessValue」、「Components Configuration」、「Thumbnail Length」、および「ThumbnailImage」属性がOSによって変更されているようです。さらに、元のJFIFデータ(JFIFを含む画像の場合)が削除されています。
推測される結果:
- フォトライブラリに保存するときは、3つのファイルすべてに同じハッシュが必要です。