Copy link to clipboard
Copied
There are various ways to delete all layers that are empty, but is there a script which can detect if the "selected" layer is empty, and if so, delete it?
Thanks!
Jeff
4 Correct answers
var layer = //your code to get the selected layer the way you need it
//check if layer can be removed (ie: is not locked & has no linked layers)
if(!( layer.allLocked || layer.pixelsLocked || layer.positionLocked || layer.transparentPixelsLocked ||(0 != layer.linkedLayers.
...
Adding to the fantastic code from Jef_Bracke1:
var layer = app.activeDocument.activeLayer;
var layerName = layer.name;
// check if layer can be removed (ie: is not locked & has no linked layers)
if (!(layer.allLocked || layer.pixelsLocked || layer.positionLocked || layer.transparentPixelsLocked || (0 !== layer.linkedLayers.length))) { // linked
// check if text & if text, if also empty or if width/height == 0 (ie nothing on the layer)
if ((LayerKind.TEXT === layer.kind && "" === layer
...
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayersIDs"));
r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var list = executeActionGet(r).getList(stringIDToTypeID("targetLayersIDs"));
var selected = new Array();
var ids = new Array();
for (var i = 0; i < list.count; i++) selected.push(list.getReference(i).getIdentifier());
f
Option for CS6
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayers"));
r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var list = executeActionGet(r).getList(stringIDToTypeID("targetLayers"));
var selected = new Array();
var ids = new Array();
for (var i = 0; i < list.count; i++) selected.push(list.getReference(i).getIndex());
for (var i = 0; i < selected.length; i++)
{
...
Explore related tutorials & articles
Copy link to clipboard
Copied
Doesn't the "Delete All Empty layers" script shipped with PS work for you.
-Manan
Copy link to clipboard
Copied
Thanks Manan,
I have several layers that are empty, which i need to keep.
This action is part of a larger script.
For this part, it focuses on a selected layer, and remove it, if empty.
Thanks
Jeff
Copy link to clipboard
Copied
var layer = //your code to get the selected layer the way you need it
//check if layer can be removed (ie: is not locked & has no linked layers)
if(!( layer.allLocked || layer.pixelsLocked || layer.positionLocked || layer.transparentPixelsLocked ||(0 != layer.linkedLayers.length))){ // linked
//check if text & if text, if also empty or if width/height == 0 (ie nothing on the layer)
if((LayerKind.TEXT == layer.kind && "" == layer.textItem.contents) || ( 0 == layer.bounds[2] && (0 == layer.bounds[3])) ) {
// remove layer
layer.remove();
}
}
Copy link to clipboard
Copied
Wouldn’t
( 0 == layer.bounds[2] && (0 == layer.bounds[3])
theoretically also identify Layers that are off-canvas and the lower right corner of whic is exactly in the top left corner of the canvas?
Copy link to clipboard
Copied
Thank you for the help!
.. but, being the noob that i am, and many failed attempts, not sure how i can indicate this to work with the selected layer?
Any suggestions?
Thanks!
Copy link to clipboard
Copied
Adding to the fantastic code from Jef_Bracke1:
var layer = app.activeDocument.activeLayer;
var layerName = layer.name;
// check if layer can be removed (ie: is not locked & has no linked layers)
if (!(layer.allLocked || layer.pixelsLocked || layer.positionLocked || layer.transparentPixelsLocked || (0 !== layer.linkedLayers.length))) { // linked
// check if text & if text, if also empty or if width/height == 0 (ie nothing on the layer)
if ((LayerKind.TEXT === layer.kind && "" === layer.textItem.contents) || (0 === layer.bounds[2] && (0 === layer.bounds[3]))) {
// remove layer
layer.remove();
alert('Active layer "' + layerName + '" removed!');
}
else {
alert('This layer is not empty!');
}
}
Copy link to clipboard
Copied
Hahaha, nuts, almost got a right solution there... 🙂
I left the activeLayer part out on purpose to encourage OP to get acquainted with the Photoshop Scripting Reference.
For OP: the following link takes you to Photoshop Scripting documentation.
Alternatively, the following link presents the same information in a slightly different way. Somehow, when I'm stuck using the first link, my brain "gets it" using this one: (I suppose it doesn't make any sense, but it works for me)
If you're ever stuck on something, it often pays off to go to either one and look around.
Another link I can highly recommend is this one which deals less with Photoshop and more with "how to code/script"
Good luck almost namesake!
Copy link to clipboard
Copied
I gave the OP a break, it wasn't so long ago that I was there too, it will all come with time and more critically with experience.
Copy link to clipboard
Copied
Your compasion graces you.
It makes sense, I'll keep that in mind, thanks.
Also: 1st solution! A celebratory cup of coffee is due. 😉
Copy link to clipboard
Copied
As a relative scripting newb, I understand how easy it is to "miss the obvious"!
Copy link to clipboard
Copied
I marked Jef's reply as the correct answer, my additions to the base code were superficial.
Copy link to clipboard
Copied
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayersIDs"));
r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var list = executeActionGet(r).getList(stringIDToTypeID("targetLayersIDs"));
var selected = new Array();
var ids = new Array();
for (var i = 0; i < list.count; i++) selected.push(list.getReference(i).getIdentifier());
for (var i = 0; i < selected.length; i++)
{
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("bounds"));
r.putIdentifier(stringIDToTypeID("layer"), selected[i]);
var bounds = executeActionGet(r).getObjectValue(stringIDToTypeID("bounds"));
var x0 = bounds.getUnitDoubleValue(stringIDToTypeID("left"));
var x1 = bounds.getUnitDoubleValue(stringIDToTypeID("right"));
var y0 = bounds.getUnitDoubleValue(stringIDToTypeID("top"));
var y1 = bounds.getUnitDoubleValue(stringIDToTypeID("bottom"));
if (!x0 && !x1 && !y0 && !y1) ids.push(selected[i]);
}
if (ids.length)
{
var r = new ActionReference();
for (var i = 0; i < ids.length; i++) r.putIdentifier(stringIDToTypeID("layer"), ids[i]);
var d = new ActionDescriptor();
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("delete"), d, DialogModes.NO);
}
Copy link to clipboard
Copied
Thanks for the help, and scripts!
Stephen_A_Marsh, The addition was just what i needed to make it work, Thanks!
r-bin, Also, thanks for the script!, Although it gave me this error.
"- The command 'Get' is not currently available.
Line: 5"
Thanks again for all the help!
Jeff
Copy link to clipboard
Copied
But it is possible to remake.
Copy link to clipboard
Copied
I'm using CS6.. lol
Thanks!
Copy link to clipboard
Copied
Option for CS6
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayers"));
r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var list = executeActionGet(r).getList(stringIDToTypeID("targetLayers"));
var selected = new Array();
var ids = new Array();
for (var i = 0; i < list.count; i++) selected.push(list.getReference(i).getIndex());
for (var i = 0; i < selected.length; i++)
{
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("bounds"));
r.putIndex(stringIDToTypeID("layer"), selected[i]);
var bounds = executeActionGet(r).getObjectValue(stringIDToTypeID("bounds"));
var x0 = bounds.getUnitDoubleValue(stringIDToTypeID("left"));
var x1 = bounds.getUnitDoubleValue(stringIDToTypeID("right"));
var y0 = bounds.getUnitDoubleValue(stringIDToTypeID("top"));
var y1 = bounds.getUnitDoubleValue(stringIDToTypeID("bottom"));
if (!x0 && !x1 && !y0 && !y1) ids.push(selected[i]);
}
if (ids.length)
{
var r = new ActionReference();
for (var i = 0; i < ids.length; i++) r.putIndex(stringIDToTypeID("layer"), ids[i]);
var d = new ActionDescriptor();
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("delete"), d, DialogModes.NO);
}
Copy link to clipboard
Copied
Thanks, r-bin!
I'll test this when im back home.
Cheers!
Copy link to clipboard
Copied
In case you were not able to be back home I marked previous answer as working solution 😉