Самый простой и точный способ сделать это - преобразовать в 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