iOS 色温和白平衡设置 / 2020-05-12

白平衡是摄影领域一项很重要的设置技巧,正确的理解白平衡和色温等知识将有助于拍摄出效果更好的作品。iOS中提供了非常便捷的API帮助我们进行白平衡的设置。

色温的基本概念

色温的单位是开尔文。开尔文(Kelvins),是热力学温标或绝对温标,使用符号K表示。与我们常用的摄氏温度不同,开尔文是以绝对零度作为计算起点,即-273.15℃=0K,温度每增加1℃,开尔文温度增加1K。在天文学和物理学中,常常使用开尔文作为标准的温度计量单位。

色温是表示光线中包含颜色成分的一个计量单位。假设有一黑体物质,能够将落在其上的能量全部吸收且这些能量都以光的形式释放出来,它就会随着温度升高变成不同的颜色,由黑变红、转黄、发白,最后发出蓝色光。关于黑体(blackbody)在不同温度下的颜色,可以参考:What color is a blackbody?

与我们平时认知的”红色是暖色,蓝色是冷色“不同,色温表现恰恰相反:颜色越红色温越低,颜色越蓝色温越高。类比到天文上,如果我们看到一颗星星颜色偏蓝,那么它表面的温度一定比颜色偏红的星星温度要高。

白平衡的作用

色温会影响到物体本来的颜色。比如当晴朗天气的傍晚,太阳颜色偏红色温偏低,此时照射到人脸上会让人脸变红。如果不加处理,拍摄出来的效果就会失去事物本来的颜色。白平衡就是将在不同环境不同色温中的物体还原成它本来的颜色,具体一点就是根据环境变化修改图片R、G、B通道增益值。

iOS的白平衡设置

从iOS8开始,iOS系统支持原生API调节相机白平衡效果,具体接口由AVCaptureDevice类提供。

whiteBalanceMode

var whiteBalanceMode: AVCaptureDevice.WhiteBalanceMode
//当前白平衡模式,取值有:
public enum WhiteBalanceMode : Int { 
	//手动修改白平衡值
	case locked = 0
	//要求设备根据当前环境自动调节白平衡一次
	case autoWhiteBalance = 1
	//要求设备根据当前环境实时调节白平衡
	case continuousAutoWhiteBalance = 2
}

WhiteBalanceGains

白平衡R、G、B通道的增益值,也是用于配置白平衡的结构体。

public struct WhiteBalanceGains {
    public var redGain: Float
    public var greenGain: Float
    public var blueGain: Float
    ...
}

redGain、greenGain、blueGain这三个通道增益值,其取值在1.0-maxWhiteBalanceGain之间,其中maxWhiteBalanceGain是一个和设备有关的值,表示支持的最大增益值。

WhiteBalanceGains结构转换

有两个转换为WhiteBalanceGains结构的API:

//通过色温值结构转换:WhiteBalanceTemperatureAndTintValues
open func deviceWhiteBalanceGains(for tempAndTintValues: AVCaptureDevice.WhiteBalanceTemperatureAndTintValues) -> AVCaptureDevice.WhiteBalanceGains
//通过CIE 1931色度图坐标结构转换:WhiteBalanceChromaticityValues
open func deviceWhiteBalanceGains(for chromaticityValues: AVCaptureDevice.WhiteBalanceChromaticityValues) -> AVCaptureDevice.WhiteBalanceGains

设置WhiteBalanceGains

open func setWhiteBalanceModeLocked(with whiteBalanceGains: AVCaptureDevice.WhiteBalanceGains, completionHandler handler: ((CMTime) -> Void)? = nil)

需要保证whiteBalanceGains参数的各个通道增益在1.0-maxWhiteBalanceGain之间,相机的白平衡模式设置为AVCaptureWhiteBalanceModeLocked。setWhiteBalanceModeLocked将按照FIFO的顺序完成调用block中的代码,回调中的CMTime标识应用了该设置后的第一帧图像的时间戳。

一个典型的设置示例:

if self.videoDevice.isLockingWhiteBalanceWithCustomDeviceGainsSupported {
    try? self.videoDevice.lockForConfiguration()
    
    let temperatureAndTintValues = AVCaptureDevice.WhiteBalanceTemperatureAndTintValues(temperature: temperature, tint: tint)
    let whiteBalanceGains = self.videoDevice.deviceWhiteBalanceGains(for: temperatureAndTintValues)
    
    //fix 1.0-maxWhiteBalanceGain
    let maxWhiteBalanceGain = self.videoDevice.maxWhiteBalanceGain
    var fixWhiteBalanceGains = whiteBalanceGains
    fixWhiteBalanceGains.redGain = max(1.0, min(maxWhiteBalanceGain, whiteBalanceGains.redGain))
    fixWhiteBalanceGains.greenGain = max(1.0, min(maxWhiteBalanceGain, whiteBalanceGains.greenGain))
    fixWhiteBalanceGains.blueGain = max(1.0, min(maxWhiteBalanceGain, whiteBalanceGains.blueGain))
    
    self.videoDevice.setWhiteBalanceModeLocked(with: fixWhiteBalanceGains) { (time) in
    }
    self.videoDevice.unlockForConfiguration()
}

在这个例子中,采用的由色温色度值转换为WhiteBalanceGains结构,会反映在RGB各个通道的增益值变化。

获取当前的白平衡配置

let whiteBalanceGains = self.videoDevice.deviceWhiteBalanceGains
let temperatureAndTintValues = self.videoDevice.temperatureAndTintValues(for: whiteBalanceGains)
let temperature = temperatureAndTintValues.temperature
let tint = temperatureAndTintValues.tint

WhiteBalanceTemperatureAndTintValues的temperature即表示开尔文温度,取值一般在1000k-30000k之间;tint表示色度值,取值范围-150-150,越低越偏蓝,越高越偏红。

其它文章

iOS APP灰度发布方案
iOS Universal Links
iOS Asset Catalog and Bundle
iOS Appium自动化测试框架原理简析