我正在尝试将自己的一些字段附加到我捕获的图像上。我似乎能够更改现有的EXIF条目,但我无法在EXIF字典中添加新条目,也不能添加到图像中的单独字典。当我添加时,我可以将它们视为图像数据的一部分,但它们永远不会保存到图像文件中。但是,当我更改现有的EXIF条目时,这些条目会保存到图像文件中。
我已经研究过:
这是我的代码:
CMAttachmentMode attachmentMode;
CFDictionaryRef exifDict = CMGetAttachment(imageDataSampleBuffer, (CFStringRef) @"{Exif}", &attachmentMode);
NSMutableDictionary *exifMutableDict = [((__bridge NSDictionary*)exifDict) mutableCopy];
[exifMutableDict setObject: @"MyApp" forKey:@"AppName"];
[exifMutableDict setObject:lockedDate forKey:@"CaptureDate"];
[exifMutableDict setObject:@(55555) forKey:@"MeteringMode"];
[exifMutableDict setObject:@"Peach" forKey:@"LensMake"];
CFMutableDictionaryRef newCFDict = (__bridge CFMutableDictionaryRef)exifMutableDict;
CMSetAttachment(imageDataSampleBuffer, (CFStringRef) @"{Exif}", newCFDict, attachmentMode);
NSMutableDictionary *anotherMutableDict = @{}.mutableCopy;
[anotherMutableDict setObject: @"MyApp" forKey:@"AppName"];
[anotherMutableDict setObject:lockedDate forKey:@"CaptureDate"];
[anotherMutableDict setObject:@(55555) forKey:@"MeteringMode"];
[anotherMutableDict setObject:@"Peach" forKey:@"Lens Make"];
CMSetAttachment(imageDataSampleBuffer, (CFStringRef) @"another", (__bridge CFMutableDictionaryRef)anotherMutableDict, kCMAttachmentMode_ShouldPropagate);
NSLog(@"metadata: %@ mutable dict %@, another %@", imageDataSampleBuffer, newCFDict, anotherMutableDict);
imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
我成功获得了EXIF字典。我添加了几个字段AppName
和CaptureDate
,然后修改了两个现有字段MeteringMode
和LensMake
。
我将此修改后的EXIF字典添加到imageDataSampleBuffer
。
我还创建了一个新词典,以防EXIF词典以某种方式限制新增加anotherMutableDict
并将其添加到imageDataSampleBuffer
。
然后我获取JPEG表示并将其写入沙盒中的文件。
当我使用图像编辑应用程序查看生成的图像时,包括Photoshop,Preview和Pixelmator,我看到了这些变化:
LensMake = Peach MeteringMode = 55555
我没有看到EXIF的其他添加内容,也没有看到另一个字典。
我还尝试完全移除EXIF并将其替换为另一个,唯一的影响是生成的文件具有明显更小的EXIF而没有任何添加,只有更改。
我不知道发生了什么。有谁看到我做错了什么?
这是NSLog语句的完整输出。正如您所看到的,更改和添加内容清晰地反映在EXIF词典中,并且还与添加到imageDataSampleBuffer的另一个词典挂起。然而,没有一个添加成为最终保存的文件,我只看到对现有字段的更改。
2015-02-09 12:18:42.960 MyApp[1720:209034] metadata: CMSampleBuffer 0x15cd2a060 retainCount: 1 allocator: 0x1991dfc80
invalid = NO
dataReady = YES
makeDataReadyCallback = 0x0
makeDataReadyRefcon = 0x0
buffer-level attachments:
another (P) = {
AppName = MyApp;
CaptureDate = "2015-02-09 20:18:25 +0000";
"Lens Make" = Peach;
MeteringMode = 55555;
}
Orientation(P) = 6
{Exif} (P) = <CFBasicHash 0x171479200 [0x1991dfc80]>{type = mutable dict, count = 24,
entries =>
0 : <CFString 0x100163398 [0x1991dfc80]>{contents = "MeteringMode"} = <CFNumber 0xb0000000000d9032 [0x1991dfc80]>{value = +55555, type = kCFNumberSInt32Type}
1 : <CFString 0x1001633d8 [0x1991dfc80]>{contents = "LensMake"} = <CFString 0x1001633b8 [0x1991dfc80]>{contents = "Peach"}
3 : <CFString 0x1992e4fa0 [0x1991dfc80]>{contents = "BrightnessValue"} = <CFNumber 0x17423b620 [0x1991dfc80]>{value = +3.50483639710326944083, type = kCFNumberFloat64Type}
4 : <CFString 0x100163358 [0x1991dfc80]>{contents = "AppName"} = <CFString 0x100163338 [0x1991dfc80]>{contents = "MyApp"}
6 : <CFString 0x19950b368 [0x1991dfc80]>{contents = "FNumber"} = <CFNumber 0x174223b00 [0x1991dfc80]>{value = +2.20000000000000017764, type = kCFNumberFloat64Type}
7 : <CFString 0x19950b688 [0x1991dfc80]>{contents = "FocalLength"} = <CFNumber 0x1742295c0 [0x1991dfc80]>{value = +4.15000000000000035527, type = kCFNumberFloat64Type}
8 : <CFString 0x19950b568 [0x1991dfc80]>{contents = "ShutterSpeedValue"} = <CFNumber 0x1742386e0 [0x1991dfc80]>{value = +4.90764099214979498953, type = kCFNumberFloat64Type}
9 : <CFString 0x19950b908 [0x1991dfc80]>{contents = "SceneType"} = <CFNumber 0xb000000000000012 [0x1991dfc80]>{value = +1, type = kCFNumberSInt32Type}
10 : <CFString 0x19950b588 [0x1991dfc80]>{contents = "ApertureValue"} = <CFNumber 0x17423c080 [0x1991dfc80]>{value = +2.27500704749987026076, type = kCFNumberFloat64Type}
11 : <CFString 0x19950b6a8 [0x1991dfc80]>{contents = "SubjectArea"} = <CFArray 0x174443720 [0x1991dfc80]>{type = mutable-small, count = 4, values = (
0 : <CFNumber 0xb0000000000065f1 [0x1991dfc80]>{value = +1631, type = kCFNumberSInt16Type}
1 : <CFNumber 0xb000000000004c71 [0x1991dfc80]>{value = +1223, type = kCFNumberSInt16Type}
2 : <CFNumber 0xb000000000007031 [0x1991dfc80]>{value = +1795, type = kCFNumberSInt16Type}
3 : <CFNumber 0xb000000000004351 [0x1991dfc80]>{value = +1077, type = kCFNumberSInt16Type}
)}
17 : <CFString 0x19950bb28 [0x1991dfc80]>{contents = "LensSpecification"} = <CFArray 0x174245760 [0x1991dfc80]>{type = mutable-small, count = 4, values = (
0 : <CFNumber 0x17423bba0 [0x1991dfc80]>{value = +4.15000000000000035527, type = kCFNumberFloat64Type}
1 : <CFNumber 0x17423a0e0 [0x1991dfc80]>{value = +4.15000000000000035527, type = kCFNumberFloat64Type}
2 : <CFNumber 0x174232900 [0x1991dfc80]>{value = +2.20000000000000017764, type = kCFNumberFloat64Type}
3 : <CFNumber 0x174235560 [0x1991dfc80]>{value = +2.20000000000000017764, type = kCFNumberFloat64Type}
)}
18 : <CFString 0x19950b7c8 [0x1991dfc80]>{contents = "PixelYDimension"} = <CFNumber 0xb000000000009902 [0x1991dfc80]>{value = +2448, type = kCFNumberSInt32Type}
19 : <CFString 0x19950b988 [0x1991dfc80]>{contents = "WhiteBalance"} = <CFNumber 0xb000000000000002 [0x1991dfc80]>{value = +0, type = kCFNumberSInt32Type}
22 : <CFString 0x100163378 [0x1991dfc80]>{contents = "CaptureDate"} = 2015-02-09 20:18:25 +0000
28 : <CFString 0x19950b3c8 [0x1991dfc80]>{contents = "ISOSpeedRatings"} = <CFArray 0x174249b70 [0x1991dfc80]>{type = mutable-small, count = 1, values = (
0 : <CFNumber 0xb000000000000401 [0x1991dfc80]>{value = +64, type = kCFNumberSInt16Type}
)}
29 : <CFString 0x19950b968 [0x1991dfc80]>{contents = "ExposureMode"} = <CFNumber 0xb000000000000002 [0x1991dfc80]>{value = +0, type = kCFNumberSInt32Type}
31 : <CFString 0x19950b7a8 [0x1991dfc80]>{contents = "PixelXDimension"} = <CFNumber 0xb00000000000cc02 [0x1991dfc80]>{value = +3264, type = kCFNumberSInt32Type}
32 : <CFString 0x19950bb68 [0x1991dfc80]>{contents = "LensModel"} = <CFString 0x17446a940 [0x1991dfc80]>{contents = "iPhone 6 back camera 4.15mm f/2.2"}
34 : <CFString 0x19950b388 [0x1991dfc80]>{contents = "ExposureProgram"} = <CFNumber 0xb000000000000022 [0x1991dfc80]>{value = +2, type = kCFNumberSInt32Type}
35 : <CFString 0x19950b9c8 [0x1991dfc80]>{contents = "FocalLenIn35mmFilm"} = <CFNumber 0xb0000000000001d2 [0x1991dfc80]>{value = +29, type = kCFNumberSInt32Type}
36 : <CFString 0x1992e3420 [0x1991dfc80]>{contents = "ExposureTime"} = <CFNumber 0x17423b540 [0x1991dfc80]>{value = +0.03333333333333333287, type = kCFNumberFloat64Type}
37 : <CFString 0x19950b668 [0x1991dfc80]>{contents = "Flash"} = <CFNumber 0xb000000000000102 [0x1991dfc80]>{value = +16, type = kCFNumberSInt32Type}
38 : <CFString 0x19950b8c8 [0x1991dfc80]>{contents = "SensingMethod"} = <CFNumber 0xb000000000000022 [0x1991dfc80]>{value = +2, type = kCFNumberSInt32Type}
40 : <CFString 0x19950b5c8 [0x1991dfc80]>{contents = "ExposureBiasValue"} = <CFNumber 0x17422a8a0 [0x1991dfc80]>{value = +0.0, type = kCFNumberFloat64Type}
}
{MakerApple}(P) = <CFBasicHash 0x174468500 [0x1991dfc80]>{type = mutable dict, count = 10,
entries =>
0 : <CFString 0x1992dfd60 [0x1991dfc80]>{contents = "7"} = <CFNumber 0xb000000000000012 [0x1991dfc80]>{value = +1, type = kCFNumberSInt32Type}
1 : <CFString 0x1992dfce0 [0x1991dfc80]>{contents = "3"} = <CFBasicHash 0x174474e40 [0x1991dfc80]>{type = mutable dict, count = 4,
entries =>
0 : <CFString 0x1992dcb80 [0x1991dfc80]>{contents = "flags"} = <CFNumber 0xb000000000000012 [0x1991dfc80]>{value = +1, type = kCFNumberSInt32Type}
1 : <CFString 0x1992dcb20 [0x1991dfc80]>{contents = "value"} = <CFNumber 0xb00371370a6edbd3 [0x1991dfc80]>{value = +60556633894333, type = kCFNumberSInt64Type}
4 : <CFString 0x1992dcb40 [0x1991dfc80]>{contents = "timescale"} = <CFNumber 0xb0000003b9aca002 [0x1991dfc80]>{value = +1000000000, type = kCFNumberSInt32Type}
5 : <CFString 0x1992dcb60 [0x1991dfc80]>{contents = "epoch"} = <CFNumber 0xb000000000000003 [0x1991dfc80]>{value = +0, type = kCFNumberSInt64Type}
}
3 : <CFString 0x1992dfd80 [0x1991dfc80]>{contents = "8"} = <CFArray 0x1742541c0 [0x1991dfc80]>{type = mutable-small, count = 3, values = (
0 : <CFNumber 0x1742371e0 [0x1991dfc80]>{value = -0.0552164577, type = kCFNumberFloat32Type}
1 : <CFNumber 0x17423bf60 [0x1991dfc80]>{value = -0.0018360948, type = kCFNumberFloat32Type}
2 : <CFNumber 0x17423c000 [0x1991dfc80]>{value = -0.9881702065, type = kCFNumberFloat32Type}
)}
4 : <CFString 0x1992dfd00 [0x1991dfc80]>{contents = "4"} = <CFNumber 0xb000000000000012 [0x1991dfc80]>{value = +1, type = kCFNumberSInt32Type}
5 : <CFString 0x1992dfe40 [0x1991dfc80]>{contents = "14"} = <CFNumber 0xb000000000000002 [0x1991dfc80]>{value = +0, type = kCFNumberSInt32Type}
6 : <CFString 0x1992dfda0 [0x1991dfc80]>{contents = "9"} = <CFNumber 0xb000000000001132 [0x1991dfc80]>{value = +275, type = kCFNumberSInt32Type}
7 : <CFString 0x1992dfd20 [0x1991dfc80]>{contents = "5"} = <CFNumber 0xb000000000000c82 [0x1991dfc80]>{value = +200, type = kCFNumberSInt32Type}
8 : <CFString 0x1992dfca0 [0x1991dfc80]>{contents = "1"} = <CFNumber 0xb000000000000022 [0x1991dfc80]>{value = +2, type = kCFNumberSInt32Type}
10 : <CFString 0x1992dfd40 [0x1991dfc80]>{contents = "6"} = <CFNumber 0xb000000000000c42 [0x1991dfc80]>{value = +196, type = kCFNumberSInt32Type}
11 : <CFString 0x1992dfcc0 [0x1991dfc80]>{contents = "2"} = <CFData 0x15cd0f070 [0x1991dfc80]>{length = 512, capacity = 512, bytes = 0x4c013801250113010101f100e100d300 ... 8d0084007b007300}
}
formatDescription = <CMVideoFormatDescription 0x174249c90 [0x1991dfc80]> {
mediaType:'vide'
mediaSubType:'jpeg'
mediaSpecific: {
codecType: 'jpeg' dimensions: 3264 x 2448
}
extensions: {(null)}
}
sbufToTrackReadiness = 0x0
numSamples = 1
sampleTimingArray[1] = {
{PTS = {60556633894333/1000000000 = 60556.634}, DTS = {INVALID}, duration = {INVALID}},
}
sampleSizeArray[1] = {
sampleSize = 1301228,
}
dataBuffer = 0x174301290
mutable dict {
ApertureValue = "2.27500704749987";
AppName = MyApp;
BrightnessValue = "3.504836397103269";
CaptureDate = "2015-02-09 20:18:25 +0000";
ExposureBiasValue = 0;
ExposureMode = 0;
ExposureProgram = 2;
ExposureTime = "0.03333333333333333";
FNumber = "2.2";
Flash = 16;
FocalLenIn35mmFilm = 29;
FocalLength = "4.15";
ISOSpeedRatings = (
64
);
LensMake = Peach;
LensModel = "iPhone 6 back camera 4.15mm f/2.2";
LensSpecification = (
"4.15",
"4.15",
"2.2",
"2.2"
);
MeteringMode = 55555;
PixelXDimension = 3264;
PixelYDimension = 2448;
SceneType = 1;
SensingMethod = 2;
ShutterSpeedValue = "4.907640992149795";
SubjectArea = (
1631,
1223,
1795,
1077
);
WhiteBalance = 0;
}, another {
AppName = MyApp;
CaptureDate = "2015-02-09 20:18:25 +0000";
"Lens Make" = Peach;
MeteringMode = 55555;
}