I am trying to pull sample pixel data from across an image. Sampled values in the following code indicates that the sampling position is being moved appropriately, but the red, blue, and green values remain exactly the same no matter what the position it is.
Any thoughts on what I’m doing wrong?
let width = layerBounds.width;
let height = layerBounds.height;
let NumSamples = 3; // 10 samples along both height and width
let WidthIncremenet = Math.round((.9*width) / (NumSamples+1));
let HeightIncrement = Math.round((.9*height) / (NumSamples+1));
let RefColorData = Array(NumSamples * NumSamples * 4); // 1=R 2=G 3=B 4=R
app.activeDocument.colorSamplers.add({ x: 1, y: 1 });
const cs = app.activeDocument.colorSamplers[0];
let z = 1;
let x = Math.round(WidthIncremenet / 2); let y = Math.round(HeightIncrement/2);
// Capture Reference image color samples
for (x = 10; x < width; x += WidthIncremenet) {
for (y = 10; y < height; y += HeightIncrement) {
cs.move({ x: x, y: y });
RefColorData[z++] = cs.position.x;
RefColorData[z++] = cs.position.y;
RefColorData[z++] = cs.color.rgb.red;
RefColorData[z++] = cs.color.rgb.green;
RefColorData[z++] = cs.color.rgb.blue;
}
}
app.activeDocument.colorSamplers.removeAll();
Representative RefColorData generated values; these are the values for pixel 1,1 specified in app.activeDocument.colorSamplers.add({ x: 1, y: 1 }), not from any of the cs.move({ x: x, y: y }).
1: 50
2: 50
3: 38.80155642023346
4: 0.28793774319066145
5: 208.7898832684825
6: 50
7: 275
8: 38.80155642023346
9: 0.28793774319066145
10: 208.7898832684825
11: 50
12: 500
13: 38.80155642023346
14: 0.28793774319066145
15: 208.7898832684825
16: 50
17: 725
18: 38.80155642023346
19: 0.28793774319066145
20: 208.7898832684825
It’s interesting that the cs.position.x and cs.position.y are updated by the cs.move, but not the cs.color.rgb.red etc.
It is not your fault. It is DOM issue and what low-level action manager code is available.
Problem with action manager (AM) is that you can’t get color sampler by ID… they don’t have the ID. You can’t even get them by index alone. But you can get all samplers in document.
So in order to get color every time correctly you would need to ask Document class for all color samplers pick correct index from array and pick correct color.
But this is not how it works under the hood. They way it works right now… it takes an array from AM… instantiate color samplers and sets color into private property of the ColorSampler instance… the color is stuck within instance forever and cannot be changed.
So right now the only way to get it right is to create new instance and get rid of the old one. Under the hood this will happen when you ask document for color sampler. So you could change it like this:
let width = layerBounds.width;
let height = layerBounds.height;
let NumSamples = 3; // 10 samples along both height and width
let WidthIncremenet = Math.round((.9*width) / (NumSamples+1));
let HeightIncrement = Math.round((.9*height) / (NumSamples+1));
let RefColorData = Array(NumSamples * NumSamples * 4); // 1=R 2=G 3=B 4=R
app.activeDocument.colorSamplers.add({ x: 1, y: 1 });
const samplers = app.activeDocument.colorSamplers // store proxy to save performance
let cs = samplers[0];
let z = 1;
let x = Math.round(WidthIncremenet / 2); let y = Math.round(HeightIncrement/2);
// Capture Reference image color samples
for (x = 10; x < width; x += WidthIncremenet) {
for (y = 10; y < height; y += HeightIncrement) {
cs = samplers[0]; // this is important... makes new instance under the hood
cs.move({ x: x, y: y });
RefColorData[z++] = cs.position.x;
RefColorData[z++] = cs.position.y;
RefColorData[z++] = cs.color.rgb.red;
RefColorData[z++] = cs.color.rgb.green;
RefColorData[z++] = cs.color.rgb.blue;
}
}
app.activeDocument.colorSamplers.removeAll();
Would be great if Adobe could add better AM code so better DOM would be possible.
Btw yes position is updated… but the value does not come from PS Document.
Let me know if that works. I did not test the code.
Thanks very much, Jarda. That almost did it. I had to make one tweak to make the rgb data match the coordinates: for some reason I had to place cs.move({ x: x, y: y } BEFORE cs=samplers[0].
for (x = width1; x < width; x += WidthIncremenet) {
for (y = height1; y < height; y += HeightIncrement) {
cs.move({ x: x, y: y });
cs = samplers[0]; // important to make new instance and reset colors
RefColorData[z++] = cs.position.x;
RefColorData[z++] = cs.position.y;
RefColorData[z++] = cs.color.rgb.red;
RefColorData[z++] = cs.color.rgb.green;
RefColorData[z++] = cs.color.rgb.blue;
}
}