如何创建Display P3颜色的去饱和版本?

时间:2017-03-31 14:33:30

标签: rgb uicolor color-space hsb

我有color UIColor(displayP3Red: 1, green: 0, blue: 0.8, alpha: 1)。我想创建一个去饱和版本 - 具有相同的色调和亮度,但饱和度较低,如原始饱和度的一半。我该怎么做?

2 个答案:

答案 0 :(得分:0)

鉴于您可以计算DCI-P3的归一化主矩阵(NPM),它应该是直截了当的:NPM的中间行代表亮度因子。我将使用Colour来说明这一点,它假设您使用的是线性值:

import numpy as np
import colour

# Computing the sRGB Luminance Equation, you should be familiar with the 
# resulting Luminance factors.
print(colour.RGB_luminance_equation(
    colour.sRGB_COLOURSPACE.primaries, 
    colour.sRGB_COLOURSPACE.whitepoint))
# Y = 0.212639005872(R) + 0.715168678768(G) + 0.0721923153607(B)

# Computing the DCI-P3 Luminance Equation.
print(colour.RGB_luminance_equation(
    colour.DCI_P3_COLOURSPACE.primaries, 
    colour.DCI_P3_COLOURSPACE.whitepoint))
# Y = 0.209491677913(R) + 0.721595254161(G) + 0.0689130679262(B)

# Computing Luminance of given RGB colour, this is assuming it is representing linear values.
DCI_P3_LUMINANCE_FACTORS = np.array([0.209491677913, 0.721595254161, 0.0689130679262])
RGB = np.array([1.0, 0.0, 0.8])
Y = np.dot(RGB, DCI_P3_LUMINANCE_FACTORS)
print(Y)
# 0.264622132254

如果 Y 代表您给定颜色的亮度,如果您想以50%去饱和,那么您可以做类似的事情:

  

lerp(RGB,[Y,Y,Y],0.5)

答案 1 :(得分:0)

extension UIColor {    
  // Calling this with 0.5 as argument returns a color whose saturation is 50% of that of the receiver.
  func desaturatedBy(fraction: CGFloat) -> UIColor {
    var hue: CGFloat = 0
    var saturation: CGFloat = 0
    var brightness: CGFloat = 0
    var alpha: CGFloat = 0
    let success = getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
    assert(success)

    saturation *= fraction

    return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
  }
}

这是因为getter在扩展的sRGB颜色空间中返回HSB,而UIColor的初始化器也在扩展的sRGB颜色空间中返回HSB。因此,我们不需要进行任何色彩空间转换。