如何创建 Display P3 颜色的去饱和版本?
How do I create a desaturated version of a Display P3 color?
我有一个colorUIColor(displayP3Red: 1, green: 0, blue: 0.8, alpha: 1)
。我想创建一个不饱和的版本——具有相同的色调和亮度,但饱和度较低,比如原始饱和度的一半。我该怎么做?
考虑到您可以计算 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)
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)
}
}
这是因为扩展 sRGB 颜色 space 中的 getter returns HSB,并且 UIColor 的初始化程序也采用扩展 sRGB 颜色 space 中的 HSB。所以我们不需要做任何颜色space转换。
我有一个colorUIColor(displayP3Red: 1, green: 0, blue: 0.8, alpha: 1)
。我想创建一个不饱和的版本——具有相同的色调和亮度,但饱和度较低,比如原始饱和度的一半。我该怎么做?
考虑到您可以计算 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)
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)
}
}
这是因为扩展 sRGB 颜色 space 中的 getter returns HSB,并且 UIColor 的初始化程序也采用扩展 sRGB 颜色 space 中的 HSB。所以我们不需要做任何颜色space转换。