Copy link to clipboard
Copied
The Task is to have a codesnippet that i can inject in other scripts for Photoshop doing the following:
Merge the first Layer (also possible to have a fixed name e.g. "WATERMARK")
on each layer below (picture 1 to picture 100).
The names of the layers should still be the same as they where before merging.
can anyone help me with this?
i know that i can do an action for this and batchprocess this task, but i have a script running that only misses that one step before saving all the files with their correct name + adding width_x_height_px.
thanks in advance
Copy link to clipboard
Copied
Then you need to duplicate the top Layer times the number of other layers, move one duplicate in front of each of those other layers and merge.
Selecting a Layer and merging it to the Layer below should maintain the lower Layer’s name anyway.
Copy link to clipboard
Copied
thanks for your reply - adding a layer on top and merging, gives the new layer the same name as the layer on top 😉
Copy link to clipboard
Copied
Not here.
Copy link to clipboard
Copied
Anyway, which part of the process gives you problems in Scripting?
Copy link to clipboard
Copied
My merge down does the following
Copy link to clipboard
Copied
Not mentioning relevant details makes it hard to get meaningful advice.
You had mentioned neither Groups nor Smart Objects.
Copy link to clipboard
Copied
you could ignore the group.. and also the smartobject.. it all could be the same like in your file - flatten down image layers.. no problem
Copy link to clipboard
Copied
i need a script that does the merging of that white watermark frame on each image below...
without changing the name of the image..
Copy link to clipboard
Copied
i need a script that does the merging of that white watermark frame on each image below...
without changing the name of the image..
What specifically is giving you problems in writing up the operation?
If something isn’t available in DOM you can try using ScriptingListener.plugin to record AM-code and wrap that in a function.
Copy link to clipboard
Copied
the problem is.. i am no coder and have no clue how to write an operation that does this for me..
take the first layer (watermark)
put in on each layer in this file
and keep the name of the layer u merged the watermark to.
i am a graphic designer.. not a coder 😞
Copy link to clipboard
Copied
@defaultzgaeia0p3ind - I'd suggest cropped screenshots of the layers panel, before and after... And or a sample PSD layered file to clearly illustrate your post.
Edit: are your layers inside one or more groups/artboards/frames?
Copy link to clipboard
Copied
does that help?
you see the "watermark" layer - i need this to be merged with all the layers below.. indivdual. and keep the name of the lower layers
Copy link to clipboard
Copied
dont get distracted by the smartobjects.. or folders.. it could also be flat layers and no folders
Copy link to clipboard
Copied
Ok, but knowing that there may possibly be groups to drill into is important to know (same for smart objects). These "insignificant" details matter as they are not insignificant to the process. It is best to build a flexible, robust script that takes all known factors into account.
Copy link to clipboard
Copied
they dont have to be there.. any solution to the main problem is welcomed.. no groups or smartobjects needet
Copy link to clipboard
Copied
Try this script, it works with groups and smart objects (which are merged) and offers a single history step. The WATERMARK layer is removed, however, it can be easily retained if you prefer to keep it.
/*
Apply Watermark Layer to All Layers.jsx
v1.0 - 5th April 2023, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-to-merge-top-layer-to-each-layer-below/td-p/13704761
*/
#target photoshop
function main() {
if (!documents.length) {
alert('There are no documents open!');
} else {
//activeDocument.activeLayer = activeDocument.layers["WATERMARK"];
selectWatermarkLayer("WATERMARK");
activeDocument.selection.selectAll();
activeDocument.selection.copy();
activeDocument.selection.deselect();
activeDocument.activeLayer.remove();
processAllLayersAndSets(app.activeDocument);
}
function processAllLayersAndSets(obj) {
// Process Layers
for (var i = obj.artLayers.length - 1; 0 <= i; i--) {
app.activeDocument.activeLayer = obj.artLayers[i];
applyWatermarkLayer();
}
// Process Layer Set Layers
for (var i = obj.layerSets.length - 1; 0 <= i; i--) {
processAllLayersAndSets(obj.layerSets[i]);
}
}
function applyWatermarkLayer() {
activeDocument.paste();
selectActAndPrevLayers();
groupFromLayers();
var theName = activeDocument.activeLayer.layers[activeDocument.activeLayer.layers.length - 1].name;
activeDocument.activeLayer.name = theName;
activeDocument.activeLayer.merge();
}
app.purge(PurgeTarget.CLIPBOARDCACHE);
}
activeDocument.suspendHistory('Apply Watermark Layer to All Layers...', 'main()');
///// FUNCTIONS /////
function selectActAndPrevLayers() {
function s2t(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( s2t( "null" ), reference );
descriptor.putEnumerated( s2t( "selectionModifier" ), s2t( "selectionModifierType" ), s2t( "addToSelection" ));
descriptor.putBoolean( s2t( "makeVisible" ), false );
descriptor.putList( s2t( "layerID" ), list );
executeAction( s2t( "select" ), descriptor, DialogModes.NO );
}
function groupFromLayers() {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putClass( s2t( "layerSection" ));
descriptor.putReference( s2t( "null" ), reference );
reference2.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "from" ), reference2 );
descriptor2.putString( s2t( "name" ), "Temp" );
descriptor.putObject( s2t( "using" ), s2t( "layerSection" ), descriptor2 );
descriptor.putString( s2t( "name" ), "Temp" );
executeAction( s2t( "make" ), descriptor, DialogModes.NO );
}
function selectWatermarkLayer(theLayerName) {
// Works even if no layers are currently selected!
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
var list = new ActionList();
var reference = new ActionReference();
reference.putName( s2t( "layer" ), theLayerName );
descriptor.putReference( s2t( "null" ), reference );
descriptor.putBoolean( s2t( "makeVisible" ), false );
list.putInteger( 15 );
descriptor.putList( s2t( "layerID" ), list );
executeAction( s2t( "select" ), descriptor, DialogModes.NO );
}
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html#Photoshop
Copy link to clipboard
Copied
Your Script works like a charm.. in the meantime i tried to get CHATGPT to do something similar.. but it produced errors .. yours works on the first try and does exactly what i wanted.. want to try @c.pfaffenbichler Version now. 🙂 thank so much for your time and effort
Copy link to clipboard
Copied
in the meantime i tried to get CHATGPT to do something similar..
I consider this approach not sensible at current.
Copy link to clipboard
Copied
// merge copies of layer named "watermark" to all other layers;
// 2023, use it at your own risk;
if (app.documents.length > 0) {
// revert for testing;
executeAction( stringIDToTypeID( "revert" ), undefined, DialogModes.NO );
var theLayers = collectLayersAndLayerOfName("watermark");
var theseLayers = theLayers[1];
// process layers;
if (theLayers[0].length == 1) {
for (var m = theseLayers.length - 1; m >= 0; m--) {
if (isSmartObject(theseLayers[m][2]) == true) {
rasterizeSmartObject(theseLayers[m][2]);
};
duplicateMoveLayerTo (theLayers[0][0][2], theseLayers[m][2]);
// merge;
var desc2 = new ActionDescriptor();
executeAction( stringIDToTypeID( "mergeLayersNew" ), desc2, DialogModes.NO );
}
} else {alert ("please do it properly")}
};
////////////////////////////////////
////// collect layers and layer with certain name //////
function collectLayersAndLayerOfName (waterMark) {
// get number of layers;
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
var theWaterMarks = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
var isSmartObject = layerDesc.hasKey(stringIDToTypeID("smartObject"));
// check name;
if (theName == waterMark) {theWaterMarks.push([theName, theIndex, theID, isSmartObject])}
else {theLayers.push([theName, theIndex, theID, isSmartObject])};
};
}
catch (e) {};
}
return [theWaterMarks, theLayers]
};
////// based on code by mike hale and paul riggott //////
function selectLayerByID(theID,add){
add = undefined ? add = false:add
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), theID);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
try{
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message);
}
};
////// move active layer in front of other layer in layer stack //////
function duplicateMoveLayerTo (thisLayerId, targetId) {
selectLayerByID(thisLayerId, false);
var idlayer = stringIDToTypeID( "layer" );
var desc58 = new ActionDescriptor();
var ref19 = new ActionReference();
ref19.putEnumerated( idlayer, stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
desc58.putReference( stringIDToTypeID( "null" ), ref19 );
var ref20 = new ActionReference();
ref20.putIndex( idlayer, getLayerIndex(targetId)+1 );
desc58.putReference( stringIDToTypeID( "to" ), ref20 );
desc58.putBoolean( stringIDToTypeID( "adjustment" ), false );
desc58.putInteger( stringIDToTypeID( "version" ), 5 );
var list11 = new ActionList();
list11.putInteger(thisLayerId);
desc58.putList( stringIDToTypeID( "layerID" ), list11 );
desc58.putBoolean( stringIDToTypeID( "duplicate" ), true );
executeAction( stringIDToTypeID( "move" ), desc58, DialogModes.NO );
};
////// by mike hale, via paul riggott //////
function getLayerIndex(theId){
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('itemIndex'));
ref.putIdentifier(charIDToTypeID("Lyr "), theId);
d = executeActionGet(ref);
return (d.getInteger(stringIDToTypeID('itemIndex'))-1);
};
////// is smart object //////
function isSmartObject (theId) {
var ref = new ActionReference();
ref.putProperty (stringIDToTypeID ("property"), stringIDToTypeID ("smartObject"));
ref.putIdentifier( charIDToTypeID("Lyr "), theId );
var layerDesc = executeActionGet(ref);
var isSmartObject = layerDesc.hasKey(stringIDToTypeID("smartObject"));
return isSmartObject
};
////// rasterize the so //////
function rasterizeSmartObject (aLayer) {
selectLayerByID(aLayer, false);
// rasterize the so;
try {
var desc125 = new ActionDescriptor();
var ref83 = new ActionReference();
ref83.putEnumerated( charIDToTypeID( "Mn " ), charIDToTypeID( "MnIt" ), stringIDToTypeID( "rasterizePlaced" ) );
desc125.putReference( charIDToTypeID( "null" ), ref83 );
executeAction( charIDToTypeID( "slct" ), desc125, DialogModes.NO );
return app.activeDocument.activeLayer
} catch (e) {alert (e)}
};
Copy link to clipboard
Copied
your script does the action 1 time - deletes all the other layers - and then tells me to do it properly 🙂 ,
i have a layer called watermark (all smallcaps) - what am i missing? do the layers need to have a specific name? or do they need to be in a "Group1" Folder? Thanks for your time btw..i really aprecciate it!.