• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Deleting layers with a special suffix

New Here ,
Jan 19, 2021 Jan 19, 2021

Copy link to clipboard

Copied

Hi everybody,

 

I am a 3D Artist and working with Photoshop mainly to edit my renderings. Due to an update, I am now getting renderings with many different layers for the same thing, which I don't need. Unfortunately, I cannot switch them off in the renderer, so I either have to delete them by hand or what I thought would be very helpfull, if I could do it over a script or an action. 

 

I was wondering if anyone of you has an idea, what would be the best way to do this. Let me just describe the process.

 

1.) I render a psd file which contains for example the following layers:

-flower

-flower_filter

-flower_alpha

-grass

-grass_filter

-grass_alpha

-sky

-sky_filter

-sky_alpha

background

 

The names and numbers of the layers can vary (although the group of 3 is always the same). I can name them any way I want. Only the background is a fixed name, which will always be the same. 

 

I only need the layers "background" and the ones with the suffix "_alpha". So is there some way, to say, that all layers, except of "background" and "_alpha" will be deleted?

 

I would really appreciate any hints and help, as I am not 100% sure how to start.

 

Thanks a lot and have a nice evening

TOPICS
Actions and scripting

Views

644

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 Expert ,
Jan 19, 2021 Jan 19, 2021

Copy link to clipboard

Copied

In a script you can get an array of the all the layers object. Them process the layers array delete layers that are not the background without a layer name the suffix _alpha. Only the bottom layer can be a background layer and there is a bit that indicated its a  Background Layer a document could have many layers with the name Background. Layer Names need not be unique.

JJMack

Votes

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
Community Expert ,
Jan 19, 2021 Jan 19, 2021

Copy link to clipboard

Copied

Method 1

Click layer "-flower", hold shift and click on layer "-sky_filter" to make a continuous selection of those layers. Then Ctrl click on the layers with named "alpha" to deselect them.

 

You now have the layer selected you want to delete, so click on the trash can icon bottom right of layers palette.

 

Method 2

Screen Shot 2021-01-19 at 5.32.00 PM.png

Change Kind to Name, then input _alpha

Click folder icon to put these in a group

Screen Shot 2021-01-19 at 5.32.14 PM.png

Change Name back to Kind

Select all layers except the layer group and background then delete layers.

 

Votes

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
New Here ,
Jan 21, 2021 Jan 21, 2021

Copy link to clipboard

Copied

Hello you two, 

 

thanks a lot for you answer. Both methods are really good, although I am prefering the first one, as it seems, that this can be done through a script and I don't have to select at every new file the layers by hand.

 

Do you know some good resources for scripting in Photoshop? I am pretty new to this.

 

Have a nice evening and thanks a lot for you help.

Votes

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
Community Expert ,
Jan 21, 2021 Jan 21, 2021

Copy link to clipboard

Copied

adobe intro to scripting 

Scripting Resources 

This Forum....

There are some Samples and Tutorials on the Web Google search

 

This script may help you get started.

