Skip to main content
Participating Frequently
February 2, 2025
Answered

PS Scripting: Copy + Paste Layer Mask Content from one to another?

  • February 2, 2025
  • 3 replies
  • 2327 views

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!

Correct answer Stephen Marsh

@David3065392143nx 

 

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);
    }
}

 

  1. Copy the code text to the clipboard
  2. Open a new blank file in a plain-text editor (not in a word processor)
  3. Paste the code in
  4. Save as a plain text format file – .txt
  5. Rename the saved file extension from .txt to .jsx
  6. Install or browse to the .jsx file to run (see below)

 

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

 

3 replies

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
February 3, 2025

@David3065392143nx 

 

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);
    }
}

 

  1. Copy the code text to the clipboard
  2. Open a new blank file in a plain-text editor (not in a word processor)
  3. Paste the code in
  4. Save as a plain text format file – .txt
  5. Rename the saved file extension from .txt to .jsx
  6. Install or browse to the .jsx file to run (see below)

 

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

 

Participating Frequently
February 3, 2025

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);
    }
}

 

 

 

Stephen Marsh
Community Expert
Community Expert
February 4, 2025

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! ❤️


@David3065392143nx 

 

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!

Participating Frequently
February 2, 2025

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!

 

Stephen Marsh
Community Expert
Community Expert
February 2, 2025

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?