ColorSample reading discrepancy

Discussion of Photoshop Scripting, Photoshop Actions and Photoshop Automation in General

Moderators: Tom, Kukurykus

undavide

ColorSample reading discrepancy

Post by undavide »

Hello,
I'm playing around with ColorSamplers, and I've found some strangeness in the way they report values.
Let's have a document filled with a color, defined in RGB: R126, G43, B76) and a color sample put somewhere.
if you simply:

Code: Select allvar myDoc = app.activeDocument;
var myCS = myDoc.colorSamplers[0]
alert("RGB: " + myCS.color.rgb.red + ", " + myCS.color.rgb.green + ", " + myCS.color.rgb.blue + "\nLab: " + myCS.color.lab.l + ", " + myCS.color.lab.a + ", " + myCS.color.lab.b)

What you get in the Alert window is:
RGB: 126, 43.0038910505837, 76
Lab:31.3751220703125, 38.0986328125, -0.811279296875

By the way, the Info Palette reads:
RGB: R126, G43, B76
Lab: 31, 39, 0

Why on earth the a channel 39 and not 38, since the floating point value is 38.0986328125? And what about -0.81 which becomes 0?

Besides that, the way you define a color in the Color Picker makes a lot of difference - if you change HSB's Saturation slider, the "true" numbers will be HSB, and RGB and Lab will be calculated from them.

Anyway, I've tried other colors as well:
RGB 0,96,0 reads
Lab: 35 -39 40 on the InfoPalette
Lab: 34.771728515625, -39.1141967773438, 38.97021484375 via scripting
(a point lower in the b: 38.9 mysteriously converts to 40)