/* ==========================================================
// 2017  John J. McAssey (JJMack) 
// ======================================================= */
// This script is supplied as is. It is provided as freeware. 
// The author accepts no liability for any problems arising from its use.
// enable double-clicking from Mac Finder or Windows Explorer
#target photoshop // this command only works in Photoshop CS2 and higher
// bring application forward for double-click events
app.bringToFront();
// ensure at least one document open
if (!documents.length) alert('There are no documents open.', 'No Document');
else {
	// declare Global variables
	var allLayers = ""; 
	//main(); // at least one document exists proceed
    app.activeDocument.suspendHistory('Some Process Name','main()');
}
///////////////////////////////////////////////////////////////////////////////
//                            main function                                  //
///////////////////////////////////////////////////////////////////////////////
function main() {
	// declare local variables
	var orig_ruler_units = app.preferences.rulerUnits;
	var orig_type_units = app.preferences.typeUnits;
	var orig_display_dialogs = app.displayDialogs;
	app.preferences.rulerUnits = Units.PIXELS;  	// Set the ruler units to PIXELS
	app.preferences.typeUnits = TypeUnits.POINTS;   // Set Type units to POINTS
	app.displayDialogs = DialogModes.NO;	    	// Set Dialogs off
	try { code(); }
	// display error message if something goes wrong
	catch(e) { alert(e + ': on line ' + e.line, 'Script Error', true); }
	alert(allLayers);
	app.displayDialogs = orig_display_dialogs;  	// Reset display dialogs 
	app.preferences.typeUnits  = orig_type_units;	// Reset ruler units to original settings 
	app.preferences.rulerUnits = orig_ruler_units;	// Reset units to original settings
}
///////////////////////////////////////////////////////////////////////////////
//                           main function end                               //
///////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////
// The real code is embedded into this function so that at any point it can return //
// to the main line function to let it restore users edit environment and end      //
/////////////////////////////////////////////////////////////////////////////////////
function code() {
	processArtLayers(activeDocument) 
}
function processArtLayers(obj) {  
    for( var i = obj.artLayers.length-1; 0 <= i; i--) {/* alert(obj.artLayers[i]); */processLayers(obj.artLayers[i])}  
    for( var i = obj.layerSets.length-1; 0 <= i; i--) {/* alert(obj.layerSets[i]); */processArtLayers(obj.layerSets[i])} // Process Layer Set Layers  
} 
function processLayers(layer) { 
	//alert('Layer Name = "' + layer.name + '" Layer Kind ' + layer.kind );
	allLayers = allLayers + "ID " + layer.id + ", " + layer.name + ", " + layer.kind + "\n";
	switch (layer.kind){
	case LayerKind.SMARTOBJECT : processSmartObj(layer); break;
	default : break; // none process layer types catch all
	}
} 
//////////////////////////////////////////////////////////////////////////////////
//			Layer Type Functions					//
//////////////////////////////////////////////////////////////////////////////////
function processSmartObj(obj) { 
//	alert('Smart Object = "' + obj.name + '"');
	var localFilePath = "";
	var ref = new ActionReference();    
    ref.putIdentifier(charIDToTypeID('Lyr '), obj.id );    
    var desc = executeActionGet(ref);  
	//alert(actionDescriptor(desc));
    var smObj = desc.getObjectValue(stringIDToTypeID('smartObject'));  
	//alert(actionDescriptor(smObj));	
	try {
		//alert(obj_to_str(smObj), "Object Properties"); 
		//var thePlace = smObj.getEnumerationType(stringIDToTypeID('place'));
		var theDocumentID = smObj.getString(stringIDToTypeID('documentID'));
		//var theCompsList = smObj.getObjectPropertyType(stringIDToTypeID('compsList'));
		var theLinked = smObj.getBoolean(stringIDToTypeID("linked"));
		var theFileReference = smObj.getString(stringIDToTypeID("fileReference"));
		alert(["Smart Object Layer " + obj.name, "\n" + theDocumentID, "\nLinked=" + theLinked, "File='" + theFileReference + "'" ]);
	}
	catch(e) {alert(e);}
	return localFilePath;
}

// Thanks to  r-bin
function obj_to_str(obj){var str = ""; for (var p in obj) if(obj.hasOwnProperty(p))try{str+=p+"::"+obj[p]+"\n";}catch(e){};return str;}  

// Thanks to SuperMerlin

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function actionDescriptor(desc){  
	if(desc.typename == 'ActionDescriptor'){  
		var c = desc.count;  
		var msg= "Action Descriptor Item Count = " + c;
		for(var i=0;i<c;i++){ //enumerate descriptor's keys  
			//$.writeln('AD '+zeroPad( i+1, 2 )+' = '+IDTz(desc.getKey(i)) +' : '+desc.getType(desc.getKey(i)));   
			msg =  msg + "\n" + 'AD '+zeroPad( i+1, 2 )+' = '+IDTz(desc.getKey(i)) +' : '+desc.getType(desc.getKey(i)) ; 
		} 
    return msg; 
	}  
	function IDTz(id){  
		try {  
			var res = typeIDToStringID( id );  
			if(res == '' ){  
				var res = typeIDToCharID( id );  
			}  
		}
		catch(e){}  
		return res;  
	}  
	function zTID( s ){  
		if( s.length == 4 ) var res = charIDToTypeID( s );  
		if( s.length > 4 ) var res = stringIDToTypeID( s );  
		return res;  
	}  
	function zeroPad(num,pad) {  
		var z = Math.pow(10,Number(pad))  
		return num <= z ? ((Number( num) + z).toString().substr(1)): num  
	}  
};  
JJMack

Votes

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
Community Expert ,
Jan 21, 2021 Jan 21, 2021

Copy link to clipboard

Copied

I'm a beginner in scripting, this is rather advanced I'm afraid. I know what I want to do, however, after many hours of dead ends I have nothing. Looking forward to seeing how this will be handled!

Votes

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
Community Expert ,
Jan 22, 2021 Jan 22, 2021

Copy link to clipboard

Copied

Try this, as long as your layer stacking pattern is as described it should work:

 

/*

https://community.adobe.com/t5/photoshop/deleting-layers-with-a-special-suffix/m-p/11772325
Deleting layers with a special suffix

I really wanted to select layers using a regular expression:

/^((?!_alpha|Background).)*$/igm

However, I ended up writing a script based on the very specific layer stacking order pattern, which is far from ideal:

flower
flower_filter
flower_alpha *
grass
grass_filter
grass_alpha *
sky
sky_filter
sky_alpha *
Background

I believe that it gets the job done, even if it is inflexible and not the thing of beauty that I was hoping for...

*/


