最简单、最准确的方法是转换为 sRGB,将亮度设置为最大值,然后再转换回 XYZ。转换为 sRGB 时,您必须确保为 Y 选择一个值,该值将在任何点 x,y 的色域内给出结果(它必须低于最小相对亮度系数,对于 sRGB,蓝色为 ≃ 0.072)。请注意,这不会检查点 x,y 是否在色域内:
#include <Math.au3>
;XYZtosRGB
Global $RsRGB[3] = [3.2409699, -1.5373832, -0.4986108]
Global $GsRGB[3] = [-0.9692436, 1.8759675, 0.0415551]
Global $BsRGB[3] = [0.0556301, -0.203977, 1.0569715]
;sRGBtoXYZ
Global $XsRGB[3] = [0.4123908, 0.3575843, 0.1804808]
Global $YsRGB[3] = [0.212639, 0.7151687, 0.0721923]
Global $ZsRGB[3] = [0.0193308, 0.1191948, 0.9505322]
Global $Wx = 0.3127, $Wy = 0.3290
Func DP($T, $S)
return $T[0] * $S[0] + $T[1] * $S[1] + $T[2] * $S[2]
EndFunc
Func xyYtoXYZ($xyY)
Local $XYZ = $xyY
If $xyY[2] <> 0 Then
$XYZ[0] = $xyY[0] * $xyY[2] / $xyY[1]
$XYZ[2] = $xyY[2] * (1 - $xyY[0] - $xyY[1]) / $xyY[1]
Else
$XYZ[0] = 0
$XYZ[2] = 0
EndIf
$XYZ[1] = $xyY[2]
Return $XYZ
EndFunc
Func FindY($x, $y)
Local $xyY = [$x, $y, 0.07]
Local $XYZ = xyYtoXYZ($xyY)
Local $sRGBin = [DP($RsRGB, $XYZ), DP($GsRGB, $XYZ), DP($BsRGB, $XYZ)]
Local $inc = _Min(_Min(1 / $RGBin[0], 1 / $RGBin[1]), 1 / $RGBin[2])
Local $sRGBout = [$sRGBin[0] * $inc, $sRGBin[1] * $inc, $sRGBin[2] * $inc]
Return DP($YsRGB, $sRGBout)
EndFunc