Please help me to iterate through the layers and find their colors
- September 6, 2023
- 1 reply
- 812 views
Dear experts
I have attached a PSD herewith.
I want to iterate through the layers and find the colors of them.
The layers can be either SOLID FILL layers or NORMAL layers which are rasterized from the COLOR FILL layers. So they have only one color, that is a known factor. Moreover the layers can be like a border, the inside part can be transparent, like layer 4.
Getting the colors from the SOLID FILL layers is very easy, but for NORMAL layers we need to check the average color or the most prominent color.
We have the code for picking up the most prominent color from a document from my earlier post -
https://community.adobe.com/t5/photoshop-ecosystem-discussions/adobe-script-selecting-the-most-prominent-color-from-a-psd-layer/m-p/14056020#M751617
But the above mentioned code is for picking up the most prominent color from the whole document, and not from a layer. Hence I am not able to use this code for my purpose. I have spent a lot of time to modify the above code for my purpose, it is now looping through all the layers, but it's a nasty code; it needs a lot of modification. But since it's AM code, it's beyound my knowledge 🙂 Also it's not working properly. For the 4th layer, it is showing that the most prominent color is the white, because it's flattening the layers. So I need to delete the background layer. Then it would give me the most prominent color. I tried to delete the background layers, but I am not able to. How can I delete the background layer from the temp file colors.raw??? My code -
const DE_THRESHOLD = 15, RESIZE_TO = 35;
for (var x=0; x<app.activeDocument.layerSets.length; x++) {
var layerSet = app.activeDocument.layerSets[x];
if (layerSet.name=="Images" || layerSet.name=="Images_1" || layerSet.name=="Images_2") {
for (var layerIndex = 0; layerIndex < layerSet.layers.length; layerIndex++) {
var layer = layerSet.layers[layerIndex];
app.activeDocument.activeLayer = layer;
var bounds = layer.bounds;
var width = bounds[2].value - bounds[0].value;
var height = bounds[3].value - bounds[1].value;
app.documents.add( width, height, 300, "temp",NewDocumentMode.RGB, DocumentFill.WHITE,1.0, BitsPerChannelType.EIGHT, "Adobe RGB (1998)" );
app.activeDocument = app.documents[0];
var idslct = charIDToTypeID( "slct" );
var desc219 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref1 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
ref1.putName( idLyr, layer.name);
desc219.putReference( idnull, ref1 );
var idMkVs = charIDToTypeID( "MkVs" );
desc219.putBoolean( idMkVs, false );
var idLyrI = charIDToTypeID( "LyrI" );
var list4 = new ActionList();
list4.putInteger( 13 );
desc219.putList( idLyrI, list4 );
executeAction( idslct, desc219, DialogModes.NO );
// =======================================================
var idDplc = charIDToTypeID("Dplc");
var desc585 = new ActionDescriptor();
var idnull = charIDToTypeID("null");
var ref123 = new ActionReference();
var idLyr = charIDToTypeID("Lyr ");
var idOrdn = charIDToTypeID("Ordn");
var idTrgt = charIDToTypeID("Trgt");
ref123.putEnumerated(idLyr, idOrdn, idTrgt);
desc585.putReference(idnull, ref123);
var idT = charIDToTypeID("T ");
var ref124 = new ActionReference();
var idDcmn = charIDToTypeID("Dcmn");
ref124.putName(idDcmn, "temp");
desc585.putReference(idT, ref124);
var idNm = charIDToTypeID("Nm ");
desc585.putString(idNm, layer.name);
var idVrsn = charIDToTypeID("Vrsn");
desc585.putInteger(idVrsn, 5);
var idIdnt = charIDToTypeID("Idnt");
var list62 = new ActionList();
list62.putInteger(112);
list62.putInteger(113);
list62.putInteger(114);
list62.putInteger(115);
desc585.putList(idIdnt, list62);
executeAction(idDplc, desc585, DialogModes.NO);
app.activeDocument = app.documents[1];
// var doc = app.activeDocument;
// for (var x = 0; x < app.activeDocument.layers.length; x++) {
// if (app.activeDocument.activeLayer.isBackgroundLayer) {
// app.activeDocument.activeLayer.remove();
// x=x-1;
// }
// }
var apl = new AM('application'),
doc = new AM('document');
// doc=app.activeDocument;
for (var x = 0; x < app.activeDocument.layers.length; x++) {
if (app.activeDocument.activeLayer.isBackgroundLayer) {
app.activeDocument.activeLayer.remove();
}
}
if (apl.getProperty('numberOfDocuments')) {
var docRes = doc.getProperty('resolution'),
docW = doc.getProperty('width') * docRes / 72,
docH = doc.getProperty('height') * docRes / 72;
doc.duplicate();
doc.resize(docW > docH ? 'width' : 'height', RESIZE_TO);
var f = new File(Folder.temp + '/colors.raw');
// doc.flatten();
doc.saveToRAW(f);
doc.close('no');
// for (var x = 0; x < app.activeDocument.layers.length; x++) {
// if (app.activeDocument.activeLayer.isBackgroundLayer) {
// app.activeDocument.activeLayer.remove();
// x=x-1;
// }
// }
var colors = findColors(f);
// alert (colors);
// alert (colors[0]);
// alert (colors[1]);
// alert (colors[2]);
// f.remove();
for (var i = 0; i < colors.length; i++) {
colors[i][3] = 0;
for (var x = 0; x < colors.length; x++) {
if (x != i && dE(colors[i], colors[x]) <= DE_THRESHOLD) colors[i][3]++
}
}
var result = 0,
idx = null;
for (var i = 0; i < colors.length; i++) {
if (colors[i][3] >= result) { result = colors[i][3]; idx = i; }
}
// alert (result);
var c = new SolidColor;
c.rgb.red = colors[idx][0],
c.rgb.green = colors[idx][1],
c.rgb.blue = colors[idx][2];
foregroundColor = c;
// alert (c);
}
function findColors(f) {
var content = '';
if (f.exists) {
f.open('r');
f.encoding = "BINARY";
content = f.read();
f.close();
f.remove();
return colors = function (s) {
var m = [],
offset = 0;
do {
var c = [];
for (i = 0; i < 3; i++) {
var k = s.charCodeAt(offset + i);
c.push(k)
};
m.push(c)
offset += 3;
} while (offset < s.length)
return m;
}(content);
}
}
function dE(a, b) {
return Math.sqrt(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2) + Math.pow(a[2] - b[2], 2));
}
function AM(target) {
var s2t = stringIDToTypeID,
t2s = typeIDToStringID,
c2t = charIDToTypeID;
target = target ? s2t(target) : null;
this.getProperty = function (property, id, idxMode) {
property = s2t(property);
(r = new ActionReference()).putProperty(s2t('property'), property);
id != undefined ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id)) :
r.putEnumerated(target, s2t('ordinal'), s2t('targetEnum'));
return getDescValue(executeActionGet(r), property)
}
this.hasProperty = function (property, id, idxMode) {
property = s2t(property);
(r = new ActionReference()).putProperty(s2t('property'), property);
id ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id))
: r.putEnumerated(target, s2t('ordinal'), s2t('targetEnum'));
return executeActionGet(r).hasKey(property)
}
this.resize = function (dimension, value) {
(d = new ActionDescriptor()).putUnitDouble(s2t(dimension), s2t("pixelsUnit"), value);
d.putBoolean(s2t("constrainProportions"), true);
d.putEnumerated(c2t("Intr"), s2t("interpolationType"), s2t("automaticInterpolation"));
executeAction(s2t("imageSize"), d, DialogModes.NO);
}
this.flatten = function () {
executeAction(s2t("flattenImage"), new ActionDescriptor(), DialogModes.NO);
}
this.saveToRAW = function (f) {
(d = new ActionDescriptor()).putBoolean(s2t('copy'), true);
(d1 = new ActionDescriptor()).putObject(s2t("as"), s2t("rawFormat"), d);
d1.putPath(s2t("in"), f);
executeAction(s2t("save"), d1, DialogModes.NO);
}
this.duplicate = function () {
(r = new ActionReference()).putEnumerated(target, s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putReference(s2t("null"), r);
executeAction(s2t("duplicate"), d, DialogModes.NO);
}
this.close = function (yesNo) {
(d = new ActionDescriptor()).putEnumerated(s2t("saving"), s2t("yesNo"), s2t(yesNo));
executeAction(s2t("close"), d, DialogModes.NO);
}
function getDescValue(d, p) {
switch (d.getType(p)) {
case DescValueType.OBJECTTYPE: return { type: t2s(d.getObjectType(p)), value: d.getObjectValue(p) };
case DescValueType.LISTTYPE: return d.getList(p);
case DescValueType.REFERENCETYPE: return d.getReference(p);
case DescValueType.BOOLEANTYPE: return d.getBoolean(p);
case DescValueType.STRINGTYPE: return d.getString(p);
case DescValueType.INTEGERTYPE: return d.getInteger(p);
case DescValueType.LARGEINTEGERTYPE: return d.getLargeInteger(p);
case DescValueType.DOUBLETYPE: return d.getDouble(p);
case DescValueType.ALIASTYPE: return d.getPath(p);
case DescValueType.CLASSTYPE: return d.getClass(p);
case DescValueType.UNITDOUBLE: return (d.getUnitDoubleValue(p));
case DescValueType.ENUMERATEDTYPE: return { type: t2s(d.getEnumerationType(p)), value: t2s(d.getEnumerationValue(p)) };
default: break;
};
}
}
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
}
}
So can you please modify this code so that it can currectly pickup the colors in all the cases?
Thanks in advance...