#target photoshop

// Layer count divided by 3, less 1
var layersLength = app.activeDocument.layers.length - 1;
var repeatValue = layersLength / 3 - 1;
//alert(repeatValue);

// Deselect all layers
app.runMenuItem(stringIDToTypeID('selectNoLayers'));

// Tidy up the first set of 3 layers
selectFrontLayer(false);
addSelectBackwardLayer(false);
removeSelectedLayers();

// Tidy up any remaining layer triplets
for (i = 0; i < repeatValue; i++) {
    repeatSteps();
}

// Here be functions

function removeSelectedLayers() {
    var c2t = function (s) {
        return app.charIDToTypeID(s);
    };

    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };

    var descriptor = new ActionDescriptor();
    var list = new ActionList();
    var reference = new ActionReference();

    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
    descriptor.putReference(c2t("null"), reference);
    list.putInteger(14);
    list.putInteger(15);
    descriptor.putList(s2t("layerID"), list);
    executeAction(s2t("delete"), descriptor, DialogModes.NO);
}

function selectFrontLayer(makeVisible) {
    var c2t = function (s) {
        return app.charIDToTypeID(s);
    };

    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };

    var descriptor = new ActionDescriptor();
    var list = new ActionList();
    var reference = new ActionReference();

    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("front"));
    descriptor.putReference(c2t("null"), reference);
    descriptor.putBoolean(s2t("makeVisible"), makeVisible);
    list.putInteger(15);
    descriptor.putList(s2t("layerID"), list);
    executeAction(s2t("select"), descriptor, DialogModes.NO);
}

function addSelectBackwardLayer(makeVisible) {
    var c2t = function (s) {
        return app.charIDToTypeID(s);
    };

    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };

    var descriptor = new ActionDescriptor();
    var list = new ActionList();
    var reference = new ActionReference();

    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("backwardEnum"));
    descriptor.putReference(c2t("null"), reference);
    descriptor.putEnumerated(s2t("selectionModifier"), s2t("selectionModifierType"), s2t("addToSelection"));
    descriptor.putBoolean(s2t("makeVisible"), makeVisible);
    list.putInteger(14);
    list.putInteger(15);
    descriptor.putList(s2t("layerID"), list);
    executeAction(s2t("select"), descriptor, DialogModes.NO);
}

function repeatSteps() {

    select(false);
    select2(false);
    delete2();

    function select(makeVisible) {
        var c2t = function (s) {
            return app.charIDToTypeID(s);
        };

        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };

        var descriptor = new ActionDescriptor();
        var list = new ActionList();
        var reference = new ActionReference();

        reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("backwardEnum"));
        descriptor.putReference(c2t("null"), reference);
        descriptor.putBoolean(s2t("makeVisible"), makeVisible);
        list.putInteger(12);
        descriptor.putList(s2t("layerID"), list);
        executeAction(s2t("select"), descriptor, DialogModes.NO);
    }

    function select2(makeVisible) {
        var c2t = function (s) {
            return app.charIDToTypeID(s);
        };

        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };

        var descriptor = new ActionDescriptor();
        var list = new ActionList();
        var reference = new ActionReference();

        reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("backwardEnum"));
        descriptor.putReference(c2t("null"), reference);
        descriptor.putEnumerated(s2t("selectionModifier"), s2t("selectionModifierType"), s2t("addToSelection"));
        descriptor.putBoolean(s2t("makeVisible"), makeVisible);
        list.putInteger(11);
        list.putInteger(12);
        descriptor.putList(s2t("layerID"), list);
        executeAction(s2t("select"), descriptor, DialogModes.NO);
    }

    function delete2() {
        var c2t = function (s) {
            return app.charIDToTypeID(s);
        };

        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };

        var descriptor = new ActionDescriptor();
        var list = new ActionList();
        var reference = new ActionReference();

        reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
        descriptor.putReference(c2t("null"), reference);
        list.putInteger(11);
        list.putInteger(12);
        descriptor.putList(s2t("layerID"), list);
        executeAction(s2t("delete"), descriptor, DialogModes.NO);
    }
}

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

 

Votes

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
Community Expert ,
Jan 22, 2021 Jan 22, 2021

Copy link to clipboard

Copied

I modified the script I posted to help you now to do what you want to do Keep the Background and Layers with a _alpha layer name suffix.  Basically a one line function.  Name this script "KeepBGandAlpha.jsx"    I removed the code that was not needed and added one line.

if ( !layer.isBackgroundLayer & layer.name.indexOf("_alpha")==-1 ) layer.remove();

 

