Copy link to clipboard
Copied
Hi!
I'm currently working on some automation in our workflow and updating Adjustment layers would be a big point on that list. We're editing our renderings with a bunch of pre-defined adjustment layers, where we can edit them manually. But if the rendering gets an update, we have to copy+paste all the values from the old file into the new file (with the new render output). For now I'm duplicating all the adjustment layers from the old file into the new one and then I update every single layer mask with some copy+paste frenzy.
While I already did improve some parts of the workflow with some basic JavaScript ... very basic, very trashy, but it gets the work done ... I'm really struggling with that part. It seems like getting / setting the values of each adjustment layer (talking about Curves, HueSat, Exposure, LUT, ...) is nearly impossible. Setting the values can be done with the stuff the Scripting Listeners spits out, but I realy have no clue how I would get the values in the same 'easy' way as the listener prints out. And even imitating the workflow I'm using right now - copy+pasting the new layer mask onto the old adjustment layers - isn't working. Same thing here: Scripting LIstener gives me some output, but I can't re-use anything of it?
Creating an Action could work, if the hierarchy is identical between the old and new file. But quite often there are some additional adjustment layers on top of all the default ones. And these layers would sabotage the PS Action I guess ...
Is this idea for a script really a little big or am I missing something? Maybe someone already did something similar? 🙂
Thanks anyway and have a nice day!
You can try the following v1.0 script.
I have updated the script to v1.1... I'm happy to make adjustments based on your feedback.
The first document opened must be the original render. The second document opened must be the new render.
/*
Update Render Adjustment Layers.jsx
Stephen Marsh
v1.1 - 3rd February 2025
https://community.adobe.com/t5/photoshop-ecosystem-discussions/ps-scripting-copy-paste-layer-mask-content-from-one-to-another/td-p/15127773
Note: The origi
...
Copy link to clipboard
Copied
Can you provide layered before and after PSD file examples? They don't need to be high resolution.
What is the source of the new layer mask content? How does this differ from the original?
Do the layer names change between different files, or are they consistent?
Do you only have 2 images open at a time?
Are you looking for a batch solution for bulk files rather than for two open images?
Copy link to clipboard
Copied
Thanks for the quick reply!
I tried to recreate a file with the part that is needed. The Render output file (Beauty pass, Smart Object) with the Adjustment layers above. The first six (counting upwards) are always the same and won't be renamed. Every additional layer needs to be placed on top of the existing ones. There the script would check, if there are any additiona layers and then it would copy+paste the whole adjustment layer. This would work with my knowledge. But the first six are alerady there. (like in the files 02_Default.) Default values, but with the latest layer masks. (layer masks come from the rendering, therefore need to be up2date. Older files may have incorrect masks). But the adjustments that are made with these first six adjustment layers need to be transfered onto the new file. And there the problem starts: How? Copying the values from old to new or copy the whole adjustment layers from old to new and then update the layer mask after. Bulk or batch processing sounds fun, but I guess for now it would be sufficient if there are only pairs (old and new) open in Photoshop. Therefore the user always gets to check and confirm the process before the file gets saved.
Ok ... so ...
Can you provide layered before and after PSD file examples? They don't need to be high resolution.
* Tried to create two files based on our production files, but reduced to the important part + smaller resolution.
What is the source of the new layer mask content? How does this differ from the original?
* Source is the Render output. New File has the correct Layer Mask. Old File has the correct values. At the these two things need to be merged. Correct values, with the correct layer mask inside the new file.
Do the layer names change between different files, or are they consistent?
* The default adjustment layers are consistent. There may are per-file-based layer names, but these are always on top.
Do you only have 2 images open at a time?
* Yes, seems to be the best workflow for overall control.
Are you looking for a batch solution for bulk files rather than for two open images?
* Not now, no.
Big thanks in advance!
Copy link to clipboard
Copied
You can try the following v1.0 script.
I have updated the script to v1.1... I'm happy to make adjustments based on your feedback.
The first document opened must be the original render. The second document opened must be the new render.
/*
Update Render Adjustment Layers.jsx
Stephen Marsh
v1.1 - 3rd February 2025
https://community.adobe.com/t5/photoshop-ecosystem-discussions/ps-scripting-copy-paste-layer-mask-content-from-one-to-another/td-p/15127773
Note: The original document should be the first render opened, the second should be the new render
*/
#target photoshop
if (app.documents.length == 2) {
app.activeDocument.suspendHistory("Update Render Adjustment Layers", "main()");
} else {
alert("There should only be two documents open!\rThe original document should be the first render opened, the second should be the new render.");
}
function main() {
var origDoc = app.documents[0];
var origDocName = origDoc.name;
var newDoc = app.documents[1];
var newDocName = newDoc.name;
// Set the original document as the active document
app.activeDocument = origDoc;
// Apply the mask from the new render document to the original document
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Trees_Curves"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Trees_HueSat"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bushes_Curves"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bushes_HueSat"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Street_Curves"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Street_ColFill"];
selectLayerChannel("mask");
applyImage("Street_ColFill", newDocName);
// Delete the adjustment layers from the new render document
app.activeDocument = newDoc;
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Trees_Curves"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Trees_HueSat"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bushes_Curves"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bushes_HueSat"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Street_Curves"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Street_ColFill"];
newDoc.activeLayer.remove();
// Duplicate the adjustment layers from the original document
app.activeDocument = origDoc;
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Trees_Curves"];
dupeLayer("Trees_Curves");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Trees_HueSat"];
dupeLayer("Trees_HueSat");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bushes_Curves"];
dupeLayer("Bushes_Curves");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bushes_HueSat"];
dupeLayer("Bushes_HueSat");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Street_Curves"];
dupeLayer("Street_Curves");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Street_ColFill"];
dupeLayer("Street_ColFill");
// Revert to previous state
executeAction(stringIDToTypeID("revert"), undefined, DialogModes.NO);
// Close the original doc
origDoc.close(SaveOptions.DONOTSAVECHANGES);
// Return to the new document
app.activeDocument = newDoc;
// Functions
function applyImage() {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("mask"));
reference.putName(s2t("layer"), app.activeDocument.activeLayer.name); // Source layer name
reference.putName(s2t("document"), newDocName); // Source doc name
descriptor2.putReference(s2t("to"), reference);
descriptor2.putBoolean(s2t("preserveTransparency"), true);
descriptor.putObject(s2t("with"), s2t("calculation"), descriptor2);
executeAction(s2t("applyImageEvent"), descriptor, DialogModes.NO);
}
function selectLayerChannel(chanPara) {
// "RGB" | "mask"
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("channel"), s2t("channel"), s2t(chanPara));
descriptor.putReference(s2t("null"), reference);
descriptor.putBoolean(s2t("makeVisible"), false);
executeAction(s2t("select"), descriptor, DialogModes.NO);
}
function dupeLayer(dupeLayerName) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var list = new ActionList();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
reference2.putName(s2t("document"), newDocName);
descriptor.putReference(s2t("to"), reference2);
descriptor.putString(s2t("name"), dupeLayerName);
executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
}
}
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html
Copy link to clipboard
Copied
Hi Stephen!
Thank you for that script. It worked perfectly fine! (even though, in line 9, the # comment of target photoshop didn't work on my side. I've changed it to // and thats it ... if anyone else maybe copies that code 🙂 )
For the test 'environment' everything worked out of the box. I've modified the script to our bigger files, containing many more adjustment layers. (many of them in german, thats why I've created some test layers :)) And I've commented the reverting+closing of the original document because there are some additional tasks that are worked on manually after that. 🙂 I'll paste the full script at the end. Feedback: Big thanks for that great little helper! Really wondering how anyone can wrap his head around that ActionDescriptor stuff. I really thought with using the Scripting Listener myself and watching tutorials this would make some sense soon, but nope. 🙂
One thing that would be "missing" now is the part with the custom adjustment layers. All the 26 hard coded layers are the same everytime. But everything above would be per-file-based. Would you say that can be achieved quite easily? I've once iterated through all the layers inside a layer set, but I can't find any of those test scripts. Maybe an iteration through all the layers, until the top default layer ('Dachbegrünung LUT') is found, could work? Then, copying those layers to the new file and create a Clipping mask. (thats where the problems happend too, the last time ...) ... There is no need to copy an existing mask (based on naming or something), because these are most likely changed anyway.
And a question also: The one part with the Solid Color / Color Fill. There the code is different to all the other layers. Is this something that is needed for Solid Color layers? Or is it because its the last layer in the list?
Thanks again! Really helping out!
The modified script with my changes:
/*
Update Render Adjustment Layers.jsx
Stephen Marsh
v1.1 - 3rd February 2025
https://community.adobe.com/t5/photoshop-ecosystem-discussions/ps-scripting-copy-paste-layer-mask-content-from-one-to-another/td-p/15127773
Note: The original document should be the first render opened, the second should be the new render
*/
//#target photoshop
if (app.documents.length == 2) {
app.activeDocument.suspendHistory("Update Render Adjustment Layers", "main()");
} else {
alert("There should only be two documents open!\rThe original document should be the first render opened, the second should be the new render.");
}
function main() {
var origDoc = app.documents[0];
var newDocName = origDoc.name;
var newDoc = app.documents[1];
var newDocName = newDoc.name;
// Set the original document as the active document
app.activeDocument = origDoc;
// Apply the mask from the new render document to the original document
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Kurven"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Farbton Sättigung uniform"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Farbton/Sättigung"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese Kurven"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese Farbton/Sättigung"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume Kurve"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume Farbton/Sättigung"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecke Kurve"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecke_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecken Farbton/Sättigung"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche Kurve"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche Farbton Sättigung"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Stauden Kurven"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Stauden_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Ranken Kurve"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Ranken_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Boardstein Kurven"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Strassen Kurven"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Color Fill Strasse"];
selectLayerChannel("mask");
applyImage("Color Fill Strasse", newDocName);
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Untersicht Kurve"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Dachbegrünung Kurven"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Dachbegrünung LUT"];
selectLayerChannel("mask");
applyImage();
// Delete the adjustment layers from the new render document
app.activeDocument = newDoc;
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Rasen Kurven"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Rasen Farbton Sättigung uniform"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Rasen Farbton/Sättigung"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Rasen_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Wiese Kurven"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Wiese_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Wiese Farbton/Sättigung"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bäume Kurve"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bäume_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bäume Farbton/Sättigung"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Hecke Kurve"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Hecke_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Hecken Farbton/Sättigung"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Büsche Kurve"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Büsche Farbton Sättigung"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Büsche_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Stauden Kurven"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Stauden_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Ranken Kurve"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Ranken_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Boardstein Kurven"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Strassen Kurven"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Color Fill Strasse"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Untersicht Kurve"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Dachbegrünung Kurven"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Dachbegrünung LUT"];
newDoc.activeLayer.remove();
// Duplicate the adjustment layers from the original document
app.activeDocument = origDoc;
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Kurven"];
dupeLayer("Rasen Kurven");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Farbton Sättigung uniform"];
dupeLayer("Rasen Farbton Sättigung uniform");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Farbton/Sättigung"];
dupeLayer("Rasen Farbton/Sättigung");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen_LUT"];
dupeLayer("Rasen_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese Kurven"];
dupeLayer("Wiese Kurven");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese_LUT"];
dupeLayer("Wiese_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese Farbton/Sättigung"];
dupeLayer("Wiese Farbton/Sättigung");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume Kurve"];
dupeLayer("Bäume Kurve");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume_LUT"];
dupeLayer("Bäume_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume Farbton/Sättigung"];
dupeLayer("Bäume Farbton/Sättigung");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecke Kurve"];
dupeLayer("Hecke Kurve");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecke_LUT"];
dupeLayer("Hecke_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecken Farbton/Sättigung"];
dupeLayer("Hecken Farbton/Sättigung");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche Kurve"];
dupeLayer("Büsche Kurve");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche Farbton Sättigung"];
dupeLayer("Büsche Farbton Sättigung");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche_LUT"];
dupeLayer("Büsche_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Stauden Kurven"];
dupeLayer("Stauden Kurven");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Stauden_LUT"];
dupeLayer("Stauden_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Ranken Kurve"];
dupeLayer("Ranken Kurve");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Ranken_LUT"];
dupeLayer("Ranken_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Boardstein Kurven"];
dupeLayer("Boardstein Kurven");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Strassen Kurven"];
dupeLayer("Strassen Kurven");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Color Fill Strasse"];
dupeLayer("Color Fill Strasse");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Untersicht Kurve"];
dupeLayer("Untersicht Kurve");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Dachbegrünung Kurven"];
dupeLayer("Dachbegrünung Kurven");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Dachbegrünung LUT"];
dupeLayer("Dachbegrünung LUT");
// Revert to previous state ... would be nice, but takes too much time with our .psb files (~ 5 seconds)
//executeAction(stringIDToTypeID("revert"), undefined, DialogModes.NO);
// Close the original doc ... not needed (for now), additional tasks follow
//origDoc.close(SaveOptions.DONOTSAVECHANGES);
// Return to the new document
app.activeDocument = newDoc;
// Functions
function applyImage() {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("mask"));
reference.putName(s2t("layer"), app.activeDocument.activeLayer.name); // Source layer name
reference.putName(s2t("document"), newDocName); // Source doc name
descriptor2.putReference(s2t("to"), reference);
descriptor2.putBoolean(s2t("preserveTransparency"), true);
descriptor.putObject(s2t("with"), s2t("calculation"), descriptor2);
executeAction(s2t("applyImageEvent"), descriptor, DialogModes.NO);
}
function selectLayerChannel(chanPara) {
// "RGB" | "mask"
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("channel"), s2t("channel"), s2t(chanPara));
descriptor.putReference(s2t("null"), reference);
descriptor.putBoolean(s2t("makeVisible"), false);
executeAction(s2t("select"), descriptor, DialogModes.NO);
}
function dupeLayer(dupeLayerName) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var list = new ActionList();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
reference2.putName(s2t("document"), newDocName);
descriptor.putReference(s2t("to"), reference2);
descriptor.putString(s2t("name"), dupeLayerName);
executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
}
}
Copy link to clipboard
Copied
And a question also: The one part with the Solid Color / Color Fill. There the code is different to all the other layers. Is this something that is needed for Solid Color layers? Or is it because its the last layer in the list?
By @David3065392143nx
I think that was a sloppy edit. :]
I originally was passing parameters to the applyImage function, however, I don't think that they are needed for the solid fill layer and you can try changing from:
applyImage("Street_ColFill", newDocName);
To:
applyImage();
If I remember correctly, when I was testing the solid fill layer did need the mask channel explicitly selected, it didn't matter for the other layers but I put the function call in there anyway for consistency. I believe that it could be removed from all of the layers except the solid fill.
selectLayerChannel("mask");
Copy link to clipboard
Copied
Hi Stephen!
Feedback: Big thanks for that great little helper! Really wondering how anyone can wrap his head around that ActionDescriptor stuff. I really thought with using the Scripting Listener myself and watching tutorials this would make some sense soon, but nope. 🙂
By @David3065392143nx
I only play and hack at Action Manager code. I don't understand it, I just work with it.
Yes, I do use the Scripting Listener plugin to get the raw code. I sometimes have a very basic understanding of editing the captured code, but can't write it from scratch. I can sometimes remove redundant code. I can manually wrap it in a function block and put in variables for use as parameters in a function call. I generally use the "Clean SL" script to beautify or simplify the code, except for when it breaks things (generally a rare occurrence).
Copy link to clipboard
Copied
And I've commented the reverting+closing of the original document because there are some additional tasks that are worked on manually after that.
By @David3065392143nx
The revert was redundant, I first had that there before adding the close without saving.
In case it wasn't obvious, I was destructively changing the original document as a shortcut. Specifically, I was using Apply Image to transfer the mask from the new render document to the original document.
I didn't want the altered file left as it was, which is why I reverted and then decided to close without saving it.
Copy link to clipboard
Copied
One thing that would be "missing" now is the part with the custom adjustment layers. All the 26 hard coded layers are the same everytime. But everything above would be per-file-based. Would you say that can be achieved quite easily? I've once iterated through all the layers inside a layer set, but I can't find any of those test scripts. Maybe an iteration through all the layers, until the top default layer ('Dachbegrünung LUT') is found, could work?
By @David3065392143nx
Yes, for the three "linear" blocks of repeated code, I avoided a for loop inside the layer group:
// Apply the mask from the new render document to the original document
// Delete the adjustment layers from the new render document
// Duplicate the adjustment layers from the original document
It was quick and dirty, repetitive and boring for 6, I didn't know that you actually had 26 to handle!
To loop over the 6 specific named layers, one solution could be to only list the 6 layers once in an array variable:
// Apply the mask from the new render document to the original document
var layers = ["Trees_Curves", "Trees_HueSat", "Bushes_Curves", "Bushes_HueSat", "Street_Curves", "Street_ColFill"];
for (var i = 0; i < layers.length; i++) {
origDoc.activeLayer = origDoc.layerSets["Render"].layers[layers[i]];
selectLayerChannel("mask");
applyImage(newDoc.name);
}
// Delete adjustment layers from the new document
app.activeDocument = newDoc;
for (var j = 0; j < layers.length; j++) {
newDoc.activeLayer = newDoc.layerSets["Render"].layers[layers[j]];
newDoc.activeLayer.remove();
}
// Duplicate adjustment layers from the original document
app.activeDocument = origDoc;
for (var k = 0; k < layers.length; k++) {
origDoc.activeLayer = origDoc.layerSets["Render"].layers[layers[k]];
dupeLayer(layers[k], newDoc.name);
}
Yes, as you say, you could probably do better by looping over the contents of the "Render" group/set and then stop when you hit a layer with a specific name. Depending on the order of the layers and the position of the specific layer, you may need to either loop forwards or backwards. Perhaps easier said than done!
Copy link to clipboard
Copied
Thanks again!
The looping through the layers won't be needed for now I guess. The lines are there now and I can edit them freely. 🙂 Still working on the duplicating of the custom layers, but I'll get there.
I've already modified the code to help me with another layer set, where I only need to adjust the opacity level of each layer. This works fine inside your script with the variables for each document and with the addressing of each layer. (Will attach the code, again 🙂 ) Also a big thank you for the suggestion of the SL Cleaner! Really great tool that may help understanding that stuff a little bit better. :)))
Only one thing that is bugging me right now: With your functions, would it be possible, to copy the content of a layer mask (this time only the content), to the newDoc? The first part of the three parts does this, somehow. Copyign the mask from the new to the original ones. But I don't get the code. 😄 Because I only need the mask and can't use the procedure that already exists ... it is the Render layer set. Sometimes this layer set / group also has a mask applied. There I can't simply copy the mask and then overwrite everything. I guess I can check with the script, if the layer set has a mask and then create a new mask in the newDoc, but how would I transfer only that mask from A to B? If you could enlighten me in that part I will be forever grateful. <3The script may be even finished then and it will make a lot of updating existing files easier than ever.
Copy link to clipboard
Copied
/*
Update Render Adjustment Layers.jsx
Stephen Marsh
v1.1 - 3rd February 2025
https://community.adobe.com/t5/photoshop-ecosystem-discussions/ps-scripting-copy-paste-layer-mask-content-from-one-to-another/td-p/15127773
Note: The original document should be the first render opened, the second should be the new render
*/
//#target photoshop
if (app.documents.length == 2) {
app.activeDocument.suspendHistory("Update Render Adjustment Layers", "main()");
} else {
alert("There should only be two documents open!\rThe original document should be the first render opened, the second should be the new render.");
}
function main() {
var origDoc = app.documents[0];
var newDocName = origDoc.name;
var newDoc = app.documents[1];
var newDocName = newDoc.name;
// Set the original document as the active document
app.activeDocument = origDoc;
// Apply the mask from the new render document to the original document
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Kurven"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Farbton Sättigung uniform"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Farbton/Sättigung"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese Kurven"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese Farbton/Sättigung"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume Kurve"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume Farbton/Sättigung"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecke Kurve"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecke_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecken Farbton/Sättigung"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche Kurve"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche Farbton Sättigung"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Stauden Kurven"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Stauden_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Ranken Kurve"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Ranken_LUT"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Boardstein Kurven"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Strassen Kurven"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Color Fill Strasse"];
selectLayerChannel("mask");
applyImage("Color Fill Strasse", newDocName);
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Untersicht Kurve"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Dachbegrünung Kurven"];
selectLayerChannel("mask");
applyImage();
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Dachbegrünung LUT"];
selectLayerChannel("mask");
applyImage();
// Delete the adjustment layers from the new render document
app.activeDocument = newDoc;
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Rasen Kurven"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Rasen Farbton Sättigung uniform"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Rasen Farbton/Sättigung"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Rasen_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Wiese Kurven"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Wiese_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Wiese Farbton/Sättigung"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bäume Kurve"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bäume_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Bäume Farbton/Sättigung"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Hecke Kurve"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Hecke_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Hecken Farbton/Sättigung"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Büsche Kurve"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Büsche Farbton Sättigung"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Büsche_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Stauden Kurven"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Stauden_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Ranken Kurve"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Ranken_LUT"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Boardstein Kurven"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Strassen Kurven"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Color Fill Strasse"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Untersicht Kurve"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Dachbegrünung Kurven"];
newDoc.activeLayer.remove();
newDoc.activeLayer = newDoc.layerSets["Render"].layers["Dachbegrünung LUT"];
newDoc.activeLayer.remove();
// Duplicate the adjustment layers from the original document
app.activeDocument = origDoc;
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Kurven"];
dupeLayer("Rasen Kurven");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Farbton Sättigung uniform"];
dupeLayer("Rasen Farbton Sättigung uniform");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen Farbton/Sättigung"];
dupeLayer("Rasen Farbton/Sättigung");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Rasen_LUT"];
dupeLayer("Rasen_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese Kurven"];
dupeLayer("Wiese Kurven");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese_LUT"];
dupeLayer("Wiese_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Wiese Farbton/Sättigung"];
dupeLayer("Wiese Farbton/Sättigung");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume Kurve"];
dupeLayer("Bäume Kurve");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume_LUT"];
dupeLayer("Bäume_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Bäume Farbton/Sättigung"];
dupeLayer("Bäume Farbton/Sättigung");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecke Kurve"];
dupeLayer("Hecke Kurve");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecke_LUT"];
dupeLayer("Hecke_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Hecken Farbton/Sättigung"];
dupeLayer("Hecken Farbton/Sättigung");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche Kurve"];
dupeLayer("Büsche Kurve");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche Farbton Sättigung"];
dupeLayer("Büsche Farbton Sättigung");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Büsche_LUT"];
dupeLayer("Büsche_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Stauden Kurven"];
dupeLayer("Stauden Kurven");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Stauden_LUT"];
dupeLayer("Stauden_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Ranken Kurve"];
dupeLayer("Ranken Kurve");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Ranken_LUT"];
dupeLayer("Ranken_LUT");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Boardstein Kurven"];
dupeLayer("Boardstein Kurven");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Strassen Kurven"];
dupeLayer("Strassen Kurven");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Color Fill Strasse"];
dupeLayer("Color Fill Strasse");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Untersicht Kurve"];
dupeLayer("Untersicht Kurve");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Dachbegrünung Kurven"];
dupeLayer("Dachbegrünung Kurven");
origDoc.activeLayer = origDoc.layerSets["Render"].layers["Dachbegrünung LUT"];
dupeLayer("Dachbegrünung LUT");
// Sync Opacity / Visibility of pre-defined layers
app.activeDocument = newDoc;
newDoc.layerSets["Adjustments"].layers["Reflect copy"].opacity = origDoc.layerSets["Adjustments"].layers["Reflect copy"].opacity;
newDoc.layerSets["Adjustments"].layers["Z_Buffer"].opacity = origDoc.layerSets["Adjustments"].layers["Z_Buffer"].opacity;
newDoc.layerSets["Adjustments"].layers["Glas"].visible = origDoc.layerSets["Adjustments"].layers["Glas"].visible;
// Revert to previous state ... would be nice, but takes too much time with our .psb files (~ 5 seconds)
//executeAction(stringIDToTypeID("revert"), undefined, DialogModes.NO);
// Close the original doc ... not needed (for now), additional tasks follow
//origDoc.close(SaveOptions.DONOTSAVECHANGES);
// Functions
function applyImage() {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("mask"));
reference.putName(s2t("layer"), app.activeDocument.activeLayer.name); // Source layer name
reference.putName(s2t("document"), newDocName); // Source doc name
descriptor2.putReference(s2t("to"), reference);
descriptor2.putBoolean(s2t("preserveTransparency"), true);
descriptor.putObject(s2t("with"), s2t("calculation"), descriptor2);
executeAction(s2t("applyImageEvent"), descriptor, DialogModes.NO);
}
function selectLayerChannel(chanPara) {
// "RGB" | "mask"
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("channel"), s2t("channel"), s2t(chanPara));
descriptor.putReference(s2t("null"), reference);
descriptor.putBoolean(s2t("makeVisible"), false);
executeAction(s2t("select"), descriptor, DialogModes.NO);
}
function dupeLayer(dupeLayerName) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var list = new ActionList();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
reference2.putName(s2t("document"), newDocName);
descriptor.putReference(s2t("to"), reference2);
descriptor.putString(s2t("name"), dupeLayerName);
executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
}
}
Copy link to clipboard
Copied
Just to be clear, because that sounded a little bit off: I'm grateful anyway 🙂
Copy link to clipboard
Copied
Just to be clear, because that sounded a little bit off: I'm grateful anyway 🙂
By @David3065392143nx
I understood, it's all good! :]
Copy link to clipboard
Copied
Only one thing that is bugging me right now: With your functions, would it be possible, to copy the content of a layer mask (this time only the content), to the newDoc? The first part of the three parts does this, somehow. Copyign the mask from the new to the original ones. But I don't get the code.
By @David3065392143nx
See if the following image helps, I prefer using Apply Image as it doesn't have the overhead of clipboard based workflows.
From within the target/destination document, set the required layer and channel, then use Apply Image to specify the data source.
The ScriptingListener will capture the absolute "string" name of the source layer and source document. These can be swapped out for variables that bring in the "string" name of the current layer and document.
Hope this helps.
Copy link to clipboard
Copied
Hi! These screenshots really helped and I've never used Apply Image before. 🙂 But it really looks straight forward. I also tried to get the stuff done with the help of the Script Listener and the Cleaner Script. And for most parts I've got it running. But it seems the next, and probably final problem: I need to copy the layer mask content from a Layer Group called 'Render'. But inside that Layer Group exists another layer (Smart Object) called 'Render'. And if both keep their name, it always copies the mask from the Layer / Smart Object. If I rename that one, it copies the correct mask. I tried to edit the code to search for Layer Groups / Layer Sets / Layer Sections, even with Chat GPT, but that didn't work out. The check for an existing layer mask, the creating of a layer mask if there is none works for now. Only thing missing would be the copy process. Do you have an idea what could help? Renaming one of the two folders would be the best case, ofc. Naming both the same is bad in the first place. But I'm afraid there are many open projects that would require re-naming that it would be nice to have that covered code-wise. 😄
Thanks! ❤️
Copy link to clipboard
Copied
Whether it's actions or scripting or even manually using the GUI, having unique layer and group names is a good practice.
In DOM code, app.activeDocument.layers is generic for the entire layers collection. You can be more specific by targeting layerSets or artLayers, or both in a parent/child group structure:
// A top-level layer set
app.activeDocument.activeLayer = app.activeDocument.layerSets["Render"];
// or a layer set inside a layer set, one level deep:
app.activeDocument.activeLayer = app.activeDocument.layerSets["Render"].layerSets["Render"];
// or, if the artLayer isn’t inside a layerSet:
app.activeDocument.activeLayer = app.activeDocument.artLayers["Render"];
// or if the artLayer is inside a layerSet:
app.activeDocument.activeLayer = app.activeDocument.layerSets["Render"].artLayers["Render"];
Action Manager code works differently, you can directly select a layer (not a group), even if it's inside a group (presuming that there is only one artLayer with the same name:
selectLayerName("Render”);
function selectLayerName(lyrName) {
var idselect = stringIDToTypeID("select");
var desc266 = new ActionDescriptor();
var idnull = stringIDToTypeID("null");
var ref59 = new ActionReference();
var idlayer = stringIDToTypeID("layer");
ref59.putName(idlayer, lyrName);
desc266.putReference(idnull, ref59);
var idmakeVisible = stringIDToTypeID("makeVisible");
desc266.putBoolean(idmakeVisible, false);
executeAction(idselect, desc266, DialogModes.NO);
}
Once you have the layer selected, you can use my previous function to select the mask channel. Hope this helps!
Copy link to clipboard
Copied
But this will select the artLayer, right? What needs to be changed to not select the artLayer, it should select the Group instead. (yes, both Render layers have an layer mask ... the artLayer (the Smart Object) has one per default. That is ok. But the Layer Group sometimes has a layer mask and that mask needs to be duplicated / Image Applied from Old to New. But I guess your script aims for the non-group 'Render' layer, right?
And yeah, I probably should introduce the unique name policy for the future 😄
Copy link to clipboard
Copied
I invite you to try each of the snippets with appropriate layer content for testing. :]
Copy link to clipboard
Copied
I'm afraid that I'm not that far with understanding that stuff?
var origDoc = app.documents[0];
var origDocName = origDoc.name;
var newDoc = app.documents[1];
var newDocName = newDoc.name;
app.activeDocument = origDoc;
app.activeDocument.activeLayer = app.activeDocument.layerSets["Render"];
selectLayerChannel("mask");
app.activeDocument = newDoc;
app.activeDocument.activeLayer = app.activeDocument.layerSets["Render"];
selectLayerChannel("mask");
alert (origDoc.activeLayer.name)
// Trying to target the origDoc Render LayerSet Mask; to apply the mask image to the currently + correctly selected Render
// =======================================================
var idAppI = charIDToTypeID( "AppI" );
var desc531 = new ActionDescriptor();
var idWith = charIDToTypeID( "With" );
var desc532 = new ActionDescriptor();
var idT = charIDToTypeID( "T " );
var ref51 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref51.putEnumerated( idChnl, idOrdn, idTrgt );
var idLyr = charIDToTypeID( "Lyr " );
ref51.putName( idLyr, origDoc.activeLayer.name );
var idDcmn = charIDToTypeID( "Dcmn" );
ref51.putName( idDcmn, origDoc.name );
desc532.putReference( idT, ref51 );
var idPrsT = charIDToTypeID( "PrsT" );
desc532.putBoolean( idPrsT, true );
var idClcl = charIDToTypeID( "Clcl" );
desc531.putObject( idWith, idClcl, desc532 );
executeAction( idAppI, desc531, DialogModes.NO );
function selectLayerChannel(chanPara) {
// "RGB" | "mask"
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("channel"), s2t("channel"), s2t(chanPara));
descriptor.putReference(s2t("null"), reference);
descriptor.putBoolean(s2t("makeVisible"), false);
executeAction(s2t("select"), descriptor, DialogModes.NO);
}
I've created a new script that only tries to get the Original Render (Layer Group) Layer Mask Image to the New Render (Layer Group) Layer mask. While selecting both masks in both documents works fine with your scripts, I can't get the Apply Image method working - at least not, that it selects the Layer Group Render. If there is another layer inside that is called Render, it always copies the wrong one. Even when I try to address the layer via activeLayer. (ofc, the name is Render too .. so that won't help)
ref51.putName( idLyr, origDoc.layerSets["Render"] );
Also changing the ref to the target layer gives me no working code. (Seems like that doesn't work?) I assume it could be connected to the part where idLyr is defined? (var idLyr = charIDToTypeID( "Lyr " );) ...
Also tried to call the Apply Image function twice to see, if the second time it gets the next Render, but nope. I know learning works best with finding the solution on my own, but I guess I'm stuck again. Sorry 😄
Copy link to clipboard
Copied
From my tests, I believe that this is a bug/limitation of AM code and/or SL when there are both one or more layer groups and layers with the same name. It appears that the code applies the layer rather than the mask. This doesn't happen when using the interface to perform the task manually. So another good reason to use unique names!
I didn't know that you would apply the mask from one group to another.
So, there are two ways around this that I can see:
1) The script can rename the Render layer group or all groups so that they are unique and don't clash with the layers ("Render Group" or "Render 1" etc) and then the apply image code will work as expected.
2) Script the copy and paste of the group mask from one doc to the other.
P.S. I have corrected the original code as there was a minor error in the global variables for the docs/names:
var origDoc = app.documents[0];
var origDocName = origDoc.name;
var newDoc = app.documents[1];
var newDocName = newDoc.name;
Copy link to clipboard
Copied
Ah, I see! Yes, then the Option #1 would be the easy one. For now I'll check if the Render ArtLayer, not the group is still called Render, and if yes, it will be renamed to Render32. (and for future setups this will be included in the process). For now I've created a 4-step workflow with 4 buttons that execute specific scripts to get insights, where stuff could (and probably will) break during the beta testing phase. 🙂
That wouldn't be possible without your help. A big big big thank you! 🙂 Helping in creating the script and also helping in understanding that whole SL / AM stuff a little bit better. Can't say its much, but SL code now is not only complete green matrix spaghetti code for me 🙂 WIll try to combine everything into one optimized script (without 26 hardcoded layer names :P), but that will happen in the future.
Thanks and have a nice day!
Copy link to clipboard
Copied