我正在尝试将sRGB值(在Photoshop中)转换为L * ab值(也用于Photoshop中)公式来自。我希望有四舍五入的错误(不是最后,我四舍五入到第三位)。只有我看不到它们。
为了简化起见,我提出了所有Photoshop代码,所以只是JavaScript
EasyRGB
var msg = "";
// RGB
// var Red = foregroundColor.rgb.red;
// var Green = foregroundColor.rgb.green;
// var Blue = foregroundColor.rgb.blue;
var Red = 255;
var Green = 0;
var Blue = 255;
msg = "RGB: " + Red + ", " + Green + ", " + Blue + "<br>";
printy(msg);
// user colour converted to XYZ space
var myColXYZ = RGB_to_XYZ(Red, Green, Blue)
var colX = myColXYZ[0];
var colY = myColXYZ[1];
var colZ = myColXYZ[2];
// using CIE L-ab* colour space
var myLab = XYZ_to_LAB(colX, colY, colZ)
//msg = "L*ab: " + myLab[0] + ", " + myLab[1] + ", " + myLab[2] + "<br>";
// b4 rounding: 60.319933664076004, 98.25421868616108, -60.84298422386232
// round to three places
for (var i = 0; i < 3; i++) {
myLab[i] = round_nicely(myLab[i], 3);
}
msg = "L*ab: " + myLab[0] + ", " + myLab[1] + ", " + myLab[2] + "<br>";
printy(msg);
// results
// RGB: 255, 0, 255
// L*ab: 60.32, 98.254, -60.843
// should be
// CIE-L*ab = 60.324 98.234 -60.825
// function RGB TO XYZ (R, G, B)
// --------------------------------------------------------
// http://www.easyrgb.com/index.php?X=MATH&H=02#text2
function RGB_to_XYZ(r, g, b) {
var_R = parseFloat(r / 255); //r from 0 to 255
var_G = parseFloat(g / 255); //g from 0 to 255
var_B = parseFloat(b / 255); //b from 0 to 255
if (var_R > 0.04045) var_R = Math.pow(((var_R + 0.055) / 1.055), 2.4)
else var_R = var_R / 12.92
if (var_G > 0.04045) var_G = Math.pow(((var_G + 0.055) / 1.055), 2.4)
else var_G = var_G / 12.92
if (var_B > 0.04045) var_B = Math.pow(((var_B + 0.055) / 1.055), 2.4)
else var_B = var_B / 12.92
var_R = var_R * 100;
var_G = var_G * 100;
var_B = var_B * 100;
// Observer. = 2°, Illuminant = D65
X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
return [X, Y, Z]
}
// function XYZ TO LAB (x, y, z)
// --------------------------------------------------------
// http://www.easyrgb.com/index.php?X=MATH&H=16#text16
function XYZ_to_LAB(x, y, z) {
var ref_X = 95.047;
var ref_Y = 100.000;
var ref_Z = 108.883;
var_X = x / ref_X; //ref_X = 95.047 Observer= 2°, Illuminant= D65
var_Y = y / ref_Y; //ref_Y = 100.000
var_Z = z / ref_Z; //ref_Z = 108.883
if (var_X > 0.008856) var_X = Math.pow(var_X, (1 / 3))
else var_X = (7.787 * var_X) + (16 / 116)
if (var_Y > 0.008856) var_Y = Math.pow(var_Y, (1 / 3))
else var_Y = (7.787 * var_Y) + (16 / 116)
if (var_Z > 0.008856) var_Z = Math.pow(var_Z, (1 / 3))
else var_Z = (7.787 * var_Z) + (16 / 116)
CIE_L = (116 * var_Y) - 16;
CIE_a = 500 * (var_X - var_Y);
CIE_b = 200 * (var_Y - var_Z);
return [CIE_L, CIE_a, CIE_b]
}
// function ROUND NICELY (num number, number of decimal places)
// --------------------------------------------------------
function round_nicely(num, places) {
// if(! places) places = 3;
var p = Math.pow(10, places)
return Math.round(num * p) / p
}
// function PRINTY (str)
// --------------------------------------------------------
function printy(message) {
var outputDiv = document.getElementById('myPage');
outputDiv.innerHTML += message;
}
显然,EasyRBG <!-- page content -->
<p id="myPage"></p>
到RGB
的转换有缺陷。它不遵守自己的规则。让我们逐步进行此操作:
输入数据是
XYZ
第一步是通过除以255将它们映射到零到一个范围。产生这个
R: 255 G: 0 B: 255
下一步是一些操作,这似乎是对色域的一些调整。但是这些操作在极端处具有固定点,这意味着输入值var_R: 1 var_G: 0 var_B: 1
或1
在此操作中不会改变。所以我们仍然在
0
下一步是将所有内容按100缩放
var_R: 1 var_G: 0 var_B: 1
然后存在向量var_R: 100 var_G: 0 var_B: 100
与(R,G,B)
的矩阵乘法,这是RGB向量的加权线性组合
(X,Y,Z)
X = 42.24 + 18.05 = 60.29
Y = 21.26 + 7.22 = 28.48
[EasyRGB从Y = 1.93 + 95.05 = 96.98
到RGB
的转换有一些不同的结果
XYZ
考虑使用Photoshop的X: 59.289, Y: 28.485, Z: 96.964
代替EasyRGB进行准确的颜色转换。
下面要点中的自定义ExtendScript/JS API函数演示了如何利用rgbToLab
类首先创建新的RGB颜色(使用给定的颜色分量; R,G,B)以及如何随后获得相应的Lab值。
SolidColor