To complete the Script you need to add a Save see if you cans figure where that code needs to added and where you want to save and name the  file for the modified document. If you save over the current document's backing  file a programming error could destroy your documents.

 

/* ==========================================================
// 2017  John J. McAssey (JJMack) 
// ======================================================= */
// This script is supplied as is. It is provided as freeware. 
// The author accepts no liability for any problems arising from its use.
// enable double-clicking from Mac Finder or Windows Explorer
#target photoshop // this command only works in Photoshop CS2 and higher
// bring application forward for double-click events
app.bringToFront();
// ensure at least one document open
if (!documents.length) alert('There are no documents open.', 'No Document');
else {
	// declare Global variables
	var allLayers = ""; 
	//main(); // at least one document exists proceed
    app.activeDocument.suspendHistory('Some Process Name','main()');
}
///////////////////////////////////////////////////////////////////////////////
//                            main function                                  //
///////////////////////////////////////////////////////////////////////////////
function main() {
	// declare local variables
	var orig_ruler_units = app.preferences.rulerUnits;
	var orig_type_units = app.preferences.typeUnits;
	var orig_display_dialogs = app.displayDialogs;
	app.preferences.rulerUnits = Units.PIXELS;  	// Set the ruler units to PIXELS
	app.preferences.typeUnits = TypeUnits.POINTS;   // Set Type units to POINTS
	app.displayDialogs = DialogModes.NO;	    	// Set Dialogs off
	try { code(); }
	// display error message if something goes wrong
	catch(e) { alert(e + ': on line ' + e.line, 'Script Error', true); }
	app.displayDialogs = orig_display_dialogs;  	// Reset display dialogs 
	app.preferences.typeUnits  = orig_type_units;	// Reset ruler units to original settings 
	app.preferences.rulerUnits = orig_ruler_units;	// Reset units to original settings
}
///////////////////////////////////////////////////////////////////////////////
//                           main function end                               //
///////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////
// The real code is embedded into this function so that at any point it can return //
// to the main line function to let it restore users edit environment and end      //
/////////////////////////////////////////////////////////////////////////////////////
function code() {
	processArtLayers(activeDocument) 
}
function processArtLayers(obj) {  
    for( var i = obj.artLayers.length-1; 0 <= i; i--) {processLayers(obj.artLayers[i])}  
    for( var i = obj.layerSets.length-1; 0 <= i; i--) {processArtLayers(obj.layerSets[i])}  
} 
function processLayers(layer) { 
	if ( !layer.isBackgroundLayer & layer.name.indexOf("_alpha")==-1 ) layer.remove();
}

 

 

 

 

 

JJMack

Votes

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
Community Expert ,
Jan 22, 2021 Jan 22, 2021

Copy link to clipboard

Copied

Nice work JJMack, that  indexOf  is what I was trying to do via a regualr expression and getting nowhere.

Votes

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
Community Expert ,
Jan 22, 2021 Jan 22, 2021

Copy link to clipboard

Copied

The thing is that is not a perfect test. The string "-alpha" could be anywhere in the File name and not be a suffix and that layer would not be deleted. To do a proper job you may be able to use  .lastIndexOf( "_alpha" ); and see if that value + the length of   "_alpha" equaled the length of the layer name. that it is a suffix.  But its their layer naming convention so what I coded will most likely be OK for  their use.  I'm dyslectic my eyes can not decipher a regular expression. So I did not even brother the learn the syntax rules for one.  Any regular expression in my code would be a copy and past job,

 

JJMack

Votes

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
Community Expert ,
May 24, 2021 May 24, 2021

Copy link to clipboard

Copied

LATEST

 

For what it is worth, with a few more months of experience the regular expression method came easy to me (regex was not the problem, the JS syntax was):

 

/*
Delete level based on first name
https://community.adobe.com/t5/photoshop/delete-level-based-on-first-name/td-p/12062329
*/

#target photoshop

function main() {
    // Call the function to process layers/layerSets
    processLayersAndSets(app.activeDocument);

    function processLayersAndSets(target) {
        // Loop through all layers
        for (var l = target.artLayers.length - 1; 0 <= l; l--) {
            // Call the removeLayer function
            removeLayer(target.artLayers[l]);
        }
        // Loop through all layer groups/sets
        for (var s = target.layerSets.length - 1; 0 <= s; s--) {
            // Call the removeLayer function
            processLayersAndSets(target.layerSets[s]);
        }
        // Remove non-background layers beginning with the word "test", case insensitive
        function removeLayer(layer) {
            if (!layer.isBackgroundLayer & layer.name.match(/^test\b/i) !== null) layer.remove();
        }
    }
}
app.activeDocument.suspendHistory("Run script", "main()");

 

Votes

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