javascript - 从 RGB 转换为 L*ab 颜色时值不准确

标签 javascript colors rgb photoshop extendscript

我正在尝试将 sRGB 值(在 Photoshop 中)转换为 L*ab 值(也可在 Photoshop 中使用)我大致了解,但没有得到与 EasyRGB 相同的结果这是我从中获得转换公式的地方。我预计会有舍入错误(不是在最后,我四舍五入到三个位置)。只是我看不到他们。

  • 输入:sRGB 255、0、255
  • 输出:L*ab:60.32、98.254、-60.843
  • 预期输出 L*ab:60.324 98.234 -60.825

为了方便起见,我删除了所有 Photoshop 代码,只使用 JavaScript

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;
}
<!-- page content -->
<p id="myPage"></p>

最佳答案

考虑使用 Photoshop 的 ExtendScript/JS API而不是 EasyRGB 来实现精确的颜色转换。

下面要点中的自定义 rgbToLab 函数演示了 SolidColor 如何可以利用该类首先创建一个新的 RGB 颜色(使用给定的颜色分量;R、G、B)以及随后如何获取相应的 Lab 值。

#target photoshop

/**
 * Converts RGB color values to the Lab color model.
 * @param {Number} red - The red component value (0-255).
 * @param {Number} green - The green component value (0-255).
 * @param {Number} blue - The blue component value (0-255).
 * @returns {Array} The Lab values.
 */
function rgbToLab(red, green, blue) {
  var color = new SolidColor;

  color.rgb.red = red;
  color.rgb.green = green;
  color.rgb.blue = blue;

  return [
    color.lab.l,
    color.lab.a,
    color.lab.b
  ]
}

var labValues = rgbToLab(255, 0, 255);

$.writeln('L*ab: '+ labValues) // --> L*ab: 60.16845703125,92.6736755371094,-60.763671875

关于javascript - 从 RGB 转换为 L*ab 颜色时值不准确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60844996/

相关文章:

c# - 如何找到黑色像素位置

C、开罗 : render stream of RGB images

javascript - 替换字符串中的单词

javascript - Ios Safari 的复制按钮

javascript - 如何模拟鼠标点击 Firefox 扩展中的任何 HTML 元素(iframe、对象等)?

matlab - 如何将颜色名称转换为 3 元素 RGB 向量?

algorithm - 以编程方式检测颜色

javascript - IE 屏蔽我的 C 盘上的 activex 内容有什么意义?

Java 用像素处理颜色的工作原理

image - Dart-获取ImageElement的像素颜色