Geänderte EXIF-Daten werden nicht richtig gespeichert
Nach unzähligen Versuchen und dem Durchsuchen jedes SO answer + google-Ergebnisses ist es mir ein Rätsel, dass die Arbeit mit EXIF unter iOS so frustrierend ist.
Unten sehen Sie den Arbeitscode mit den Ergebnissen.
[[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);
}];
Welche Ausgaben dies:
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;
};
}
Und das:
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;
};
}
Und nachdem alles erledigt ist, gilt Folgendes:
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;
};
}
Wie das Beispiel zeigt, können Sie die ursprünglichen Metadaten des Bildes, seine Änderung und dann seine endgültige Ausgabe sehen.
Die endgültige Ausgabe ist das, was mich stört, denn egal was ich tue, ich kann meine geänderten Werte nicht zum Festhalten bringen!
Gibt es ein bestimmtes Format, das mir fehlt? Warum entfernt iOS meine Änderungen? Was muss ich tun, um diese zusätzlichen Werte hinzuzufügen? Sie sind in der .header-Datei aufgeführt und finden, dass sie leicht akzeptiert werden sollten.