Reading Hex Codes on each layer of a Photoshop Document?
- July 26, 2023
- 2 replies
- 2453 views
I have this script (modified a bit) from @jazz-y that allows me to read all the hex codes in a document into an array which is great. I was wondering if there was a way to push the hexes into their own arrays based off the layers?
const DE_CIE76 = 0; //color difference: 0-255
const THRESHOLD = 0; //color pixels threshold
var s2t = stringIDToTypeID,
t2s = typeIDToStringID,
colorsObj = {},
colorsArr = [];
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('mode'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
if (t2s(executeActionGet(r).getEnumerationValue(p)) == 'RGBColor') {
var f = new File(Folder.temp + '/colors.raw');
(d = new ActionDescriptor()).putBoolean(s2t("channelsInterleaved"), true);
d.putBoolean(s2t('copy'), true);
(d1 = new ActionDescriptor()).putObject(s2t("as"), s2t("rawFormat"), d);
d1.putPath(s2t("in"), f);
executeAction(s2t("save"), d1, DialogModes.NO);
f.open('r');
f.encoding = "BINARY";
doForcedProgress('Reading colors', 'readColors(f.read(), colorsObj)');
f.close();
f.remove();
for (var a in colorsObj) if (colorsObj[a] > THRESHOLD) colorsArr.push({hex: a });
if (DE_CIE76) doForcedProgress('Filtering colors by dE = ' + DE_CIE76, 'filterByDE(colorsArr)');
}
function readColors(s, colorsObj) {
for (var i = 0; i < s.length; i += 3) {
var cur = toHex(s, i, 3)
updateProgress(i, s.length)
if (colorsObj[cur]) colorsObj[cur]++; else colorsObj[cur] = 1;
}
}
function filterByDE(c) {
for (var i = 0; i < c.length; i++) {
updateProgress(i, c.length)
if (c[i] == null) continue;
var cA = new SolidColor;
cA.rgb.hexValue = c[i].hex;
for (var x = i + 1; x < c.length; x++) {
if (c[x] == null || c[i] == null) continue;
var cB = new SolidColor;
cB.rgb.hexValue = c[x].hex;
if (deltaE(cA, cB) <= 10) {
if (c[i].pixels > c[x].pixels) {
c[i].pixels += c[x].pixels
c[x] = null
} else {
c[x].pixels += c[i].pixels
c[i] = null
}
}
}
}
}
function toHex(s, from, bits) {
var h = '';
for (var i = from; i < from + bits; i++) h += (('0' + s.charCodeAt(i).toString(16)).slice(-2));
return h
}
function deltaE(a, b) {
return Math.sqrt(Math.pow(b.lab.l - a.lab.l, 2) + Math.pow(b.lab.a - a.lab.a, 2) + Math.pow(b.lab.b - a.lab.b, 2))
}
Here is my example document:

In this example I have four layers named Corgi, Tennis Racquet, Runner, and Bowling Ball and Pin as well as a background layer. The current code generates a list of hex codes which I put in a note. I can shift the background color into it's own array so that my note reads
"Background: Hex1
Hex2
Hex3
Hex4
etc."
But what I really want is a note like this:
"Background: Hex1
Layer 1
Hex2
Hex3
Layer 2
Hex2
Hex4
etc."
I understand that in this code to read the colors a temporary raw file is made and read, ignoring all the layers. Is there a way to read the colors layer by layer or somehow sort the colors after the colors are read?
I really appreciate any help anyone can offer!

