用色彩平衡修改颜色

3
在JavaScript中,我可以使用如下函数调整图片的色彩平衡:
colorBalanceLayer(-50,0,0)

function colourBalanceLayer(cya, mag, yel)
{
  // cyan, magenta, yellow values are between -100 & +100
    var id713 = charIDToTypeID( "ClrB" );
    var desc162 = new ActionDescriptor();
    var id714 = charIDToTypeID( "ShdL" );
    var list37 = new ActionList();
    list37.putInteger( 0 );
    list37.putInteger( 0 );
    list37.putInteger( 0 );
    desc162.putList( id714, list37 );
    var id715 = charIDToTypeID( "MdtL" );
    var list38 = new ActionList();
    list38.putInteger( cya );
    list38.putInteger( mag );
    list38.putInteger( yel );
    desc162.putList( id715, list38 );
    var id716 = charIDToTypeID( "HghL" );
    var list39 = new ActionList();
    list39.putInteger( 0 );
    list39.putInteger( 0 );
    list39.putInteger( 0 );
    desc162.putList( id716, list39 );
    var id717 = charIDToTypeID( "PrsL" );
    desc162.putBoolean( id717, true );
    executeAction( id713, desc162, DialogModes.NO );
}

这个方法很好用,例如我在我的例子中为图片的中间色调添加了大量青色。我想知道的是:如果我想通过类似于上面例子中-50青色的数值来修改RGB颜色,该如何操作?最好将颜色改成CMKY,适当地进行调整,然后再改回RGB吗?只是我听说最好先从RGB转到L*ab(我知道如何做)。

2个回答

3

如果您想在RGB颜色上使用该功能,您需要将它们转换为CMY,因为colorBalanceLayer是设计用于处理CMY颜色的。可以使用以下函数轻松完成:

// r, g, b and c, m, y are in the range of 0 to 255

function rgb_cmy(r, g, b) {
    return [].map.call(arguments, function(v) {return 255 - v;});
}

// return value is an array of the form: [cyan, magenta, yellow]

处理完后,使用相同的函数将其转换回RGB:

rgb_cmy(c, m, y) // returns an array of the form: [red, green, blue]

我们是否应该将L*ab转换为中间步骤?不需要。

RGB和CMY是两种不同的颜色空间,大小相同:也就是说,它们都包含相同数量的颜色。但是两个空间不能完全覆盖对方。这意味着RGB包含一些不能准确表示为CMY颜色的颜色,反之亦然。因此,每次转换可能会引入一些不准确性。

L*ab颜色空间比其他空间大得多,完全覆盖了RGB和CMY。也就是说,每个RGB(或CMY)颜色都可以准确地表示为L*ab颜色,但有许多L*ab颜色无法用RGB或CMY表示。

如果有一个RGB颜色不能准确适配CMY,则会发生以下情况:

RGB --inaccurate--> CMY --inaccurate--> RGB // output !== input
RGB --accurate--> L*ab --inaccurate--> CMY --accurate--> L*ab --inaccurate--> RGB

我们发现同样存在一些不准确之处。
编辑:在colorBalanceLayer内部,您调用了一些其他函数。我看不出它们具体做什么,所以我只能提供以下草稿。
当然,可以在RGB颜色中更改青色、洋红色或黄色,而无需进行任何转换。为此,我们需要知道两件事:
1)CMY使用印刷颜料,RGB使用发射光,因此它们是亮度补色。这意味着:向CMY添加一些值会使颜色变暗,向RGB添加一些值会使其变亮。
2)RGB和CMY的色轮旋转60度,因此它们是颜色补色。这意味着:两者的相反颜色构成互补对:青/红、洋红/绿、黄/蓝。
因此,以下操作会导致相同的结果(CMY左,RGB右):
cyan += 20   ===   red -= 20;
magenta  -= 30   ===   green += 30;
yellow += 40   ===   blue -= 40;

你的函数可能可以进行调整,以便能够与 RGB 配置一起使用。


谢谢解释。现在我需要做的就是关联颜色平衡变化的值。RGB 128、128、128 +100红色变为156、97、97和60、60、60变为91、33、33。看起来红色向上移动了30,其他颜色向下移动了相同的距离。我需要进一步调查以获取更准确的值。 - Ghoul Fool
@GhoulFool 调整颜色平衡时必须保持颜色亮度稳定。因此,如果 red += 50,则应该有 green -=25blue -= 25 - Martin Ernst

0
回答我自己的问题:可以返回“平衡”颜色的值。这不是一种优雅的解决方案。
colourBalanceLayer("C0FFEE", 100,0,0);