RGB Pure White (Lab 100, 0, 0 on the Info Palette) reads 100, -0.5, -0.5 (no matter what default rendering intent is set in the Color Preferences, and what is the white point of the document's ICC.
I'm a bit puzzled, what do you think about?
Thanks

Davide

Professional AI Audio Generation within Adobe Premiere Pro - Download Free Plugin here

xbytor

ColorSample reading discrepancy

Post by xbytor »

Just out of curiosity, does changing the bit depth of the image modify the behaviour that you are seeing?
undavide

ColorSample reading discrepancy

Post by undavide »

Really puzzled:
RGB 0,96,0 now reads RGB: 3.4552001953125, 95.8818054199219, 0.
(while the Lab readings are correct, compared with the infoPalette)

I've rebooted PS, created a blank sRGB document 8bit.
Duplicate the same, mode 16bit.
Filled with the same RGB 0,96,0.

8bit, InfoPalette: RGB: 0,97,0 - Lab: 35, -39, 40
16bit, Info Palette: RGB: 0,96,0 - Lab: 35, -39, 40

Script:
8bit:
RGB: 3.5174560546875, 96.8934631347656, 0
Lab: 35.14, -39.05, 39.91

16bit:
RGB: 3.4552001953125, 95.8818054199219, 0
Lab: 34.77, -38.77, 39.63

jacobolus

ColorSample reading discrepancy

Post by jacobolus »

What color space is your document in? What bit depth? What do the info palettes say if you change them to output 16-bit or floating point colors? What CMM do you have Photoshop set up to use, and what rendering intent? Do you mind putting up a copy of your document online somewhere?

Keep in mind, Photoshop's implementation of 8-bit CIELAB has possible values of a and b in the info palette ranging from -128 to 127 (-0x80 to 0x79), and in 16 bit/channel they range from -16384 to 16256 (-0x4000 to 0x3F80). I'm not sure that the values have the same ranges in the script output.

Cheers.
Mike Hale

ColorSample reading discrepancy

Post by Mike Hale »

For what it is worth, I remember a long thread in the Abode Photoshop scripting forum between Rags Gardner and Chris Cox about how Photoshop handles colors. As I recall these are some points to consider.

1. The info panel is not that useful. It only displays 8bit values and those may be converted( see below )
2. One of the color options in the info panel is Actual Color. That is the actual color of the sample and what mode it displays depends on the doc mode.
3. All other color modes in the info panel show converted values except for the mode that matches the document mode.
4. When you set a color in a script if the color mode doesn't match the doc mode the values used are converted to determine. i.e if you set a Lab color in a RGB doc the lab values are converted to RGB to create the color.
5. When you read a color that is not the same mode as the doc the values are converted. So if you set then read Lab colors in a RGB doc the values may be converted twice.
6. For the reason above to get the most accurate color values set and read the color using the same mode as the doc.

They also went on and on about 16bit vs 15bit math. Rags was making some kind of calibration script and was having trouble with the values being returned in the script. I seem to remember Chris Cox finally admitting there was something wrong but I don't recall what. The was on the old Adobe forum and I don't know if that can still be found online.
undavide

ColorSample reading discrepancy

Post by undavide »

Hello,
thanks for your answers Mike and Jacob.
I've put together a brief script to summarize - with a 8/16 bit comparison as xbytor suggested:

Code: Select all#target photoshop
app.preferences.rulerUnits = Units.PIXELS;

// will make the Color Settings to use: AdobeRGB, GrayGamma 2.2, Adobe ACE, Relative Colorimetric, BPC, Dither
// =======================================================
var idsetd = charIDToTypeID( "setd" );
    var desc64 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref31 = new ActionReference();
        var idPrpr = charIDToTypeID( "Prpr" );
        var idcolorSettings = stringIDToTypeID( "colorSettings" );
        ref31.putProperty( idPrpr, idcolorSettings );
        var idcapp = charIDToTypeID( "capp" );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idTrgt = charIDToTypeID( "Trgt" );
        ref31.putEnumerated( idcapp, idOrdn, idTrgt );
    desc64.putReference( idnull, ref31 );
    var idT = charIDToTypeID( "T   " );
        var desc65 = new ActionDescriptor();
        var idworkingRGB = stringIDToTypeID( "workingRGB" );
        desc65.putString( idworkingRGB, "Adobe RGB (1998)" );
        var idEngn = charIDToTypeID( "Engn" );
        desc65.putString( idEngn, "Adobe (ACE)" );
        var idInte = charIDToTypeID( "Inte" );
        var idInte = charIDToTypeID( "Inte" );
        var idClrm = charIDToTypeID( "Clrm" );
        desc65.putEnumerated( idInte, idInte, idClrm );
        var idMpBl = charIDToTypeID( "MpBl" );
        desc65.putBoolean( idMpBl, true );
        var idDthr = charIDToTypeID( "Dthr" );
        desc65.putBoolean( idDthr, true );
        var idrenderSceneReferred = stringIDToTypeID( "renderSceneReferred" );
        desc65.putBoolean( idrenderSceneReferred, false );
    var idcolorSettings = stringIDToTypeID( "colorSettings" );
    desc64.putObject( idT, idcolorSettings, desc65 );
executeAction( idsetd, desc64, DialogModes.NO );
// =======================================================

// Set a solid color
var myColor = new SolidColor();
myColor.rgb.red = 0;
myColor.rgb.green = 96;
myColor.rgb.blue = 0;

// Create blank 8bit doc, fill with color, add a sampler
var myDoc8bit = app.documents.add(400, 400, 72, "8 bit", NewDocumentMode.RGB, DocumentFill.WHITE, 1, BitsPerChannelType.EIGHT, ColorProfile.CUSTOM = "Adobe RGB (1998)");
myDoc8bit.selection.fill(myColor);
var my8bitColorSampler = myDoc8bit.colorSamplers.add([UnitValue(200, 'px'), UnitValue(200, 'px')])

// Create blank 16bit doc, fill with color, add a sampler
var myDoc16bit = app.documents.add(400, 400, 72, "16 bit", NewDocumentMode.RGB, DocumentFill.WHITE, 1, BitsPerChannelType.SIXTEEN, ColorProfile.CUSTOM = "Adobe RGB (1998)");
myDoc16bit.selection.fill(myColor);
var my16bitColorSampler = myDoc16bit.colorSamplers.add([UnitValue(200, 'px'), UnitValue(200, 'px')])

alert("Samples from 8bit/16bit files\nRGB 8bit:\n" + my8bitColorSampler.color.rgb.red + "\n" + my8bitColorSampler.color.rgb.green + "\n" + my8bitColorSampler.color.rgb.blue + ".\n\nRGB 16bit:\n" + my16bitColorSampler.color.rgb.red + "\n" + my16bitColorSampler.color.rgb.green + "\n" + my16bitColorSampler.color.rgb.blue + ".");
alert("Samples from 8bit/16bit files\nLab 8bit:\n" + my8bitColorSampler.color.lab.l + "\n" + my8bitColorSampler.color.lab.a + "\n" + my8bitColorSampler.color.lab.b + ".\n\nLab 16bit:\n" + my16bitColorSampler.color.lab.l + "\n" + my16bitColorSampler.color.lab.a + "\n" + my16bitColorSampler.color.lab.b + ".");


Basically, to answer Jacob, I've Adobe (ACE) as color engine, RelCol with BPC (the ScriptingListener code sets these preferences).
The script creates a RGB 8bit file, defines an RGB color and fills the document; then creates a RGB 16bit file and fills it with the very same RGB color. The alert shows the different readings. I know no way to set the sampling preferences via scripting (all layers, 5x5px for instance... any hint?) but with a flat color patch it's not a problem.

Please run the script in order to replicate my readings, and have a look to your Info Palette.

I've worked in RGB only (both document and SolidColor, to avoid conversions). My temporary conclusions:
1) The same color applied to 8bit and 16bit files leads to different script readings (1 point in RGB in one channel, 0.5 points in Lab in all three channels)
2) InfoPalette readings are equal to script readings with RGB (so the same bizarre 1point difference from 8/16bit shows); while in Lab the rounding is simply wrong (for instance in 8bit file, script b42.2 translate in Palette b43, while in 16bit file, script b41,9 translate in Palette b43).

