iOS 用前置摄像头闪光灯的新值覆盖 EXIF 闪光灯 属性
iOS overwrite EXIF flash property with new value for front camera flash
我正在尝试更改 Exif 词典的 kCGImagePropertyExifFlash
属性。我的应用程序提供前置闪光灯模式,因此我正在尝试更改此 Exif 值。当我使用 ALAssetsLibrary
的 writeImageDataToSavedPhotosAlbum
方法保存 newImageData
时,无论我做什么,它都会删除我设置的值。
如果能提供任何帮助,我将不胜感激。
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:
[self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo]
completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
if (imageSampleBuffer && !error)
{
CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL, imageSampleBuffer, kCMAttachmentMode_ShouldPropagate);
NSDictionary *metadata = [NSDictionary dictionaryWithDictionary:(__bridge NSDictionary *)metadataDict];
CFRelease(metadataDict);
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
if (metadata && imageData)
{
NSMutableDictionary *newMetaData = [NSMutableDictionary dictionaryWithDictionary:metadata];
NSMutableDictionary *exifMetadata = [NSMutableDictionary dictionaryWithDictionary:
[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary]];
if (self.isUsingFrontCamera && exifMetadata)
{
if (self.flashButton.flashMode == On)
{
[exifMetadata setObject:@"On, Fired" forKey:(NSString *)kCGImagePropertyExifFlash];
}
else if (self.flashButton.flashMode == Off)
{
[exifMetadata setObject:@"Off, did not fire" forKey:(NSString *)kCGImagePropertyExifFlash];
}
else if (self.frontFlashAutoDidFire)
{
[exifMetadata setObject:@"Auto, Fired" forKey:(NSString *)kCGImagePropertyExifFlash];
}
}
[newMetaData setObject:exifMetadata forKey:(NSString *)kCGImagePropertyExifDictionary];
NSData *newImageData = [self writeMetadataIntoImageData:imageData metadata:newMetaData];
[ALAssetsLibrary.new writeImageDataToSavedPhotosAlbum:newImageData metadata:nil completionBlock:nil];
}
}
}
- (NSData *)writeMetadataIntoImageData:(NSData *)imageData metadata:(NSDictionary *)metadata
{
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL);
CFStringRef UTI = CGImageSourceGetType(source);
NSMutableData *data = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)data, UTI, 1, NULL);
CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef) metadata);
CGImageDestinationFinalize(destination);
CFRelease(destination);
CFRelease(source);
return data;
}
我明白了;结果 kCGImagePropertyExifFlash
是 NSCFNumber
,而不是 NSCFString
,这是我的问题。我能够记录闪光灯模式的默认整数值:
- On, Fired 值为 9
- 关,没火是16的值
- 自动,不开火是24的值
- Auto, Fired 的值为 25
- 如果硬件设备不支持闪存,则值为 32
- 不确定任何其他可能的值,可能与闪光灯太热时无法使用有关。
代码:
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:
[self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo]
completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
if (imageSampleBuffer && !error)
{
CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL, imageSampleBuffer, kCMAttachmentMode_ShouldPropagate);
NSDictionary *metadata = [NSDictionary dictionaryWithDictionary:(__bridge NSDictionary *)metadataDict];
CFRelease(metadataDict);
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
if (metadata && imageData)
{
NSMutableDictionary *newMetaData = [NSMutableDictionary dictionaryWithDictionary:metadata];
NSMutableDictionary *exifMetadata = [NSMutableDictionary dictionaryWithDictionary:
[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary]];
if (self.isUsingFrontCamera && exifMetadata)
{
if (self.flashButton.flashMode == On)
{
[exifMetadata setObject:@(9) forKey:(NSString *)kCGImagePropertyExifFlash];
}
else if (self.flashButton.flashMode == Off)
{
[exifMetadata setObject:@(16) forKey:(NSString *)kCGImagePropertyExifFlash];
}
else if (self.flashButton.flashMode == Auto)
{
[exifMetadata setObject:@(24) forKey:(NSString *)kCGImagePropertyExifFlash];
if (self.frontFlashAutoDidFire)
{
[exifMetadata setObject:@(25) forKey:(NSString *)kCGImagePropertyExifFlash];
}
}
}
[newMetaData setObject:exifMetadata forKey:(NSString *)kCGImagePropertyExifDictionary];
[ALAssetsLibrary.new writeImageDataToSavedPhotosAlbum:imageData metadata:newMetaData completionBlock:nil];
}
}
}
当我 运行 在使用相机开发 iOS 应用程序时遇到同样的问题,我查找了一些典型的 EXIF 密钥及其标准 t运行 格式。
这是 EXIF flash 属性 描述:
IFD Exif
Code 37385 (hex 0x9209)
Name Flash
描述
Indicates the status of flash when the image was shot.
Bit 0 indicates the flash firing status, bits 1 and 2 indicate the flash return status, bits 3 and 4 indicate the flash mode, bit 5 indicates whether the flash function is present, and bit 6 indicates "red eye" mode.
Values for bit 0 indicating whether the flash fired.
0 = Flash did not fire
1 = Flash fired
Values for bits 1 and 2 indicating the status of returned light.
00 = No strobe return detection function
01 = reserved
10 = Strobe return light not detected
11 = Strobe return light detected
Values for bits 3 and 4 indicating the camera's flash mode.
00 = unknown
01 = Compulsory flash firing
10 = Compulsory flash suppression
11 = Auto mode
Values for bit 5 indicating the presence of a flash function.
0 = Flash function present
1 = No flash function
Values for bit 6 indicating the camera's red-eye mode.
0 = No red-eye reduction mode or unknown
1 = Red-eye reduction supported
Not all combinations make sense though. The specification defines these combined values:
hex 0000 = Flash did not fire
hex 0001 = Flash fired
hex 0005 = Strobe return light not detected
hex 0007 = Strobe return light detected
hex 0009 = Flash fired, compulsory flash mode
hex 000D = Flash fired, compulsory flash mode, return light not detected
hex 000F = Flash fired, compulsory flash mode, return light detected
hex 0010 = Flash did not fire, compulsory flash mode
hex 0018 = Flash did not fire, auto mode
hex 0019 = Flash fired, auto mode
hex 001D = Flash fired, auto mode, return light not detected
hex 001F = Flash fired, auto mode, return light detected
hex 0020 = No flash function
hex 0041 = Flash fired, red-eye reduction mode
hex 0045 = Flash fired, red-eye reduction mode, return light not detected
hex 0047 = Flash fired, red-eye reduction mode, return light detected
hex 0049 = Flash fired, compulsory flash mode, red-eye reduction mode
hex 004D = Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected
hex 004F = Flash fired, compulsory flash mode, red-eye reduction mode, return light detected
hex 0059 = Flash fired, auto mode, red-eye reduction mode
hex 005D = Flash fired, auto mode, return light not detected, red-eye reduction mode
hex 005F = Flash fired, auto mode, return light detected, red-eye reduction mode
使用十六进制到十进制的转换和 objective-C,这里有一个方法来 t运行slate 调用 :
给出的枚举
[[exifDictionary objectForKey : @"Flash"] integerValue]
进入NSString描述
-(NSString *) translateFlashEnumToNSString: (long) flash
{
switch (flash) {
case 0:
return @"Flash did not fire";
case 1:
return @"Flash did fire";
case 5:
return @"Strobe return light not detected";
case 7:
return @"Strobe return light detected";
case 9:
return @"Flash fired, compulsory flash mode";
case 13:
return @"Flash fired, compulsory flash mode, return light not detected";
case 15:
return @"Flash fired, compulsory flash mode, return light detected";
case 16:
return @"Flash did not fire, compulsory flash mode";
case 24:
return @"Flash did not fire, auto mode";
case 25:
return @"Flash fired, auto mode";
case 29:
return @"Flash fired, auto mode, return light not detected";
case 31:
return @"Flash fired, auto mode, return light detected";
case 32:
return @"No flash function";
case 65:
return @"Flash fired, red-eye reduction mode";
case 69:
return @"Flash fired, red-eye reduction mode, return light not detected";
case 71:
return @"Flash fired, red-eye reduction mode, return light detected";
case 73:
return @"Flash fired, compulsory flash mode, red-eye reduction mode";
case 77:
return @"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected";
case 79:
return @"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected";
case 89:
return @"Flash fired, auto mode, red-eye reduction mode";
case 93:
return @"Flash fired, auto mode, return light not detected, red-eye reduction mode";
case 95:
return @"Flash fired, auto mode, return light detected, red-eye reduction mode";
default:
return @"Flash mode unsupported";
}
}
调用方法:
NSLog(@"Flash EXIF : %@", [self translateFlashEnumToNSString: [[exifDictionary objectForKey:@"Flash"] integerValue]];
希望对您有所帮助。
对于其他 EXIF 密钥及其描述:http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif/flash.html
我正在尝试更改 Exif 词典的 kCGImagePropertyExifFlash
属性。我的应用程序提供前置闪光灯模式,因此我正在尝试更改此 Exif 值。当我使用 ALAssetsLibrary
的 writeImageDataToSavedPhotosAlbum
方法保存 newImageData
时,无论我做什么,它都会删除我设置的值。
如果能提供任何帮助,我将不胜感激。
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:
[self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo]
completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
if (imageSampleBuffer && !error)
{
CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL, imageSampleBuffer, kCMAttachmentMode_ShouldPropagate);
NSDictionary *metadata = [NSDictionary dictionaryWithDictionary:(__bridge NSDictionary *)metadataDict];
CFRelease(metadataDict);
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
if (metadata && imageData)
{
NSMutableDictionary *newMetaData = [NSMutableDictionary dictionaryWithDictionary:metadata];
NSMutableDictionary *exifMetadata = [NSMutableDictionary dictionaryWithDictionary:
[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary]];
if (self.isUsingFrontCamera && exifMetadata)
{
if (self.flashButton.flashMode == On)
{
[exifMetadata setObject:@"On, Fired" forKey:(NSString *)kCGImagePropertyExifFlash];
}
else if (self.flashButton.flashMode == Off)
{
[exifMetadata setObject:@"Off, did not fire" forKey:(NSString *)kCGImagePropertyExifFlash];
}
else if (self.frontFlashAutoDidFire)
{
[exifMetadata setObject:@"Auto, Fired" forKey:(NSString *)kCGImagePropertyExifFlash];
}
}
[newMetaData setObject:exifMetadata forKey:(NSString *)kCGImagePropertyExifDictionary];
NSData *newImageData = [self writeMetadataIntoImageData:imageData metadata:newMetaData];
[ALAssetsLibrary.new writeImageDataToSavedPhotosAlbum:newImageData metadata:nil completionBlock:nil];
}
}
}
- (NSData *)writeMetadataIntoImageData:(NSData *)imageData metadata:(NSDictionary *)metadata
{
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL);
CFStringRef UTI = CGImageSourceGetType(source);
NSMutableData *data = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)data, UTI, 1, NULL);
CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef) metadata);
CGImageDestinationFinalize(destination);
CFRelease(destination);
CFRelease(source);
return data;
}
我明白了;结果 kCGImagePropertyExifFlash
是 NSCFNumber
,而不是 NSCFString
,这是我的问题。我能够记录闪光灯模式的默认整数值:
- On, Fired 值为 9
- 关,没火是16的值
- 自动,不开火是24的值
- Auto, Fired 的值为 25
- 如果硬件设备不支持闪存,则值为 32
- 不确定任何其他可能的值,可能与闪光灯太热时无法使用有关。
代码:
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:
[self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo]
completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
if (imageSampleBuffer && !error)
{
CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL, imageSampleBuffer, kCMAttachmentMode_ShouldPropagate);
NSDictionary *metadata = [NSDictionary dictionaryWithDictionary:(__bridge NSDictionary *)metadataDict];
CFRelease(metadataDict);
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
if (metadata && imageData)
{
NSMutableDictionary *newMetaData = [NSMutableDictionary dictionaryWithDictionary:metadata];
NSMutableDictionary *exifMetadata = [NSMutableDictionary dictionaryWithDictionary:
[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary]];
if (self.isUsingFrontCamera && exifMetadata)
{
if (self.flashButton.flashMode == On)
{
[exifMetadata setObject:@(9) forKey:(NSString *)kCGImagePropertyExifFlash];
}
else if (self.flashButton.flashMode == Off)
{
[exifMetadata setObject:@(16) forKey:(NSString *)kCGImagePropertyExifFlash];
}
else if (self.flashButton.flashMode == Auto)
{
[exifMetadata setObject:@(24) forKey:(NSString *)kCGImagePropertyExifFlash];
if (self.frontFlashAutoDidFire)
{
[exifMetadata setObject:@(25) forKey:(NSString *)kCGImagePropertyExifFlash];
}
}
}
[newMetaData setObject:exifMetadata forKey:(NSString *)kCGImagePropertyExifDictionary];
[ALAssetsLibrary.new writeImageDataToSavedPhotosAlbum:imageData metadata:newMetaData completionBlock:nil];
}
}
}
当我 运行 在使用相机开发 iOS 应用程序时遇到同样的问题,我查找了一些典型的 EXIF 密钥及其标准 t运行 格式。
这是 EXIF flash 属性 描述:
IFD Exif
Code 37385 (hex 0x9209)
Name Flash
描述
Indicates the status of flash when the image was shot.
Bit 0 indicates the flash firing status, bits 1 and 2 indicate the flash return status, bits 3 and 4 indicate the flash mode, bit 5 indicates whether the flash function is present, and bit 6 indicates "red eye" mode.
Values for bit 0 indicating whether the flash fired.
0 = Flash did not fire
1 = Flash fired
Values for bits 1 and 2 indicating the status of returned light.
00 = No strobe return detection function
01 = reserved
10 = Strobe return light not detected
11 = Strobe return light detected
Values for bits 3 and 4 indicating the camera's flash mode.
00 = unknown
01 = Compulsory flash firing
10 = Compulsory flash suppression
11 = Auto mode
Values for bit 5 indicating the presence of a flash function.
0 = Flash function present
1 = No flash function
Values for bit 6 indicating the camera's red-eye mode.
0 = No red-eye reduction mode or unknown
1 = Red-eye reduction supported
Not all combinations make sense though. The specification defines these combined values:
hex 0000 = Flash did not fire
hex 0001 = Flash fired
hex 0005 = Strobe return light not detected
hex 0007 = Strobe return light detected
hex 0009 = Flash fired, compulsory flash mode
hex 000D = Flash fired, compulsory flash mode, return light not detected
hex 000F = Flash fired, compulsory flash mode, return light detected
hex 0010 = Flash did not fire, compulsory flash mode
hex 0018 = Flash did not fire, auto mode
hex 0019 = Flash fired, auto mode
hex 001D = Flash fired, auto mode, return light not detected
hex 001F = Flash fired, auto mode, return light detected
hex 0020 = No flash function
hex 0041 = Flash fired, red-eye reduction mode
hex 0045 = Flash fired, red-eye reduction mode, return light not detected
hex 0047 = Flash fired, red-eye reduction mode, return light detected
hex 0049 = Flash fired, compulsory flash mode, red-eye reduction mode
hex 004D = Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected
hex 004F = Flash fired, compulsory flash mode, red-eye reduction mode, return light detected
hex 0059 = Flash fired, auto mode, red-eye reduction mode
hex 005D = Flash fired, auto mode, return light not detected, red-eye reduction mode
hex 005F = Flash fired, auto mode, return light detected, red-eye reduction mode
使用十六进制到十进制的转换和 objective-C,这里有一个方法来 t运行slate 调用 :
给出的枚举[[exifDictionary objectForKey : @"Flash"] integerValue]
进入NSString描述
-(NSString *) translateFlashEnumToNSString: (long) flash
{
switch (flash) {
case 0:
return @"Flash did not fire";
case 1:
return @"Flash did fire";
case 5:
return @"Strobe return light not detected";
case 7:
return @"Strobe return light detected";
case 9:
return @"Flash fired, compulsory flash mode";
case 13:
return @"Flash fired, compulsory flash mode, return light not detected";
case 15:
return @"Flash fired, compulsory flash mode, return light detected";
case 16:
return @"Flash did not fire, compulsory flash mode";
case 24:
return @"Flash did not fire, auto mode";
case 25:
return @"Flash fired, auto mode";
case 29:
return @"Flash fired, auto mode, return light not detected";
case 31:
return @"Flash fired, auto mode, return light detected";
case 32:
return @"No flash function";
case 65:
return @"Flash fired, red-eye reduction mode";
case 69:
return @"Flash fired, red-eye reduction mode, return light not detected";
case 71:
return @"Flash fired, red-eye reduction mode, return light detected";
case 73:
return @"Flash fired, compulsory flash mode, red-eye reduction mode";
case 77:
return @"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected";
case 79:
return @"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected";
case 89:
return @"Flash fired, auto mode, red-eye reduction mode";
case 93:
return @"Flash fired, auto mode, return light not detected, red-eye reduction mode";
case 95:
return @"Flash fired, auto mode, return light detected, red-eye reduction mode";
default:
return @"Flash mode unsupported";
}
}
调用方法:
NSLog(@"Flash EXIF : %@", [self translateFlashEnumToNSString: [[exifDictionary objectForKey:@"Flash"] integerValue]];
希望对您有所帮助。 对于其他 EXIF 密钥及其描述:http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif/flash.html