Script that finds and removes all black layers.

Explorer ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

Hello,

I am looking for a script that can locate and delete all black layers in PS.

 

Layerstack.JPG

 

I don't know how to write Javascript, and I can't find any thread explaining how to do this.

I am looking for something that is similar to "Delete All Empty Layers" script, but that finds black layers instead.

 

Thank you for taking your time,

 

Tsu-tey

TOPICS
Actions and scripting

Views

368

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 2 Correct answers

Adobe Community Professional , Jul 02, 2021 Jul 02, 2021
sTT = stringIDToTypeID; function tggl() { (ref = new ActionReference()).putIdentifier(sTT('layer'), idntfr); (lst = new ActionList()).putReference(ref); (dsc = new ActionDescriptor()) .putList(sTT('null'), lst), dsc.putBoolean(sTT('toggleOptionsPalette'), true) executeAction(sTT('show'), dsc) } lrs = [].slice.call((aD = activeDocument).artLayers) wh = aD.width * aD.height; while(lrs.length) idntfr = (shft = lrs.shift()).id, tggl(), blck = aD.histogram[0] == wh, tggl(), blck && shft.rem...

Likes

Translate

Translate
Adobe Community Professional , Jul 03, 2021 Jul 03, 2021
Give an example. Upload your PSD file. Noticed that scripts (mine and yours) remove the black layer if there is one RGB pixel (0,0,1) in it, which is wrong. Corrected my script // important, the active layer must not have to be a group. var inv = false; // depends on channels settings. true = masked areas, false = selected areas. check what you have. var r = new ActionReference(); r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("count")); r.putEnumerated(stringIDToTypeID("lay...

Likes

Translate

Translate
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

Try this script (not CS6 compatible)

 

 

// important, the active layer must not have to be a group. 

var inv = true; // depends on channels settings. true = masked areas, false = selected areas. check what you have.


var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("count"));
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var count = executeActionGet(r).getInteger(stringIDToTypeID("count"));


var n = 0; 
try { app.activeDocument.backgroundLayer; } catch(e) { n = 1; ++count; }


var r_idx = new ActionReference();

for (var i = count-1; i >= n; i--)
    {
    var r = new ActionReference();
    r.putIndex(stringIDToTypeID("layer"), i);
    if (executeActionGet(r).getInteger(stringIDToTypeID("layerKind")) != 1) continue; 

    var d = new ActionDescriptor();
    var r = new ActionReference();
    r.putProperty(stringIDToTypeID("channel"), stringIDToTypeID("selection"));
    d.putReference(stringIDToTypeID("null"), r);
    var d1 = new ActionDescriptor();
    var r1 = new ActionReference();
    r1.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("gray"));
    r1.putIndex(stringIDToTypeID("layer"), i);
    d1.putBoolean(stringIDToTypeID("invert"), inv);
    d1.putReference(stringIDToTypeID("to"), r1);
    d1.putEnumerated(stringIDToTypeID("calculation"), stringIDToTypeID("calculationType"), stringIDToTypeID("linearDodge"));
    var r2 = new ActionReference();
    r2.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("gray"));
    r2.putIndex(stringIDToTypeID("layer"), i);
    d1.putReference(stringIDToTypeID("source2"), r2);
    d1.putBoolean(stringIDToTypeID("invertSource2"), inv);
    d.putObject(stringIDToTypeID("to"), stringIDToTypeID("calculation"), d1);
    executeAction(stringIDToTypeID("set"), d, DialogModes.NO);


    var r = new ActionReference();
    r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("selection"));
    r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));

    if (!executeActionGet(r).hasKey(stringIDToTypeID("selection")))  r_idx.putIndex(stringIDToTypeID("layer"), i);
    }

app.activeDocument.selection.deselect();

var d = new ActionDescriptor();
d.putReference(stringIDToTypeID("null"), r_idx);

executeAction(stringIDToTypeID("delete"), d, DialogModes.NO);

alert("done");

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

Error_8800.JPG

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

change true to false.

I'll fix the script yet. This also will be an error if there are no black layers.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

// important, the active layer must not have to be a group. 

var inv = false; // depends on channels settings. true = masked areas, false = selected areas. check what you have.


