-- code converted by Josh Chunick
-- Resources:
-- http://www.easyrgb.com/math.html
-- http://www.brucelindbloom.com/index.html?Equations.html
-- http://www.cs.rit.edu/~ncs/color/a_spaces.html
-- http://www.f4.fhtw-berlin.de/~barthel/ImageJ/ColorInspector/HTMLHelp/farbraumJava.htm
-- http://www.efg2.com/Lab/Graphics/Colors/index.html
-- http://www.nebulus.org/tutorials/2d/photoshop/color/index.html
-- convert rgb or hex colours to Director's current frame palette.
-- this is affected by the frame channel palette setting
-- so, you should test using _movie.framePalette first...
-- returns a negative value for built-in palettes:
--systemMac -1
--systemWin -102
--rainbow -2
--grayscale -3
--pastels -4
--vivid -5
--ntsc -6
--metallic -7
--web16 -8
--systemWinDir4 -101
-- a frame set to a member of type #palette have a positive
-- value equal to it's member number.
on ToPaletteIndex(aColor)
if ilk(aColor) = #color then return aColor.paletteIndex
if stringP(aColor) then return color(aColor).paletteIndex
return -1
end
-- note, this returns the RGB colour from the index of Director's current frame palette.
on PaletteIndexToRGB(tColorIndex, tPaletteRef)
img = image(1,1,32)
img.paletteRef = tPaletteRef
img.setPixel(0, 0, paletteIndex(tColorIndex))
col = img.getPixel(0, 0)
col.colorType = #rgb
return rgb(col)
end
on RGBtoInteger(aColor)
R = aColor.red
G = aColor.green
B = aColor.blue
return R *256*256 + G *256 + B
end
--on aRGBtoInteger(a, R, G, B)
-- R = aColor.red
-- G = aColor.green
-- B = aColor.blue
-- int = R *256*256 + G *256 + B
-- a = (int / -16777216) *256*256*256
-- return -(int + a)
--end
--on IntegertoRGB(int)
-- R = aColor.red
-- G = aColor.green
-- B = aColor.blue
-- return R *256*256 + G *256 + B
--end
on CMYKtoRGB (C, M, Y, K)
if C > 1 or M > 1 or Y > 1 or K > 1 then
C = C / 100.0
M = M / 100.0
Y = Y / 100.0
K = K / 100.0
end if
R = (1 - C * (1 - K) - K) * 256
G = (1 - M * (1 - K) - K) * 256
B = (1 - Y * (1 - K) - K) * 256
return color(R, G, B)
end
on RGBtoCMYK (R, G, B)
C = 1 - (R / 255.0)
M = 1 - (G / 255.0)
Y = 1 - (B / 255.0)
if min(C, M, Y) = 1 then return [0, 0, 0, 1]
K = min(C,M,Y)
C = (C - K) / (1 - K)
M = (M - K) / (1 - K)
Y = (Y - K) / (1 - K)
return [C, M, Y, K]
end
on RGBtoCMY (R, G, B)
C = 1 - (R / 255.0)
M = 1 - (G / 255.0)
Y = 1 - (B / 255.0)
return [C, M, Y]
end
on CMYtoRGB (C, M, Y)
if C > 1 or M > 1 or Y > 1 then
C = C / 100.0
M = M / 100.0
Y = Y / 100.0
K = K / 100.0
end if
R = (1 - C) * 255
G = (1 - M) * 255
B = (1 - Y) * 255
return color(R, G, B)
end
on CMYtoCMYK (C, M, Y)
K = 1
if C < K then K = C
if M < K then K = M
if Y < K then K = Y
C = (C - K) / (1 - K)
M = (M - K) / (1 - K)
Y = (Y - K) / (1 - K)
return [C, M, Y, K]
end
on CMYKtoCMY (C, M, Y, K)
C = ( C * ( 1 - K ) + K )
M = ( M * ( 1 - K ) + K )
Y = ( Y * ( 1 - K ) + K )
return [C, M, Y]
end
on RGBtoHex(R, G, B)
return color(R, G, B).hexString()
end
on HextoRGB(aHex)
return rgb(aHex)
end
-- 0, 3, 6, 9, C, F
-- 0%, 20%, 40%, 60%, 80%, 100%
on RGBtoWebSafe(R, G, B)
webSafe = [0, 51, 102, 153, 204, 255]
webSafe.sort()
R1 = webSafe[webSafe.findPosNear(R)]
if R < max(0, R1 - 25.5) then R1 = webSafe[max(1,webSafe.getPos(R) - 1)]
G1 = webSafe[webSafe.findPosNear(G)]
if G < max(0, G1 - 25.5) then G1 = webSafe[max(1,webSafe.getPos(G) - 1)]
B1 = webSafe[webSafe.findPosNear(B)]
if B < max(0, B1 - 25.5) then B1 = webSafe[max(1,webSafe.getPos(B) - 1)]
aColor = rgb(R1, G1, B1)
return aColor.hexString()
end
on WebSafetoRGB(aHex)
webSafe = ["0": 0, "3": 51, "6": 102, "9": 153, "C": 204, "F": 255]
R = webSafe.getProp(aHex.char[2])
G = webSafe.getProp(aHex.char[4])
B = webSafe.getProp(aHex.char[6])
return color(R, G, B)
end
on HextoWebSafe(aHex)
aColor = rgb(aHex)
webSafe = [0, 51, 102, 153, 204, 255]
webSafe.sort()
R = webSafe[webSafe.findPosNear(aColor.red)]
if aColor.red < max(0, R - 25.5) then R = webSafe[max(1,webSafe.getPos(R) - 1)]
G = webSafe[webSafe.findPosNear(aColor.green)]
if aColor.green < max(0, G - 25.5) then G = webSafe[max(1,webSafe.getPos(G) - 1)]
B = webSafe[webSafe.findPosNear(aColor.blue)]
if aColor.blue < max(0, B - 25.5) then B = webSafe[max(1,webSafe.getPos(B) - 1)]
aColor = rgb(R, G, B)
return aColor.hexString()
end
-- Colour Conversion Algorithms
-- http://www.easyrgb.com/math.html
-- http://www.cs.rit.edu/~ncs/color/t_convert.html
-- RGB to Hue, Saturation, Value
-- R, G, B values are from 0 to 1
-- h = [0,360], s = [0,1], v = [0,1]
on RGBtoHSB(R, G, B)
var_R = ( R / 255.0 )
var_G = ( G / 255.0 )
var_B = ( B / 255.0)
var_Min = min( var_R, var_G, var_B )
var_Max = max( var_R, var_G, var_B )
del_Max = var_Max - var_Min
V = var_Max
if del_Max = 0 then
H = 0
S = 0
else
S = del_Max / var_Max
del_R = ( ( ( var_Max - var_R ) / 6.0 ) + ( del_Max / 2.0 ) ) / del_Max
del_G = ( ( ( var_Max - var_G ) / 6.0 ) + ( del_Max / 2.0 ) ) / del_Max
del_B = ( ( ( var_Max - var_B ) / 6.0 ) + ( del_Max / 2.0 ) ) / del_Max
if ( var_R = var_Max ) then
H = del_B - del_G
else if ( var_G = var_Max ) then
H = ( 1 / 3.0 ) + del_R - del_B
else if ( var_B = var_Max ) then
H = ( 2 / 3.0 ) + del_G - del_R
end if
if H < 0 then H = H + 1
if H > 1 then H = H - 1
end if
return [H, S, V]
end
on HSBtoRGB(H, S, V)
if S = 0 then
R = V * 255
G = V * 255
B = V * 255
else
var_h = H * 6
if var_h = 6 then var_h = 0
var_i = integer(var_h) - (var_h < integer(var_h))
var_1 = V * ( 1 - S )
var_2 = V * ( 1 - S * ( var_h - var_i ) )
var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) )
if var_i = 0 then
var_r = V
var_g = var_3
var_b = var_1
else if var_i = 1 then
var_r = var_2
var_g = V
var_b = var_1
else if var_i = 2 then
var_r = var_1
var_g = V
var_b = var_3
else if var_i = 3 then
var_r = var_1
var_g = var_2
var_b = V
else if var_i = 4 then
var_r = var_3
var_g = var_1
var_b = V
else
var_r = V
var_g = var_1
var_b = var_2
end if
R = var_r * 255
G = var_g * 255
B = var_b * 255
end if
return color(R, G, B)
end
-- alternative functions to the HSV functions
-- in case the programmer knows HSB as the
-- HSV colour space (Hue, Saturation, Value)
on RGBtoHSV (R, G, B)
return RGBtoHSB(R, G, B)
end
on HSVtoRGB (H, S, V)
return HSBtoRGB(H, S, V)
end
-- RGB to Hue, Saturation, Luminosity
-- dependencies: HueToRGB()
on RGBtoHSL (R, G, B)
R = R / 255.0
G = G / 255.0
B = B / 255.0
vMin = min(R, G, B)
vMax = max(R, G, B)
dMax = vMax - vMin
L = (vMax + vMin) / 2
if dMax = 0 then
H = 0
S = 0
else
if L < 0.5 then
S = dMax / float(vMax + vMin)
else
S = dMax / float(2 - vMax - vMin)
end if
dR = (((vMax - R) / 6.0) + (dMax / 2.0))/float(dMax)
dG = (((vMax - G) / 6.0) + (dMax / 2.0))/float(dMax)
dB = (((vMax - B) / 6.0) + (dMax / 2.0))/float(dMax)
if R = vMax then
H = B - G
else if G = vMax then
H = (1/3.0) + R - B
else if B = vMax then
H = (2/3.0) + G - R
end if
if H < 0 then H = H + 1
if H > 1 then H = H - 1
end if
return [H, S, L]
end
-- this function calls another function: HuetoRGB( v1, v2, vH )
on HSLtoRGB (H, S, L)
if S = 0 then
R = L * 255
G = L * 255
B = L * 255
else
if L < 0.5 then
v2 = L * (1 + S)
else
v2 = (L + S) - (S * L)
end if
v1 = 2 * L - v2
R = 255 * HuetoRGB(v1, v2, H + (1/3.0))
G = 255 * HuetoRGB(v1, v2, H)
B = 255 * HuetoRGB(v1, v2, H - (1/3.0))
end if
return color(R, G, B)
end
on HuetoRGB( v1, v2, vH )
if vH < 0 then vH = vH + 1
if vH > 1 then vH = vH - 1
if ( 6 * vH ) < 1 then
return (v1 + ( v2 - v1 ) * 6 * vH)
end if
if ( 2 * vH ) < 1 then
return v2
end if
if ( 3 * vH ) < 2 then
return (v1 + ( v2 - v1 ) * ( ( 2.0 / 3.0 ) - vH ) * 6)
end if
return v1
end
-- alternative versions of the HSL functions
-- in case the user knows the HSL colour space as HLS or HSI (Hue, Saturation, Intensity)
on HLStoRGB (H, L, S)
return HSLtoRGB (H, S, L)
end
on RGBtoHLS (R, G, B)
return RGBtoHSL (R, G, B)
end
on HSItoRGB (H, S, I)
return HSLtoRGB (H, S, I)
end
on RGBtoHSI (R, G, B)
return RGBtoHSI (R, G, B)
end
on RGBtoXYZ (R, G, B)
R = ( R / 255.0 ) --Where R = 0 - 255
G = ( G / 255.0 ) --Where G = 0 - 255
B = ( B / 255.0 ) --Where B = 0 - 255
if R > 0.04045 then
R = power((( R + 0.055 ) / 1.055 ), 2.4)
else
R = R / 12.92
end if
if G > 0.04045 then
G = power((( G + 0.055 ) / 1.055 ), 2.4)
else
G = G / 12.92
end if
if B > 0.04045 then
B = power((( B + 0.055 ) / 1.055 ), 2.4)
else
B = B / 12.92
end if
R = R * 100
G = G * 100
B = B * 100
--Observer. = 2°, Illuminant = D65
X = (0.412453 * R) + (0.357580 * G) + (0.180423 * B)
Y = (0.212671 * R) + (0.715160 * G) + (0.072169 * B)
Z = (0.019334 * R) + (0.119193 * G) + (0.950227 * B)
return [X, Y, Z]
end
on XYZtoRGB (X, Y, Z)
X = X / 100.0 --Where X = 0 - 95.047
Y = Y / 100.0 --Where Y = 0 - 100.000
Z = Z / 100.0 --Where Z = 0 - 108.883
--Observer = 2°, Illuminant = D65
R = X * 3.2406 + Y * -1.5372 + Z * -0.4986
G = X * -0.9689 + Y * 1.8758 + Z * 0.0415
B = X * 0.0557 + Y * -0.2040 + Z * 1.0570
if ( R > 0.0031308 ) then
R = 1.055 * power(R, 1 / 2.4) - 0.055
else
R = 12.92 * R
end if
if ( G > 0.0031308 ) then
G = 1.055 * power(G, 1 / 2.4) - 0.055
else
G = 12.92 * G
end if
if ( B > 0.0031308 ) then
B = 1.055 * power(B, 1 / 2.4) - 0.055
else
B = 12.92 * B
end if
R = R * 255
G = G * 255
B = B * 255
return color(R, G, B)
end
on XYZtoCIELab (X, Y, Z)
-- Observer= 2°, Illuminant= D65
X = X / 95.047 --refX = 95.047
Y = Y / 100.000 --refY = 100.000
Z = Z / 108.883 --refZ = 108.883
if ( X > 0.008856 ) then
X = power(X, 1.0/3.0)
else
X = ( 7.787 * X ) + ( 16.0 / 116.0 )
end if
if ( Y > 0.008856 ) then
Y = power(Y, 1.0/3.0)
else
Y = ( 7.787 * Y ) + ( 16.0 / 116.0 )
end if
if ( Z > 0.008856 ) then
Z = power(Z, 1.0/3.0)
else
Z = ( 7.787 * Z ) + ( 16.0 / 116.0 )
end if
L = ( 116 * Y ) - 16
a = 500 * ( X - Y )
b = 200 * ( Y - Z )
return [L, a, b]
end
on CIELabtoXYZ (L, a, b)
Y = ( L + 16 ) / 116.0
X = ( a / 500.0 )+ Y
Z = Y - ( b / 200.0 )
if ( power(Y, 3) > 0.008856 ) then
Y = power( Y, 3)
else
Y = ( Y - (16.0 / 116.0 )) / 7.787
end if
if ( power(X, 3) > 0.008856 ) then
X = power(X, 3)
else
X = ( X - (16.0 / 116.0) ) / 7.787
end if
if ( power(Z, 3) > 0.008856 ) then
Z = power(Z, 3)
else
Z = ( Z - (16.0 / 116.0) ) / 7.787
end if
X = 95.047 * X --refX = 95.047 Observer= 2°, Illuminant= D65
Y = 100.000 * Y --refY = 100.000
Z = 108.883 * Z --refZ = 108.883
return [X, Y, Z]
end
on XYZtoCIELuv (X, Y, Z)
U = ( 4 * X ) / ( X + ( 15 * Y ) + ( 3 * Z ) )
V = ( 9 * Y ) / ( X + ( 15 * Y ) + ( 3 * Z ) )
Y = Y / 100.0
if ( Y > 0.008856 ) then
Y = power(Y, 1/3.0)
else
Y = ( 7.787 * Y ) + ( 16 / 116.0 )
end if
refX = 95.047 --Observer= 2°, Illuminant= D65
refY = 100.000
refZ = 108.883
refU = ( 4 * refX ) / ( refX + ( 15 * refY ) + ( 3 * refZ ) )
refV = ( 9 * refY ) / ( refX + ( 15 * refY ) + ( 3 * refZ ) )
L = ( 116 * Y ) - 16
U = 13 * L * ( U - refU )
V = 13 * L * ( V - refV )
return [L, U, V]
end
on CIELuvtoXYZ (L, U, V)
Y = ( L + 16 ) / 116.0
if ( power(Y, 3) > 0.008856 ) then
Y = power(Y, 3)
else
Y = ( Y - (16 / 116.0) ) / 7.787
end if
refX = 95.047 --Observer= 2°, Illuminant= D65
refY = 100.000
refZ = 108.883
refU = ( 4 * refX ) / ( refX + ( 15 * refY ) + ( 3 * refZ ) )
refV = ( 9 * refY ) / ( refX + ( 15 * refY ) + ( 3 * refZ ) )
U = U / ( 13 * L ) + refU
V = U / ( 13 * L ) + refV
Y = Y * 100
X = - ( 9 * Y * U ) / ( ( U - 4 ) * V - U * V )
Z = ( 9 * Y - ( 15 * V * Y ) - ( V * X ) ) / ( 3 * V )
return [X, Y, Z]
end
on XYZtoHunterLab (X, Y, Z)
HL = 10 * sqrt( Y )
Ha = 17.5 * ( ( ( 1.02 * X ) - Y ) / sqrt( Y ) )
Hb = 7 * ( ( Y - ( 0.847 * Z ) ) / sqrt( Y ) )
return [HL, Ha, Hb]
end
on HunterLabtoXYZ (HL, Ha, Hb)
Y = HL / 10
X = Ha / 17.5 * HL / 10
Z = Hb / 7 * HL / 10
Y = power(Y,2)
X = ( X + Y ) / 1.02
Z = -( Z - Y ) / 0.847
return [X, Y, Z]
end
--Where X = 0 - 95.047 Observer. = 2°, Illuminant = D65
--Where Y = 0 - 100.000
--Where Z = 0 - 108.883
on XYZtoYxy (X, Y, Z)
Y = Y
xx = X / ( X + Y + Z )
yy = Y / ( X + Y + Z )
return [Y, xx, yy]
end
--Where Y = 0 - 100
--Where xx = 0 - 1
--Where yy = 0 - 1
on YxytoXYZ (Y, xx, yy)
X = xx * ( Y / yy )
Y = Y
Z = ( 1 - xx - yy ) * ( Y / yy )
return [X, Y, Z]
end
-- The YIQ system is the colour primary system
-- adopted by NTSC for colour television broadcasting
on RGBtoYIQ (R, G, B)
Y = (0.299 * R) + (0.587 * G) + (0.114 * B)
I = (0.596 * R) + (-0.275 * G) + (-0.321 * B)
Q = (0.212 * R) + (-0.523 * G) + (0.311 * B)
return [Y, I, Q]
end
on YIQtoRGB (Y, I, Q)
R = (1.0 * Y) + (0.956 * I) + (0.621 * Q)
G = (1.0 * Y) + (-0.272 * I) + (-0.647 * Q)
B = (1.0 * Y) + (-1.105 * I) + (1.702 * Q)
return color(R, G, B)
end
-- YUV is like YIQ, except that it is the PAL/European standard
on RGBtoYUV (R, G, B)
Y = (0.299 * R) + (0.587 * G) + (0.114 * B)
U = (-0.147 * R) + (-0.289 * G) + (0.437 * B)
V = (0.615 * R) + (-0.515 * G) + (-0.100 * B)
return [Y, U, V]
end
on YUVtoRGB (Y, U, V)
R = (1.0 * Y) + (0.0 * U) + (1.140 * V)
G = (1.0 * Y) + (-0.394 * U) + (-0.581 * V)
B = (1.0 * Y) + (2.028 * U) + (0.0 * V)
return color(R, G, B)
end
-- ******************************************************************
-- Sub Functions
-- ******************************************************************
on CIELabtoRGB (L, a, b)
XYZ = CIELabToXYZ(L, a, b)
return XYZtoRGB(XYZ[1], XYZ[2], XYZ[3])
end
on RGBtoCIELab (R, G, B)
XYZ = RGBtoXYZ(R, G, B)
return XYZtoCIELab (XYZ[1], XYZ[2], XYZ[3])
end
-- *********************************************************************************
-- XYZ (Tristimulus) Reference values of a perfect reflecting diffuser
-- *********************************************************************************
-- Observer 2° (CIE 1931) 10° (CIE 1964)
--Illuminant X2 Y2 Z2 X10 Y10 Z10
--
--A (Tungsten) 109.850 100.0 35.585 111.144 100.0 35.200
--C 98.074 100.0 118.232 97.285 100.0 116.145
--D50 96.422 100.0 82.521 96.720 100.0 81.427
--D55 95.682 100.0 92.149 95.799 100.0 90.926
--D65 (Daylight) 95.047 100.0 108.883 94.811 100.0 107.304
--D75 94.972 100.0 122.638 94.416 100.0 120.641
--D93 (CRT monitor)
--F2 (Fluorescent) 99.187 100.0 67.395 103.280 100.0 69.026
--F7 95.044 100.0 108.755 95.792 100.0 107.687
--F11 100.966 100.0 64.370 103.866 100.0 65.620
--Temperature x y Dir y/x
--(Kelvin)
--2000 0.52669 0.41331 1.33101
--2105 0.51541 0.41465 1.39021
--2222 0.50338 0.41525 1.45962
--2353 0.49059 0.41498 1.54240
--2500 0.47701 0.41368 1.64291
--2677 0.463 0.41121 1.76811 % error in table [3], estimated values
--2857 0.446 0.40742 1.92863
--3077 0.43156 0.40216 2.14300
--3333 0.41502 0.39535 2.44455
--3636 0.39792 0.38690 2.90309
--4000 0.38045 0.37676 3.68730
--4444 0.36276 0.36496 5.34398
--5000 0.34510 0.35162 11.17883
--5714 0.32775 0.33690 -39.34888
--6667 0.31101 0.32116 -6.18336
--8000 0.29518 0.30477 -3.08425
--10000 0.28063 0.28828 -1.93507
-- ************************************************************
-- The below are from:
-- http://www.srgb.com/hpsrgbprof/sld001.htm
-- however, I do not know if the math is correct
-- ************************************************************
on XYZD65toXYZD50 (X65, Y65, Z65)
X50 = (1.0479 * X65) + (.0229 * Y65) + (-0.0502 * Z65)
Y50 = (.0296 * X65) + (.9904 * Y65) + (-0.0171 * Z65)
Z50 = (-0.0092 * X65) + (.0151 * Y65) + (.7519 * Z65)
return [X50, Y50, Z50]
end
-- 2.2 Gamma
on XYZD50toRGB (X, Y, Z)
R = (.4361 * X) + (.2664 * Y) + (.1431 * Z)
G = (.2225 * X) + (.7169 * Y) + (.0606 * Z)
B = (.0139 * X) + (.0971 * Y) + (.7141 * Z)
return color(R, G, B)
end
--on XYZtoRGB (X, Y, Z)
-- R = (.8951 * X) + (.2664 * Y) + (-0.1614 * Z)
-- G = (-0.7502 * X) + (1.7135 * Y) + (.0367 * Z)
-- B = (.0389 * X) + (.0685 * Y) + (1.0296 * Z)
-- return color(R, G, B)
--end
-- Gamma Equation
-- For each R, G, B value:
-- if RGB <= 0.03928
-- RGB' = RGB/12.92
-- else
-- RGB' = power((0.55 + RGB)/1.055), 2.4)
-- end if
-- Note: RGB normalized to 0.0 to 0.1
--on ceil myNum
--
--return integer(myNum + 0.499999999999999)
--
--end
--
--on floor myNum
--
--return integer(myNum - 0.499999999999999)
--
--end
--ITU-R BT.709 Primaries and white point D65 [9]. Valid for sRGB.
on sRGBtoXYZ (R, G, B)
R = R/255.0
G = G/255.0
B = B/255.0
X = (0.4124 * R) + (0.3576 * G) + (0.1805 * B)
Y = (0.2126 * R) + (0.7152 * G) + (0.0722 * B)
Z = (0.0193 * R) + (0.1192 * G) + (0.9505 * B)
return [X * 100, Y * 100, Z * 100]
end
on XYZtosRGB (X, Y, Z)
X = X/100.0
Y = Y/100.0
Z = Z/100.0
R = (3.2410 * X) + (-1.5374 * Y) + ( -0.4986 * Z)
G = (-0.9692 * X) + ( 1.8760 * Y) + ( 0.0416 * Z)
B = (0.0556 * X) + ( -0.2040 * Y) + ( 1.0570 * Z)
return color(R * 255, G * 255, B * 255)
end
--Basic matrix shells
-- X = (0 * R) + (0 * G) + (0 * B)
-- Y = (0 * R) + (0 * G) + (0 * B)
-- Z = (0 * R) + (0 * G) + (0 * B)
-- R = (0 * X) + (0 * Y) + (0 * Z)
-- G = (0 * X) + (0 * Y) + (0 * Z)
-- B = (0 * X) + (0 * Y) + (0 * Z)
--The conversion for D65 RGB to D65 XYZ uses the matrix on page 14, ITU-R BT.709 Primaries.
--D65 XYZ means XYZ without changing the illuminant.
-- XYZD65 -> RGBD65
-- X = 0.4124 0.3576 0.1805 R
-- Y = 0.2126 0.7152 0.0722 G
-- Z = 0.0193 0.1192 0.9505 B
on XYZ2RGB (X, Y, Z)
X = X/100.0
Y = Y/100.0
Z = Z/100.0
R = (3.240479 * X) + (-1.537150 * Y) + (-0.498535 * Z)
G = (-0.969256 * X) + (1.875992 * Y) + (0.041556 * Z)
B = (0.055648 * X) + (-0.204043 * Y) + (1.057311 * Z)
return color(R * 255, G * 255, B * 255)
end
on RGB2XYZ (R, G, B)
R = R/255.0
G = G/255.0
B = B/255.0
X = (0.412453 * R) + (0.357580 * G) + (0.180423 * B)
Y = (0.212671 * R) + (0.715160 * G) + (0.072169 * B)
Z = (0.019334 * R) + (0.119193 * G) + (0.950227 * B)
return [X * 100, Y * 100, Z * 100]
end
--The conversion for D65 RGB to D50 XYZ applies additionally (by multiplication) the Bradford
--correction, which takes the adaptation of the eyes into account. This correction is an improved
--alternative to the Von Kries correction [1].
--Monitors are assumed D65, but for printed paper the standard illuminant is D50. Therefore
--this transformation is recommended if the data are used for printing:
-- XYZD50 -> RGBD65
-- X = 0.4361 0.3851 0.1431 R
-- Y = 0.2225 0.7169 0.0606 G
-- Z = 0.0139 0.0971 0.7141 B