better color conversion
This commit is contained in:
parent
b108bac73f
commit
6bd029faae
8 changed files with 337 additions and 186 deletions
|
|
@ -69,7 +69,7 @@ export default Component.extend({
|
|||
|
||||
rgbPreview: observer('rgb', function () {
|
||||
let rgb = this.get('rgb'),
|
||||
xy = this.rgbToXy(rgb[0], rgb[1], rgb[2]);
|
||||
xy = rgbToCie(rgb[0], rgb[1], rgb[2]);
|
||||
|
||||
this.set('colorLoopOn', false);
|
||||
|
||||
|
|
@ -85,6 +85,30 @@ export default Component.extend({
|
|||
$('.color').css('background', 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')');
|
||||
}),
|
||||
|
||||
onActiveLightsChange: on('init', observer('activeLights.[]', function () {
|
||||
let lightsData = this.get('lightsData'),
|
||||
xy = null,
|
||||
setRGB = true;
|
||||
|
||||
this.get('activeLights').forEach((i) => {
|
||||
let light = lightsData[i];
|
||||
|
||||
if (xy !== null && xy[0] !== light.state.xy[0] && xy[1] !== light.state.xy[1]) {
|
||||
setRGB = false;
|
||||
}
|
||||
|
||||
xy = light.state.xy;
|
||||
});
|
||||
|
||||
if (setRGB && xy) {
|
||||
let rgb = cieToRgb(xy[0], xy[1]);
|
||||
|
||||
$('.color').css('background', 'rgb(' + Math.abs(rgb[0]) + ',' + Math.abs(rgb[1]) + ',' + Math.abs(rgb[2]) + ')');
|
||||
} else {
|
||||
$('.color').css('background', 'rgb(' + 255 + ',' + 255 + ',' + 255 + ')');
|
||||
}
|
||||
})),
|
||||
|
||||
// determines whether the lights are on/off for the lights switch
|
||||
lightsOnChange: on('init', observer('lightsData.@each.state.on', 'activeLights.[]', function () {
|
||||
if (!this.get('strobeOn')) {
|
||||
|
|
@ -250,92 +274,5 @@ export default Component.extend({
|
|||
|
||||
dimmerOnClass: computed('dimmerOn', function () {
|
||||
return this.get('dimmerOn') ? 'dimmerOn' : null;
|
||||
}),
|
||||
|
||||
// **************** STROBE LIGHT FINISH ****************
|
||||
// http://www.developers.meethue.com/documentation/color-conversions-rgb-xy
|
||||
rgbToXy(red, green, blue) {
|
||||
let X, Y, Z, x, y;
|
||||
|
||||
// normalize
|
||||
red = Number((red / 255));
|
||||
green = Number((green / 255));
|
||||
blue = Number((blue / 255));
|
||||
|
||||
// gamma correction
|
||||
red = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92);
|
||||
green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92);
|
||||
blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92);
|
||||
|
||||
// RGB to XYZ
|
||||
X = red * 0.664511 + green * 0.154324 + blue * 0.162028;
|
||||
Y = red * 0.283881 + green * 0.668433 + blue * 0.047685;
|
||||
Z = red * 0.000088 + green * 0.072310 + blue * 0.986039;
|
||||
|
||||
x = X / (X + Y + Z);
|
||||
y = Y / (X + Y + Z);
|
||||
|
||||
return [x, y];
|
||||
},
|
||||
|
||||
xyToRgb(x, y) {
|
||||
let r, g, b, X, Y = 1.0, Z;
|
||||
|
||||
X = (Y / y) * x;
|
||||
Z = (Y / y) * (1 - x - y);
|
||||
|
||||
r = X * 1.656492 - Y * 0.354851 - Z * 0.255038;
|
||||
g = X * -0.707196 + Y * 1.655397 + Z * 0.036152;
|
||||
b = X * 0.051713 - Y * 0.121364 + Z * 1.011530;
|
||||
|
||||
if (r > b && r > g && r > 1.0) {
|
||||
// red is too big
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0;
|
||||
} else if (g > b && g > r && g > 1.0) {
|
||||
// green is too big
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0;
|
||||
} else if (b > r && b > g && b > 1.0) {
|
||||
// blue is too big
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0;
|
||||
}
|
||||
|
||||
r = (r <= 0.0031308) ? 12.92 * r : 1.055 * Math.pow(r, (1.0 / 2.4)) - 0.055;
|
||||
g = (g <= 0.0031308) ? 12.92 * g : 1.055 * Math.pow(g, (1.0 / 2.4)) - 0.055;
|
||||
b = (b <= 0.0031308) ? 12.92 * b : 1.055 * Math.pow(b, (1.0 / 2.4)) - 0.055;
|
||||
|
||||
if (r > b && r > g) {
|
||||
// red is biggest
|
||||
if (r > 1.0) {
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0;
|
||||
}
|
||||
} else if (g > b && g > r) {
|
||||
// green is biggest
|
||||
if (g > 1.0) {
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0;
|
||||
}
|
||||
} else if (b > r && b > g) {
|
||||
// blue is biggest
|
||||
if (b > 1.0) {
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
r = r * 255;
|
||||
g = g * 255;
|
||||
b = b * 255;
|
||||
|
||||
return [r, g, b];
|
||||
}
|
||||
})
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ module.exports = function(defaults) {
|
|||
});
|
||||
|
||||
app.import('vendor/dancer.js');
|
||||
app.import('vendor/cie-rgb-converter.js');
|
||||
|
||||
app.import('bower_components/intro.js/intro.js');
|
||||
app.import('bower_components/intro.js/introjs.css');
|
||||
|
|
|
|||
141
mobile/vendor/cie-rgb-converter.js
vendored
Normal file
141
mobile/vendor/cie-rgb-converter.js
vendored
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
With these functions you can convert the CIE color space to the RGB color space and vice versa.
|
||||
|
||||
The developer documentation for Philips Hue provides the formulas used in the code below:
|
||||
https://developers.meethue.com/documentation/color-conversions-rgb-xy
|
||||
|
||||
I've used the formulas and Objective-C example code and transfered it to JavaScript.
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
var rgb = cie_to_rgb(0.6611, 0.2936)
|
||||
var cie = rgb_to_cie(255, 39, 60)
|
||||
|
||||
------------------------------------------------------------------------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 www.usolved.net
|
||||
Published under https://github.com/usolved/cie-rgb-converter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Converts CIE color space to RGB color space
|
||||
* @param {Number} x
|
||||
* @param {Number} y
|
||||
* @param {Number} brightness - Ranges from 1 to 254
|
||||
* @return {Array} Array that contains the color values for red, green and blue
|
||||
*/
|
||||
function cieToRgb(x, y, brightness) {
|
||||
//Set to maximum brightness if no custom value was given (Not the slick ECMAScript 6 way for compatibility reasons)
|
||||
if (brightness === undefined) {
|
||||
brightness = 254;
|
||||
}
|
||||
|
||||
var z = 1.0 - x - y;
|
||||
var Y = (brightness / 254).toFixed(2);
|
||||
var X = (Y / y) * x;
|
||||
var Z = (Y / y) * z;
|
||||
|
||||
//Convert to RGB using Wide RGB D65 conversion
|
||||
var red = X * 1.656492 - Y * 0.354851 - Z * 0.255038;
|
||||
var green = -X * 0.707196 + Y * 1.655397 + Z * 0.036152;
|
||||
var blue = X * 0.051713 - Y * 0.121364 + Z * 1.011530;
|
||||
|
||||
//If red, green or blue is larger than 1.0 set it back to the maximum of 1.0
|
||||
if (red > blue && red > green && red > 1.0) {
|
||||
|
||||
green = green / red;
|
||||
blue = blue / red;
|
||||
red = 1.0;
|
||||
}
|
||||
else if (green > blue && green > red && green > 1.0) {
|
||||
|
||||
red = red / green;
|
||||
blue = blue / green;
|
||||
green = 1.0;
|
||||
}
|
||||
else if (blue > red && blue > green && blue > 1.0) {
|
||||
|
||||
red = red / blue;
|
||||
green = green / blue;
|
||||
blue = 1.0;
|
||||
}
|
||||
|
||||
//Reverse gamma correction
|
||||
red = red <= 0.0031308 ? 12.92 * red : (1.0 + 0.055) * Math.pow(red, (1.0 / 2.4)) - 0.055;
|
||||
green = green <= 0.0031308 ? 12.92 * green : (1.0 + 0.055) * Math.pow(green, (1.0 / 2.4)) - 0.055;
|
||||
blue = blue <= 0.0031308 ? 12.92 * blue : (1.0 + 0.055) * Math.pow(blue, (1.0 / 2.4)) - 0.055;
|
||||
|
||||
|
||||
//Convert normalized decimal to decimal
|
||||
red = Math.round(red * 255);
|
||||
green = Math.round(green * 255);
|
||||
blue = Math.round(blue * 255);
|
||||
|
||||
if (isNaN(red))
|
||||
red = 0;
|
||||
|
||||
if (isNaN(green))
|
||||
green = 0;
|
||||
|
||||
if (isNaN(blue))
|
||||
blue = 0;
|
||||
|
||||
|
||||
return [red, green, blue];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts RGB color space to CIE color space
|
||||
* @param {Number} red
|
||||
* @param {Number} green
|
||||
* @param {Number} blue
|
||||
* @return {Array} Array that contains the CIE color values for x and y
|
||||
*/
|
||||
function rgbToCie(red, green, blue) {
|
||||
var X, Y, Z, x, y;
|
||||
|
||||
// normalize
|
||||
red = Number((red / 255));
|
||||
green = Number((green / 255));
|
||||
blue = Number((blue / 255));
|
||||
|
||||
// gamma correction
|
||||
red = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92);
|
||||
green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92);
|
||||
blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92);
|
||||
|
||||
// RGB to XYZ
|
||||
X = red * 0.664511 + green * 0.154324 + blue * 0.162028;
|
||||
Y = red * 0.283881 + green * 0.668433 + blue * 0.047685;
|
||||
Z = red * 0.000088 + green * 0.072310 + blue * 0.986039;
|
||||
|
||||
x = X / (X + Y + Z);
|
||||
y = Y / (X + Y + Z);
|
||||
|
||||
return [x, y];
|
||||
}
|
||||
|
|
@ -1,13 +1,6 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
const {
|
||||
Component,
|
||||
observer,
|
||||
computed,
|
||||
on,
|
||||
run: { later, once },
|
||||
$
|
||||
} = Ember;
|
||||
const { Component, observer, computed, on, run: { later, once }, $ } = Ember;
|
||||
|
||||
export default Component.extend({
|
||||
classNames: ['col-sm-10', 'col-sm-offset-1', 'col-xs-12'],
|
||||
|
|
@ -70,7 +63,7 @@ export default Component.extend({
|
|||
|
||||
rgbPreview: observer('rgb', function () {
|
||||
let rgb = this.get('rgb'),
|
||||
xy = this.rgbToXy(rgb[0], rgb[1], rgb[2]);
|
||||
xy = rgbToCie(rgb[0], rgb[1], rgb[2]);
|
||||
|
||||
this.set('colorLoopOn', false);
|
||||
|
||||
|
|
@ -86,6 +79,30 @@ export default Component.extend({
|
|||
$('.color').css('background', 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')');
|
||||
}),
|
||||
|
||||
onActiveLightsChange: on('init', observer('activeLights.[]', function () {
|
||||
let lightsData = this.get('lightsData'),
|
||||
xy = null,
|
||||
setRGB = true;
|
||||
|
||||
this.get('activeLights').forEach((i) => {
|
||||
let light = lightsData[i];
|
||||
|
||||
if (xy !== null && xy[0] !== light.state.xy[0] && xy[1] !== light.state.xy[1]) {
|
||||
setRGB = false;
|
||||
}
|
||||
|
||||
xy = light.state.xy;
|
||||
});
|
||||
|
||||
if (setRGB && xy) {
|
||||
let rgb = cieToRgb(xy[0], xy[1]);
|
||||
|
||||
$('.color').css('background', 'rgb(' + Math.abs(rgb[0]) + ',' + Math.abs(rgb[1]) + ',' + Math.abs(rgb[2]) + ')');
|
||||
} else {
|
||||
$('.color').css('background', 'rgb(' + 255 + ',' + 255 + ',' + 255 + ')');
|
||||
}
|
||||
})),
|
||||
|
||||
// determines whether the lights are on/off for the lights switch
|
||||
lightsOnChange: on('init', observer('lightsData.@each.state.on', 'activeLights.[]', function () {
|
||||
if (!this.get('strobeOn')) {
|
||||
|
|
@ -257,92 +274,5 @@ export default Component.extend({
|
|||
toggleDimmer() {
|
||||
this.sendAction('toggleDimmer');
|
||||
}
|
||||
},
|
||||
|
||||
// **************** STROBE LIGHT FINISH ****************
|
||||
// http://www.developers.meethue.com/documentation/color-conversions-rgb-xy
|
||||
rgbToXy(red, green, blue) {
|
||||
let X, Y, Z, x, y;
|
||||
|
||||
// normalize
|
||||
red = Number((red / 255));
|
||||
green = Number((green / 255));
|
||||
blue = Number((blue / 255));
|
||||
|
||||
// gamma correction
|
||||
red = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92);
|
||||
green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92);
|
||||
blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92);
|
||||
|
||||
// RGB to XYZ
|
||||
X = red * 0.664511 + green * 0.154324 + blue * 0.162028;
|
||||
Y = red * 0.283881 + green * 0.668433 + blue * 0.047685;
|
||||
Z = red * 0.000088 + green * 0.072310 + blue * 0.986039;
|
||||
|
||||
x = X / (X + Y + Z);
|
||||
y = Y / (X + Y + Z);
|
||||
|
||||
return [x, y];
|
||||
},
|
||||
|
||||
xyToRgb(x, y) {
|
||||
let r, g, b, X, Y = 1.0, Z;
|
||||
|
||||
X = (Y / y) * x;
|
||||
Z = (Y / y) * (1 - x - y);
|
||||
|
||||
r = X * 1.656492 - Y * 0.354851 - Z * 0.255038;
|
||||
g = X * -0.707196 + Y * 1.655397 + Z * 0.036152;
|
||||
b = X * 0.051713 - Y * 0.121364 + Z * 1.011530;
|
||||
|
||||
if (r > b && r > g && r > 1.0) {
|
||||
// red is too big
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0;
|
||||
} else if (g > b && g > r && g > 1.0) {
|
||||
// green is too big
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0;
|
||||
} else if (b > r && b > g && b > 1.0) {
|
||||
// blue is too big
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0;
|
||||
}
|
||||
|
||||
r = (r <= 0.0031308) ? 12.92 * r : 1.055 * Math.pow(r, (1.0 / 2.4)) - 0.055;
|
||||
g = (g <= 0.0031308) ? 12.92 * g : 1.055 * Math.pow(g, (1.0 / 2.4)) - 0.055;
|
||||
b = (b <= 0.0031308) ? 12.92 * b : 1.055 * Math.pow(b, (1.0 / 2.4)) - 0.055;
|
||||
|
||||
if (r > b && r > g) {
|
||||
// red is biggest
|
||||
if (r > 1.0) {
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0;
|
||||
}
|
||||
} else if (g > b && g > r) {
|
||||
// green is biggest
|
||||
if (g > 1.0) {
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0;
|
||||
}
|
||||
} else if (b > r && b > g) {
|
||||
// blue is biggest
|
||||
if (b > 1.0) {
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
r = r * 255;
|
||||
g = g * 255;
|
||||
b = b * 255;
|
||||
|
||||
return [r, g, b];
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ module.exports = function(defaults) {
|
|||
});
|
||||
|
||||
app.import('vendor/dancer.js');
|
||||
|
||||
app.import('vendor/cie-rgb-converter.js');
|
||||
|
||||
app.import('bower_components/bootstrap-sass/assets/javascripts/bootstrap/tooltip.js');
|
||||
app.import('bower_components/intro.js/intro.js');
|
||||
app.import('bower_components/intro.js/introjs.css');
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 8 KiB After Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 7.3 KiB |
141
web/vendor/cie-rgb-converter.js
vendored
Normal file
141
web/vendor/cie-rgb-converter.js
vendored
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
With these functions you can convert the CIE color space to the RGB color space and vice versa.
|
||||
|
||||
The developer documentation for Philips Hue provides the formulas used in the code below:
|
||||
https://developers.meethue.com/documentation/color-conversions-rgb-xy
|
||||
|
||||
I've used the formulas and Objective-C example code and transfered it to JavaScript.
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
var rgb = cie_to_rgb(0.6611, 0.2936)
|
||||
var cie = rgb_to_cie(255, 39, 60)
|
||||
|
||||
------------------------------------------------------------------------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 www.usolved.net
|
||||
Published under https://github.com/usolved/cie-rgb-converter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Converts CIE color space to RGB color space
|
||||
* @param {Number} x
|
||||
* @param {Number} y
|
||||
* @param {Number} brightness - Ranges from 1 to 254
|
||||
* @return {Array} Array that contains the color values for red, green and blue
|
||||
*/
|
||||
function cieToRgb(x, y, brightness) {
|
||||
//Set to maximum brightness if no custom value was given (Not the slick ECMAScript 6 way for compatibility reasons)
|
||||
if (brightness === undefined) {
|
||||
brightness = 254;
|
||||
}
|
||||
|
||||
var z = 1.0 - x - y;
|
||||
var Y = (brightness / 254).toFixed(2);
|
||||
var X = (Y / y) * x;
|
||||
var Z = (Y / y) * z;
|
||||
|
||||
//Convert to RGB using Wide RGB D65 conversion
|
||||
var red = X * 1.656492 - Y * 0.354851 - Z * 0.255038;
|
||||
var green = -X * 0.707196 + Y * 1.655397 + Z * 0.036152;
|
||||
var blue = X * 0.051713 - Y * 0.121364 + Z * 1.011530;
|
||||
|
||||
//If red, green or blue is larger than 1.0 set it back to the maximum of 1.0
|
||||
if (red > blue && red > green && red > 1.0) {
|
||||
|
||||
green = green / red;
|
||||
blue = blue / red;
|
||||
red = 1.0;
|
||||
}
|
||||
else if (green > blue && green > red && green > 1.0) {
|
||||
|
||||
red = red / green;
|
||||
blue = blue / green;
|
||||
green = 1.0;
|
||||
}
|
||||
else if (blue > red && blue > green && blue > 1.0) {
|
||||
|
||||
red = red / blue;
|
||||
green = green / blue;
|
||||
blue = 1.0;
|
||||
}
|
||||
|
||||
//Reverse gamma correction
|
||||
red = red <= 0.0031308 ? 12.92 * red : (1.0 + 0.055) * Math.pow(red, (1.0 / 2.4)) - 0.055;
|
||||
green = green <= 0.0031308 ? 12.92 * green : (1.0 + 0.055) * Math.pow(green, (1.0 / 2.4)) - 0.055;
|
||||
blue = blue <= 0.0031308 ? 12.92 * blue : (1.0 + 0.055) * Math.pow(blue, (1.0 / 2.4)) - 0.055;
|
||||
|
||||
|
||||
//Convert normalized decimal to decimal
|
||||
red = Math.round(red * 255);
|
||||
green = Math.round(green * 255);
|
||||
blue = Math.round(blue * 255);
|
||||
|
||||
if (isNaN(red))
|
||||
red = 0;
|
||||
|
||||
if (isNaN(green))
|
||||
green = 0;
|
||||
|
||||
if (isNaN(blue))
|
||||
blue = 0;
|
||||
|
||||
|
||||
return [red, green, blue];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts RGB color space to CIE color space
|
||||
* @param {Number} red
|
||||
* @param {Number} green
|
||||
* @param {Number} blue
|
||||
* @return {Array} Array that contains the CIE color values for x and y
|
||||
*/
|
||||
function rgbToCie(red, green, blue) {
|
||||
var X, Y, Z, x, y;
|
||||
|
||||
// normalize
|
||||
red = Number((red / 255));
|
||||
green = Number((green / 255));
|
||||
blue = Number((blue / 255));
|
||||
|
||||
// gamma correction
|
||||
red = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92);
|
||||
green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92);
|
||||
blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92);
|
||||
|
||||
// RGB to XYZ
|
||||
X = red * 0.664511 + green * 0.154324 + blue * 0.162028;
|
||||
Y = red * 0.283881 + green * 0.668433 + blue * 0.047685;
|
||||
Z = red * 0.000088 + green * 0.072310 + blue * 0.986039;
|
||||
|
||||
x = X / (X + Y + Z);
|
||||
y = Y / (X + Y + Z);
|
||||
|
||||
return [x, y];
|
||||
}
|
||||
Reference in a new issue