function colourBalanceLayer(hexcol, cya, mag, yel)
{

  var pixH = 10;
  var pixV = 10;

  // create a document to work with
  var docRef = app.documents.add(pixH *2, pixV *2, 72, "colours")
  var newDoc = app.activeDocument;

  // =======================================================
  var id70 = charIDToTypeID( "Fl  " );
  var desc18 = new ActionDescriptor();
  var id71 = charIDToTypeID( "From" );
  var desc19 = new ActionDescriptor();
  var id72 = charIDToTypeID( "Hrzn" );
  var id73 = charIDToTypeID( "#Pxl" );
  desc19.putUnitDouble( id72, id73, 10.000000 );
  var id74 = charIDToTypeID( "Vrtc" );
  var id75 = charIDToTypeID( "#Pxl" );
  desc19.putUnitDouble( id74, id75, 9.000000 );
  var id76 = charIDToTypeID( "Pnt " );
  desc18.putObject( id71, id76, desc19 );
  var id77 = charIDToTypeID( "Tlrn" );
  desc18.putInteger( id77, 32 );
  var id78 = charIDToTypeID( "AntA" );
  desc18.putBoolean( id78, true );
  var id79 = charIDToTypeID( "Usng" );
  var id80 = charIDToTypeID( "FlCn" );
  var id81 = charIDToTypeID( "FrgC" );
  desc18.putEnumerated( id79, id80, id81 );
  executeAction( id70, desc18, DialogModes.NO );

  // cyan, magenta, yellow values are between -100 & +100
  var id713 = charIDToTypeID( "ClrB" );
  var desc162 = new ActionDescriptor();
  var id714 = charIDToTypeID( "ShdL" );
  var list37 = new ActionList();
  list37.putInteger( 0 );
  list37.putInteger( 0 );
  list37.putInteger( 0 );
  desc162.putList( id714, list37 );
  var id715 = charIDToTypeID( "MdtL" );
  var list38 = new ActionList();
  list38.putInteger( cya );
  list38.putInteger( mag );
  list38.putInteger( yel );
  desc162.putList( id715, list38 );
  var id716 = charIDToTypeID( "HghL" );
  var list39 = new ActionList();
  list39.putInteger( 0 );
  list39.putInteger( 0 );
  list39.putInteger( 0 );
  desc162.putList( id716, list39 );
  var id717 = charIDToTypeID( "PrsL" );
  desc162.putBoolean( id717, true );
  executeAction( id713, desc162, DialogModes.NO );

  // =======================================================
  var id40 = charIDToTypeID( "setd" );
  var desc11 = new ActionDescriptor();
  var id41 = charIDToTypeID( "null" );
  var ref5 = new ActionReference();
  var id42 = charIDToTypeID( "Clr " );
  var id43 = charIDToTypeID( "FrgC" );
  ref5.putProperty( id42, id43 );
  desc11.putReference( id41, ref5 );
  var id44 = charIDToTypeID( "T   " );
  var desc12 = new ActionDescriptor();
  var id45 = charIDToTypeID( "Rd  " );
  desc12.putDouble( id45, 255.000000 );
  var id46 = charIDToTypeID( "Grn " );
  desc12.putDouble( id46, 255.000000 );
  var id47 = charIDToTypeID( "Bl  " );
  desc12.putDouble( id47, 255.000000 );
  var id48 = charIDToTypeID( "RGBC" );
  desc11.putObject( id44, id48, desc12 );
  executeAction( id40, desc11, DialogModes.NO );

  var selRegion = null;
  selRegion = Array(Array(pixH, pixV),
  Array(pixH + 1, pixV),
  Array(pixH + 1, pixV + 1),
  Array(pixH, pixV + 1),
  Array(pixH, pixV));
  newDoc.selection.select(selRegion);
  var histR = newDoc.channels.getByName("Red").histogram;
  var histG = newDoc.channels.getByName("Green").histogram;
  var histB = newDoc.channels.getByName("Blue").histogram;
  var returnColor = new RGBColor();

  for (iHistR in histR)
  {
  if (histR[iHistR]!=0)
    {
      returnColor.red = iHistR;
    }
  }
  for (iHistG in histG)
  {
  if(histG[iHistG]!=0)
    {
      returnColor.green = iHistG;
    }
  }
  for (iHistB in histB)
  {
    if(histB[iHistB]!=0)
    {
      returnColor.blue = iHistB;
    }
  }

  alert(returnColor.red+","+returnColor.green+","+returnColor.blue);

  return returnColor;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接