SwiftUI写入Exif曝光补偿值2/3时显示异常求助
SwiftUI写入Exif曝光补偿时2/3值异常的解决方案
问题概述
使用SwiftUI结合Core Graphics写入Exif的kCGImagePropertyExifExposureBiasValue属性时,发现唯独2/3(≈0.666)这个值无法正确存储:
- 代码中设置
let expBias: Double = 2/3,写入后在Apple预览、照片应用及ExifTool中显示为0.5或1/2 - 类似分数如
5/3(≈1.666)能正常显示为1.667或5/3 - 调试输出的
CleanupRecodeProperties日志与该问题无关,属于ImageIO内部日志
原因分析
Exif规范中,ExposureBiasValue字段的类型是SRational(有符号有理分数),即存储为「分子/分母」的整数对,而非直接存储浮点数。当传入Double类型的2/3时:
2/3无法用有限二进制浮点数精确表示,其Double值是一个无限循环的近似值(≈0.6666666666666666)- Core Graphics的
CGImageDestination在将这个近似Double转换为SRational时,出现了错误的近似映射,最终存储为1/2 - 而
5/3的Double近似值在转换时,系统能正确匹配到5/3的有理分数表示,因此显示正常
解决方案
直接传入分子和分母组成的Int32数组来表示有理分数,绕过Double转换的精度问题:
修改writeExifFunction中的赋值代码:
public func writeExifFunction(_ directoryURLS: [URL]) { for (index, _) in directoryURLS.enumerated() { var exifDictionary: [CFString: Any] = [:] // 用[分子, 分母]的Int32数组替代Double exifDictionary[kCGImagePropertyExifExposureBiasValue] = [2, 3] as [Int32] var exifData: [CFString: Any] = [:] exifData[kCGImagePropertyExifDictionary] = exifDictionary let imageURL = directoryURLS[index] addEXIFDataToImage(imageURL: imageURL, exifData: exifData) } }
验证结果
使用上述方式赋值后:
- Apple预览、照片应用会显示
0.7或2/3(取决于应用的显示逻辑) - ExifTool会直接读取到
2/3的有理分数值,显示为0.666667或2/3
补充说明
- 对于其他需要精确表示的分数曝光补偿值(如
-2/3、1/3等),都建议使用这种「Int32数组」的方式赋值 - 调试输出的
CleanupRecodeProperties日志是ImageIO处理图片时的内部信息,与曝光补偿的写入问题无关,可忽略
内容的提问来源于stack exchange,提问作者miothethis
相关产品推荐
相关产品推荐

