SOの答え+ Googleの結果が何度も何度も試してふるいすぎると、iOSのEXIFで作業することはとてもイライラします。変更されたEXIFデータが適切に保存されない
以下はその結果を示す作業コードです。
この出力[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection
completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
NSData *imageNSData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
CGImageSourceRef imgSource = CGImageSourceCreateWithData((__bridge_retained CFDataRef)imageNSData, NULL);
//get all the metadata in the image
NSDictionary *metadata = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(imgSource, 0, NULL);
NSLog(@"original metadata Info: %@",metadata);
//make the metadata dictionary mutable so we can add properties to it
NSMutableDictionary *metadataAsMutable = [metadata mutableCopy];
NSMutableDictionary *EXIFDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyExifDictionary]mutableCopy];
NSMutableDictionary *GPSDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyGPSDictionary]mutableCopy];
NSMutableDictionary *RAWDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyRawDictionary]mutableCopy];
if(!EXIFDictionary)
EXIFDictionary = [[NSMutableDictionary dictionary] init];
if(!GPSDictionary)
GPSDictionary = [[NSMutableDictionary dictionary] init];
if(!RAWDictionary)
RAWDictionary = [[NSMutableDictionary dictionary] init];
[GPSDictionary setObject:@"camera coord Latitude"
forKey:(NSString*)kCGImagePropertyGPSLatitude];
[GPSDictionary setObject:@"camera coord Longitude"
forKey:(NSString*)kCGImagePropertyGPSLongitude];
[GPSDictionary setObject:@"camera GPS Date Stamp"
forKey:(NSString*)kCGImagePropertyGPSDateStamp];
[GPSDictionary setObject:@"camera direction (heading) in degrees"
forKey:(NSString*)kCGImagePropertyGPSImgDirection];
[GPSDictionary setObject:@"subject coord Latitude"
forKey:(NSString*)kCGImagePropertyGPSDestLatitude];
[GPSDictionary setObject:@"subject coord Longitude"
forKey:(NSString*)kCGImagePropertyGPSDestLongitude];
[EXIFDictionary setObject:@"[S.D.] kCGImagePropertyExifUserComment"
forKey:(NSString *)kCGImagePropertyExifUserComment];
[EXIFDictionary setValue:@"69 m" forKey:(NSString *)kCGImagePropertyExifSubjectDistance];
//Add the modified Data back into the image’s metadata
[metadataAsMutable setObject:EXIFDictionary forKey:(NSString *)kCGImagePropertyExifDictionary];
[metadataAsMutable setObject:GPSDictionary forKey:(NSString *)kCGImagePropertyGPSDictionary];
[metadataAsMutable setObject:RAWDictionary forKey:(NSString *)kCGImagePropertyRawDictionary];
NSLog(@"metadataAsMutable Info: %@",metadataAsMutable);
CFStringRef UTI = CGImageSourceGetType(imgSource); //this is the type of image (e.g., public.jpeg)
//this will be the data CGImageDestinationRef will write into
NSMutableData *newImageData = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)newImageData, UTI, 1, NULL);
if(!destination)
NSLog(@"***Could not create image destination ***");
//add the image contained in the image source to the destination, overidding the old metadata with our modified metadata
CGImageDestinationAddImageFromSource(destination, imgSource, 0, (__bridge CFDictionaryRef) metadataAsMutable);
//tell the destination to write the image data and metadata into our data object.
//It will return false if something goes wrong
BOOL success = NO;
success = CGImageDestinationFinalize(destination);
if(!success)
NSLog(@"***Could not create data from image destination ***");
CIImage *testImage = [CIImage imageWithData:newImageData];
NSDictionary *propDict = [testImage properties];
NSLog(@"Properties %@", propDict);
}];
:
2012-10-12 23:17:45.415 Waypointer[3120:907] original metadata Info: {
ColorModel = RGB;
DPIHeight = 72;
DPIWidth = 72;
Depth = 8;
Orientation = 1;
PixelHeight = 2448;
PixelWidth = 3264;
"{Exif}" = {
ApertureValue = "2.526069";
BrightnessValue = "-4.410617";
ColorSpace = 1;
ComponentsConfiguration = (
1,
2,
3,
0
);
ExifVersion = (
2,
2,
1
);
ExposureMode = 0;
ExposureProgram = 2;
ExposureTime = "0.06666667";
FNumber = "2.4";
Flash = 16;
FlashPixVersion = (
1,
0
);
FocalLenIn35mmFilm = 35;
FocalLength = "4.28";
ISOSpeedRatings = (
800
);
MeteringMode = 5;
PixelXDimension = 3264;
PixelYDimension = 2448;
SceneCaptureType = 0;
SensingMethod = 2;
ShutterSpeedValue = "3.906905";
SubjectArea = (
1631,
1223,
881,
881
);
WhiteBalance = 0;
};
"{TIFF}" = {
Orientation = 1;
ResolutionUnit = 2;
XResolution = 72;
YResolution = 72;
"_YCbCrPositioning" = 1;
};
}
そして、この:それはすべて完了だ後
2012-10-12 23:17:45.421 Waypointer[3120:907] metadataAsMutable Info: {
ColorModel = RGB;
DPIHeight = 72;
DPIWidth = 72;
Depth = 8;
Orientation = 1;
PixelHeight = 2448;
PixelWidth = 3264;
"{Exif}" = {
ApertureValue = "2.526069";
BrightnessValue = "-4.410617";
ColorSpace = 1;
ComponentsConfiguration = (
1,
2,
3,
0
);
ExifVersion = (
2,
2,
1
);
ExposureMode = 0;
ExposureProgram = 2;
ExposureTime = "0.06666667";
FNumber = "2.4";
Flash = 16;
FlashPixVersion = (
1,
0
);
FocalLenIn35mmFilm = 35;
FocalLength = "4.28";
ISOSpeedRatings = (
800
);
MeteringMode = 5;
PixelXDimension = 3264;
PixelYDimension = 2448;
SceneCaptureType = 0;
SensingMethod = 2;
ShutterSpeedValue = "3.906905";
SubjectArea = (
1631,
1223,
881,
881
);
SubjectDistance = "69 m";
UserComment = "[S.D.] kCGImagePropertyExifUserComment";
WhiteBalance = 0;
};
"{GPS}" = {
DateStamp = "camera GPS Date Stamp";
DestLatitude = "subject coord Latitude";
DestLongitude = "subject coord Longitude";
ImgDirection = "camera direction (heading) in degrees";
Latitude = "camera coord Latitude";
Longitude = "camera coord Longitude";
};
"{Raw}" = {
};
"{TIFF}" = {
Orientation = 1;
ResolutionUnit = 2;
XResolution = 72;
YResolution = 72;
"_YCbCrPositioning" = 1;
};
}
そして、この:例が示すように
2012-10-12 23:17:47.131 Waypointer[3120:907] Properties {
ColorModel = RGB;
DPIHeight = 72;
DPIWidth = 72;
Depth = 8;
Orientation = 1;
PixelHeight = 2448;
PixelWidth = 3264;
"{Exif}" = {
ApertureValue = "2.526069";
BrightnessValue = "-4.410617";
ColorSpace = 1;
ComponentsConfiguration = (
0,
0,
0,
1
);
ExifVersion = (
2,
2,
1
);
ExposureMode = 0;
ExposureProgram = 2;
ExposureTime = "0.06666667";
FNumber = "2.4";
Flash = 16;
FlashPixVersion = (
1,
0
);
FocalLenIn35mmFilm = 35;
FocalLength = "4.28";
ISOSpeedRatings = (
800
);
MeteringMode = 5;
PixelXDimension = 3264;
PixelYDimension = 2448;
SceneCaptureType = 0;
SensingMethod = 2;
ShutterSpeedValue = "3.906905";
SubjectArea = (
1631,
1223,
881,
881
);
UserComment = "[S.D.] kCGImagePropertyExifUserComment";
WhiteBalance = 0;
};
"{JFIF}" = {
DensityUnit = 1;
JFIFVersion = (
1,
1
);
XDensity = 72;
YDensity = 72;
};
"{TIFF}" = {
Orientation = 1;
ResolutionUnit = 2;
XResolution = 72;
YResolution = 72;
"_YCbCrPositioning" = 1;
};
}
を、あなたイメージの元のmetaData、そのmoそして最終的な出力を計算します。
最終的な出力は、私が何をしても、変更された値をスティックすることができないためです。
いくつかの非常に具体的なフォーマットがありますか? iOSで変更内容を削除するのはなぜですか? これらの追加値を追加するには何が必要ですか?彼らは.headerにリストされており、簡単に受け入れられるべきだと考えられました。
「メタデータ」では、ARCが「__bridge_transfer」(または「CFBridgingRelease」)ではなく「__bridge」を使用する必要があります。君は。 –
さて、完了です。しかし、私はまだ同じ結果を得る。 –
私があなたに持っている唯一のもう一つのことは、辞書を間違って作成していることです。 'dictionary'のような便利なコンストラクタはすでに初期化されたオブジェクトを返すので、' init'をそのようなオブジェクトに送る必要はありません。 '[[... alloc] init]'、 '[... new]'、 '[NSMutableDictionary dictionary]'のいずれかを使います。私はこれが問題を解決するとは思わない、出力が正しく見えるので、それは私が見ることができる唯一の残りのバグだ。 –