var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("count"));
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var count = executeActionGet(r).getInteger(stringIDToTypeID("count"));


var n = 0; 
try { app.activeDocument.backgroundLayer; } catch(e) { n = 1; ++count; }


var r_idx = new ActionReference();
var do_it = false;

for (var i = count-1; i >= n; i--)
    {
    var r = new ActionReference();
    r.putIndex(stringIDToTypeID("layer"), i);
    if (executeActionGet(r).getInteger(stringIDToTypeID("layerKind")) != 1) continue; 

    var d = new ActionDescriptor();
    var r = new ActionReference();
    r.putProperty(stringIDToTypeID("channel"), stringIDToTypeID("selection"));
    d.putReference(stringIDToTypeID("null"), r);
    var d1 = new ActionDescriptor();
    var r1 = new ActionReference();
    r1.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("gray"));
    r1.putIndex(stringIDToTypeID("layer"), i);
    d1.putBoolean(stringIDToTypeID("invert"), inv);
    d1.putReference(stringIDToTypeID("to"), r1);
    d1.putEnumerated(stringIDToTypeID("calculation"), stringIDToTypeID("calculationType"), stringIDToTypeID("linearDodge"));
    var r2 = new ActionReference();
    r2.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("gray"));
    r2.putIndex(stringIDToTypeID("layer"), i);
    d1.putReference(stringIDToTypeID("source2"), r2);
    d1.putBoolean(stringIDToTypeID("invertSource2"), inv);
    d.putObject(stringIDToTypeID("to"), stringIDToTypeID("calculation"), d1);
    executeAction(stringIDToTypeID("set"), d, DialogModes.NO);


    var r = new ActionReference();
    r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("selection"));
    r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));

    if (!executeActionGet(r).hasKey(stringIDToTypeID("selection")))  { r_idx.putIndex(stringIDToTypeID("layer"), i); do_it = true; }
    }

app.activeDocument.selection.deselect();

if (do_it)
    {
    var d = new ActionDescriptor();
    d.putReference(stringIDToTypeID("null"), r_idx);
    executeAction(stringIDToTypeID("delete"), d, DialogModes.NO);
    }

alert("done");

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

Awesome, thank you aswell 🙂

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

Ah, I will test it out.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

I found your script deletes all layers beside black ones and some layers with black elements 😕

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 03, 2021 Jul 03, 2021

Copy link to clipboard

Copied

Give an example. Upload your PSD file.

Noticed that scripts (mine and yours) remove the black layer if there is one RGB pixel (0,0,1) in it, which is wrong. Corrected my script

 

// important, the active layer must not have to be a group. 

var inv = false; // depends on channels settings. true = masked areas, false = selected areas. check what you have.


var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("count"));
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var count = executeActionGet(r).getInteger(stringIDToTypeID("count"));


var n = 0; 
try { app.activeDocument.backgroundLayer; } catch(e) { n = 1; ++count; }


var r_idx = new ActionReference();
var do_it = false;

for (var i = count-1; i >= n; i--)
    {
    var r = new ActionReference();
    r.putIndex(stringIDToTypeID("layer"), i);
    if (executeActionGet(r).getInteger(stringIDToTypeID("layerKind")) != 1) continue; 

    var d = new ActionDescriptor();
    var r = new ActionReference();
    r.putProperty(stringIDToTypeID("channel"), stringIDToTypeID("selection"));
    d.putReference(stringIDToTypeID("null"), r);
    var d1 = new ActionDescriptor();
    var r1 = new ActionReference();
    r1.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("gray"));
    r1.putIndex(stringIDToTypeID("layer"), i);
    d1.putBoolean(stringIDToTypeID("invert"), inv);
    d1.putReference(stringIDToTypeID("to"), r1);
    d1.putEnumerated(stringIDToTypeID("calculation"), stringIDToTypeID("calculationType"), stringIDToTypeID("normal"));
    var r2 = new ActionReference();
    r2.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("gray"));
    r2.putIndex(stringIDToTypeID("layer"), i);
    d1.putReference(stringIDToTypeID("source2"), r2);
    d1.putBoolean(stringIDToTypeID("invertSource2"), inv);
    d.putObject(stringIDToTypeID("to"), stringIDToTypeID("calculation"), d1);
    executeAction(stringIDToTypeID("set"), d, DialogModes.NO);


    var r = new ActionReference();
    r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("selection"));
    r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));

    if (!executeActionGet(r).hasKey(stringIDToTypeID("selection")))  { r_idx.putIndex(stringIDToTypeID("layer"), i); do_it = true; }
    }