Mind you, if you duplicate an 8bit file already filled with color, then switch the duplicate to 16bit, the readings are equal (while the roundings are wrong as well) - my script on the other hand creates from scratch the two documents *then* fills them.
Cheers,

Davide
larsen67

ColorSample reading discrepancy

Post by larsen67 »

Rags… called it quasi-15bit if you google that & Photoshop you will find so bits relating to that discussion… But the links to the old forum are dead… This one is probably the closest if you have not already seen this…

http://compgroups.net/comp.graphics.app ... 6-bit-mode ... 6-bit-mode
jacobolus

ColorSample reading discrepancy

Post by jacobolus »

jacobolus

ColorSample reading discrepancy

Post by jacobolus »

I cleaned your code up a bit so I could see what it was doing:
Code: Select allapp.preferences.rulerUnits = Units.PIXELS;

var s = function (str) { return app.stringIDToTypeID (str) }

var rgbColor = function (r, g, b) {
  var color = new SolidColor();
  color.rgb.red = r, color.rgb.green = g, color.rgb.blue = b;
  return color;
}

// will make the Color Settings to use: AdobeRGB, GrayGamma 2.2, Adobe ACE, Relative Colorimetric, BPC, Dither
// =======================================================
  var desc1 = new ActionDescriptor();
  var ref1 = new ActionReference();
  var desc2 = new ActionDescriptor();
 
  ref1.putProperty(s('property'), s('colorSettings'));
  ref1.putEnumerated(s('application'), s('ordinal'), s('targetEnum'));
 
  desc1.putReference(s('null'), ref1);
     
  desc2.putString(s('workingRGB'), 'Adobe RGB (1998)');
  desc2.putString(s('engine'), 'Adobe (ACE)');
  desc2.putEnumerated(s('intent'), s('intent'), s('colorimetric'));
  desc2.putBoolean(s('mapBlack'), true);
  desc2.putBoolean(s('dither'), true);
  desc2.putBoolean(s('renderSceneReferred'), false);
  desc1.putObject(s('to'), s('colorSettings'), desc2);

executeAction(s('set'), desc1, DialogModes.NO);
// =======================================================

// Set a solid color
var myColor = rgbColor(0, 96, 0)

// Create blank 8bit doc, fill with color, add a sampler
var doc8 = app.documents.add(
  400, 400, 72,
  '8 bit', NewDocumentMode.RGB,
  DocumentFill.WHITE, 1,
  BitsPerChannelType.EIGHT,
  ColorProfile.CUSTOM = 'Adobe RGB (1998)');
doc8.selection.fill(myColor);
var sampler8 = doc8.colorSamplers.add([UnitValue(200, 'px'), UnitValue(200, 'px')])

// Create blank 16bit doc, fill with color, add a sampler
var doc16 = app.documents.add(
  400, 400, 72,
  '16 bit', NewDocumentMode.RGB,
  DocumentFill.WHITE, 1,
  BitsPerChannelType.SIXTEEN,
  ColorProfile.CUSTOM = 'Adobe RGB (1998)');
doc16.selection.fill(myColor);
var sampler16 = doc16.colorSamplers.add([UnitValue(200, 'px'), UnitValue(200, 'px')])

var printColor = function (color, indent) {
  return (
    indent + 'RGB:\n' + indent + '    ' +
    color.rgb.red.toFixed(3) + ', ' +
    color.rgb.green.toFixed(3) + ', ' +
    color.rgb.blue.toFixed(3) + '\n' +
    indent + 'CIELAB:\n' + indent + '    ' +
    color.lab.l.toFixed(3) + ', ' +
    color.lab.a.toFixed(3) + ', ' +
    color.lab.b.toFixed(3)
  )
}

$.write(
  '\n----------\n\n' +
  'Original color:\n' +
  printColor(myColor, '    ') + '\n' +
  '8-bit file:\n' +
  printColor(sampler8.color, '    ') + '\n' +
  '16-bit file:\n' +
  printColor(sampler16.color, '    ')
);

Now it prints out the values for the color you set up, as well as the sampled results when you paste that color into a file. I think it looks like the issue is with rounding when you fill in an 8-bit-per-channel document.