app.activeDocument.selection.deselect();

if (do_it)
    {
    var d = new ActionDescriptor();
    d.putReference(stringIDToTypeID("null"), r_idx);
    executeAction(stringIDToTypeID("delete"), d, DialogModes.NO);
    }

alert("done");

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 03, 2021 Jul 03, 2021

Copy link to clipboard

Copied

The script I refered is 1st one you posted, however I'm saying now about probably updated version, but in the same post with that code. Create new document, add normal layer, fill it with black, then add another empty layer. That script will remove empty layer, but not black layer, while it should do the opposite.

 

The current one seems to work correctly. Why didn't you edit your first post, but created another posts with changed codes? It would be much better to have them in origianl one 😉

 

Good find about that 0, 0, 1 RGB values. That's probably because LAB is still 0, 0, 0. When you use 1, 0, 0 RGB values, the LAB is not changed again, so histogram must be refered to LAB?

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 03, 2021 Jul 03, 2021

Copy link to clipboard

Copied

It depends on the setting of the "inv" variable. Read the notes. It should match the channel settings (add a new alpha channel and check what settings you have). Either black or white (and blank) layers are removed.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 03, 2021 Jul 03, 2021

Copy link to clipboard

Copied

I changed inv to false (in first code) and it gives error. Well no matter. Your other code is ok 🙂

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 03, 2021 Jul 03, 2021

Copy link to clipboard

Copied

It does not take into account the lack of removable layers. Your code (and mine) will also give an error if all layers are black.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 03, 2021 Jul 03, 2021

Copy link to clipboard

Copied

LATEST

Probably author is not going to use documents with only black layers, he didn't want it 😉

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 03, 2021 Jul 03, 2021

Copy link to clipboard

Copied

Removed my answer as correct. Let the author decide for himself.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 03, 2021 Jul 03, 2021

Copy link to clipboard

Copied

Mark your last code as correct, I think it's good one.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

 

sTT = stringIDToTypeID; function tggl() {
	(ref = new ActionReference()).putIdentifier(sTT('layer'), idntfr);
	(lst = new ActionList()).putReference(ref); (dsc = new ActionDescriptor())
	.putList(sTT('null'), lst), dsc.putBoolean(sTT('toggleOptionsPalette'), true)
	executeAction(sTT('show'), dsc)
}

lrs = [].slice.call((aD = activeDocument).artLayers)
wh = aD.width * aD.height; while(lrs.length)
	idntfr = (shft = lrs.shift()).id, tggl(),
	blck = aD.histogram[0] == wh,
	tggl(), blck && shft.remove()

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

Kukurykus, what's this?

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

The solution 🙂

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

What does it do? The black layers are not removed from me.

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

I filled some layers with black colour, and the script I provided deletes only them.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

Not working for 2020. What is its working principle?

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

It makes visible only one layer at time. Then it checks if 1st cell of hitogram (that is reserved for black) is equal to document dimension. If it is, there are not any other colors, so the layer is fully black. Then it toogles previous visibility of layers, and if layer was black it gets deleted.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

What is toggleOptionsPalette?

 

upd.  I understood. But for some reason it doesn't work. 

 

upd2. For it to work, you need to put pixels in the ruler. Also does not work for layers in folders. Doesn't ignore adjustment layers. 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 02, 2021 Jul 02, 2021

Copy link to clipboard

Copied

'toggleOptionsPalette' is when you manually click on 'eye' of layer.

 

1) Like me, create new document. Add some layers, and fill some of them with black paint.

 

2) Yes that's right, for Pixels only and no layer sets. Original poster did not use Adjustment layers, but it works for them too, so I did it simple according posted image 😉

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
    • 1
    • 2