Skip to main content
Known Participant
August 20, 2024
Answered

"Expand" and "Content Aware Fill" functions are not working via JavaScript

  • August 20, 2024
  • 9 replies
  • 16753 views

I am running the Creative Cloud. Photoshop is 25.11.

I need a JavaScript based routine that can process images automatically. It should "Expand" a mask and fill it using "Content Aware Fill", but JavaScript cannot do it. Previous Photoshop versions apparently offered JavaScript this functionality.

Am I understand it wrongly?

Thank you!

This topic has been closed for replies.
Correct answer Stephen Marsh

@crehage2 

 

Try this batch script. I would advise you to have a small number of files in the source folder as this may take a while to run, particularly if the source files are high-resolution, 16-BPC docs. You should also keep drive space in mind as you process the files. Output files will overwrite any existing files without warning.

 

/*
All Top-Level Layers With Content Aware Fill to TIFF.jsx
v1.0 - 22nd August 2024, Stephen Marsh
v1.1 - 23rd August 2024, Added a conditional check to only process smart object layers
https://community.adobe.com/t5/photoshop-ecosystem-discussions/quot-expand-quot-and-quot-content-aware-fill-quot-functions-are-not-working-via-javascript/td-p/14810803
*/

#target photoshop

    (function () {

        // Ensure that no docs are open
        if (app.documents.length == 0) {

            try {

                // Set the input folder
                var inputFolder = Folder.selectDialog("Please select the folder to process...");
                if (inputFolder === null) {
                    //alert('Script cancelled!');
                    return;
                }

                // Limit the file input to psd/psb
                var inputFolderList = inputFolder.getFiles(/\.(psd|psb)$/i);

                // Validate that input folder contains psd/psb files 
                var validateEmptyList = (inputFolderList.length > 0);
                if (validateEmptyList === false) {
                    alert("Script cancelled as the input folder is empty!");
                    return;
                }

                // Alpha-numeric sort
                inputFolderList.sort();

                // Set the output folder
                var outputFolder = Folder.selectDialog("Please select the folder to save to...");
                if (outputFolder === null) {
                    //alert('Script cancelled!');
                    return;
                }

                // TIFF save options
                var tiffSaveOptions = new TiffSaveOptions();
                tiffSaveOptions.imageCompression = TIFFEncoding.NONE;
                tiffSaveOptions.embedColorProfile = true;
                tiffSaveOptions.byteOrder = ByteOrder.IBM;
                tiffSaveOptions.transparency = true;
                tiffSaveOptions.layers = false;
                tiffSaveOptions.layerCompression = LayerCompression.ZIP;
                tiffSaveOptions.interleaveChannels = true;
                tiffSaveOptions.alphaChannels = true;
                tiffSaveOptions.annotations = true;
                tiffSaveOptions.spotColors = true;
                tiffSaveOptions.saveImagePyramid = false;

                // Set the file processing counter
                var outputCounter = 0;

                // Hide the Photoshop panels
                app.togglePalettes();

                // Script running notification window - courtesy of William Campbell
                /* https://www.marspremedia.com/download?asset=adobe-script-tutorial-11.zip
                https://youtu.be/JXPeLi6uPv4?si=Qx0OVNLAOzDrYPB4 */
                var working;
                working = new Window("palette");
                working.preferredSize = [300, 80];
                working.add("statictext");
                working.t = working.add("statictext");
                working.add("statictext");
                working.display = function (message) {
                    this.t.text = message || "Script running, please wait...";
                    this.show();
                    app.refresh();
                };
                working.display();

                // Start Timer
                var timeDiff = {
                    setStartTime: function () {
                        d = new Date();
                        time = d.getTime();
                    },
                    getDiff: function () {
                        d = new Date();
                        t = d.getTime() - time;
                        time = d.getTime();
                        return t;
                    }
                };
                timeDiff.setStartTime();

                // Loop over the psd/psb files
                for (var i = 0; i < inputFolderList.length; i++) {

                    open(inputFolderList[i]);
                    var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                    var layerName = app.activeDocument.activeLayer.name;
                    // Set the zero padding and layer processing counter
                    var zeroPadLength = 3;
                    var layerCounter = 1;

                    // Loop over the top-level layers
                    for (var j = 0; j < app.activeDocument.layers.length; j++) {

                        app.activeDocument.activeLayer = app.activeDocument.layers[j];
                        // Only process smart object layers
                        if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
                            // Active layer processing
                            dupeLayerToDoc(layerName, layerName);
                            rasterizeLayer();
                            layerTransparencyToSelection();
                            executeAction(stringIDToTypeID("inverse"), undefined, DialogModes.NO);
                            app.activeDocument.selection.expand(UnitValue(1, 'px'));
                            contentAwareFill(false, false, false);
                            app.activeDocument.selection.deselect();
                            app.activeDocument.flatten();
                            // Save as TIFF
                            app.activeDocument.saveAs(new File(outputFolder + '/' + docName + ' ' + zeroPad(layerCounter, zeroPadLength) + '.tif'), tiffSaveOptions);
                            // Close the TIFF doc
                            app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                            // Increment the layer processing counter
                            layerCounter++
                            // Increment the file processing counter
                            outputCounter++
                        }
                    }

                    // Close the PSD/PSB doc
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

                }

                // Ensure Photoshop has focus before closing the running script notification window
                app.bringToFront();
                working.close();
                
                // End of script notification
                app.beep();
                alert('Script completed!' + '\r' + inputFolderList.length + ' source PSD/PSB files processed & ' + '\r' + outputCounter + ' TIFF files created.' + "\r" + "Run Time: " + timeDiff.getDiff() / 1000 + " seconds.");

                // Restore the Photoshop panels
                app.togglePalettes();

                // Open the output folder in Windows Explorer or the Mac Finder
                //outputFolder.execute();
                

                ///// Functions /////

                function dupeLayerToDoc(theNewDocName, theLayerName) {
                    var s2t = function (s) {
                        return app.stringIDToTypeID(s);
                    };
                    var descriptor = new ActionDescriptor();
                    var reference = new ActionReference();
                    var reference2 = new ActionReference();
                    reference2.putClass(s2t("document"));
                    descriptor.putReference(s2t("null"), reference2);
                    descriptor.putString(s2t("name"), theNewDocName);
                    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
                    descriptor.putReference(s2t("using"), reference);
                    descriptor.putString(s2t("layerName"), theLayerName);
                    executeAction(s2t("make"), descriptor, DialogModes.NO);
                }

                function rasterizeLayer() {
                    var s2t = function (s) {
                        return app.stringIDToTypeID(s);
                    };
                    var descriptor = new ActionDescriptor();
                    var reference = new ActionReference();
                    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
                    descriptor.putReference(s2t("null"), reference);
                    executeAction(s2t("rasterizeLayer"), descriptor, DialogModes.NO);
                }

                function layerTransparencyToSelection() {
                    var s2t = function (s) {
                        return app.stringIDToTypeID(s);
                    };
                    var descriptor = new ActionDescriptor();
                    var reference = new ActionReference();
                    var reference2 = new ActionReference();
                    reference.putProperty(s2t("channel"), s2t("selection"));
                    descriptor.putReference(s2t("null"), reference);
                    reference2.putEnumerated(s2t("channel"), s2t("channel"), s2t("transparencyEnum"));
                    descriptor.putReference(s2t("to"), reference2);
                    executeAction(s2t("set"), descriptor, DialogModes.NO);
                }

                function contentAwareFill(cafSampleAllLayers, cafScale, cafMirror) {
                    var s2t = function (s) {
                        return app.stringIDToTypeID(s);
                    };
                    var descriptor = new ActionDescriptor();
                    descriptor.putEnumerated(s2t("cafSamplingRegion"), s2t("cafSamplingRegion"), s2t("cafSamplingRegionRectangular"));
                    descriptor.putBoolean(s2t("cafSampleAllLayers"), cafSampleAllLayers);
                    descriptor.putEnumerated(s2t("cafColorAdaptationLevel"), s2t("cafColorAdaptationLevel"), s2t("cafColorAdaptationDefault"));
                    descriptor.putEnumerated(s2t("cafRotationAmount"), s2t("cafRotationAmount"), s2t("cafRotationAmountNone"));
                    descriptor.putBoolean(s2t("cafScale"), cafScale);
                    descriptor.putBoolean(s2t("cafMirror"), cafMirror);
                    descriptor.putEnumerated(s2t("cafOutput"), s2t("cafOutput"), s2t("cafOutputToCurrentLayer"));
                    executeAction(s2t("cafWorkspace"), descriptor, DialogModes.NO);
                }

                function zeroPad(num, digit) {
                    var tmp = num.toString();
                    while (tmp.length < digit) {
                        tmp = "0" + tmp;
                    }
                    return tmp;
                }

            } catch (err) {
                while (app.documents.length > 0) {
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                }
                alert("Error!" + "\r" + err + "\r" +'Line: ' + err.line);
            }

        } else {
            alert('Please close all open documents before running this script!');
        }

    }());

 

9 replies

Stephen Marsh
Community Expert
Community Expert
August 27, 2024

As an alternative, you may wish to try batch-exporting each layer to a separate file. Then run a simple batch action to create the content aware fill.

 

crehage2Author
Known Participant
August 27, 2024

Stephen! I finally understood the problem! Many of my PSD or PSB files have all layers selected when you open them. Is this something that the script could work around by saying something like "deselect all layers" at the beginning?

Stephen Marsh
Community Expert
Community Expert
August 28, 2024
quote

Stephen! I finally understood the problem! Many of my PSD or PSB files have all layers selected when you open them. Is this something that the script could work around by saying something like "deselect all layers" at the beginning?


By @crehage2

 

Yes, either deselecting all layers, or selecting a single layer should be workable.

Stephen Marsh
Community Expert
Community Expert
August 23, 2024

@crehage2 

 

I have no idea what is going on when you swap out the function call for an action!

 

Back in the original script, replace the function call again with this new one:

 

contentAwareFill(false, false, false, false, 100);

 

Then find the function and replace it with this new code:

 

function contentAwareFill(contentAwareColorAdaptationFill, contentAwareRotateFill, contentAwareScaleFill, contentAwareMirrorFill, opacity) {
	var s2t = function (s) {
		return app.stringIDToTypeID(s);
	};
	var descriptor = new ActionDescriptor();
	descriptor.putEnumerated( s2t( "using" ), s2t( "fillContents" ), s2t( "contentAware" ));
	descriptor.putBoolean( s2t( "contentAwareColorAdaptationFill" ), contentAwareColorAdaptationFill );
	descriptor.putBoolean( s2t( "contentAwareRotateFill" ), contentAwareRotateFill );
	descriptor.putBoolean( s2t( "contentAwareScaleFill" ), contentAwareScaleFill );
	descriptor.putBoolean( s2t( "contentAwareMirrorFill" ), contentAwareMirrorFill );
	descriptor.putUnitDouble( s2t( "opacity" ), s2t( "percentUnit" ), opacity );
	descriptor.putEnumerated( s2t( "mode" ), s2t( "blendMode" ), s2t( "normal" ));
	executeAction( s2t( "fill" ), descriptor, DialogModes.NO );
}

 

This code uses the simpler Edit > Fill: Content Aware rather than the full CAF command. Perhaps this will work (it doesn't offer a 'rectangular' option though).

 

crehage2Author
Known Participant
August 23, 2024

Thank you, Stephen! I will try to do this. One thing I am wondering is: don't you think maybe something went wrong at an earlier stage, so sometimes not just one layer but multiple layers end up in the same document that is being treated with our routine?

crehage2Author
Known Participant
August 23, 2024

I am currently running the script with the action as before on a large number of layers in multiple PSD files. Every time the script accesses a new PSD, the first layer causes the error message. And every time that happens, the layer is visibly stacked on top of a bunch of other layers. That's why I am confused.

Stephen Marsh
Community Expert
Community Expert
August 23, 2024

To call an action, change this line:

 

contentAwareFill(false, false, false);

 

To the following, changing the action set folder and action set name to your particular case-sensitive spelling of the action set and action in your action panel that was recorded with the content aware fill:

 

app.doAction("My Action Name", "My Action Set Folder");

 

 

crehage2Author
Known Participant
August 23, 2024

Hello Stephen,

 

I managed to record the action and apply it as you said, thank you!

Now a strange thing has happened. So the script gave an error on the first layer of the batch, saying the action that I specified was not available. It worked fine on all subsequent layers, though. When I checked the Tiffs that it created, it seems as though the first one (the problematic one) does not in fact just show one layer, but multiple layers (as you can see in the top right corner where they overlap). I wonder what happened here. I am attaching screenshots. Thank you, and best wishes from Austria,

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
August 22, 2024

@crehage2 

 

Try this batch script. I would advise you to have a small number of files in the source folder as this may take a while to run, particularly if the source files are high-resolution, 16-BPC docs. You should also keep drive space in mind as you process the files. Output files will overwrite any existing files without warning.

 

/*
All Top-Level Layers With Content Aware Fill to TIFF.jsx
v1.0 - 22nd August 2024, Stephen Marsh
v1.1 - 23rd August 2024, Added a conditional check to only process smart object layers
https://community.adobe.com/t5/photoshop-ecosystem-discussions/quot-expand-quot-and-quot-content-aware-fill-quot-functions-are-not-working-via-javascript/td-p/14810803
*/

#target photoshop

    (function () {

        // Ensure that no docs are open
        if (app.documents.length == 0) {

            try {

                // Set the input folder
                var inputFolder = Folder.selectDialog("Please select the folder to process...");
                if (inputFolder === null) {
                    //alert('Script cancelled!');
                    return;
                }

                // Limit the file input to psd/psb
                var inputFolderList = inputFolder.getFiles(/\.(psd|psb)$/i);

                // Validate that input folder contains psd/psb files 
                var validateEmptyList = (inputFolderList.length > 0);
                if (validateEmptyList === false) {
                    alert("Script cancelled as the input folder is empty!");
                    return;
                }

                // Alpha-numeric sort
                inputFolderList.sort();

                // Set the output folder
                var outputFolder = Folder.selectDialog("Please select the folder to save to...");
                if (outputFolder === null) {
                    //alert('Script cancelled!');
                    return;
                }

                // TIFF save options
                var tiffSaveOptions = new TiffSaveOptions();
                tiffSaveOptions.imageCompression = TIFFEncoding.NONE;
                tiffSaveOptions.embedColorProfile = true;
                tiffSaveOptions.byteOrder = ByteOrder.IBM;
                tiffSaveOptions.transparency = true;
                tiffSaveOptions.layers = false;
                tiffSaveOptions.layerCompression = LayerCompression.ZIP;
                tiffSaveOptions.interleaveChannels = true;
                tiffSaveOptions.alphaChannels = true;
                tiffSaveOptions.annotations = true;
                tiffSaveOptions.spotColors = true;
                tiffSaveOptions.saveImagePyramid = false;

                // Set the file processing counter
                var outputCounter = 0;

                // Hide the Photoshop panels
                app.togglePalettes();

                // Script running notification window - courtesy of William Campbell
                /* https://www.marspremedia.com/download?asset=adobe-script-tutorial-11.zip
                https://youtu.be/JXPeLi6uPv4?si=Qx0OVNLAOzDrYPB4 */
                var working;
                working = new Window("palette");
                working.preferredSize = [300, 80];
                working.add("statictext");
                working.t = working.add("statictext");
                working.add("statictext");
                working.display = function (message) {
                    this.t.text = message || "Script running, please wait...";
                    this.show();
                    app.refresh();
                };
                working.display();

                // Start Timer
                var timeDiff = {
                    setStartTime: function () {
                        d = new Date();
                        time = d.getTime();
                    },
                    getDiff: function () {
                        d = new Date();
                        t = d.getTime() - time;
                        time = d.getTime();
                        return t;
                    }
                };
                timeDiff.setStartTime();

                // Loop over the psd/psb files
                for (var i = 0; i < inputFolderList.length; i++) {

                    open(inputFolderList[i]);
                    var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                    var layerName = app.activeDocument.activeLayer.name;
                    // Set the zero padding and layer processing counter
                    var zeroPadLength = 3;
                    var layerCounter = 1;

                    // Loop over the top-level layers
                    for (var j = 0; j < app.activeDocument.layers.length; j++) {

                        app.activeDocument.activeLayer = app.activeDocument.layers[j];
                        // Only process smart object layers
                        if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
                            // Active layer processing
                            dupeLayerToDoc(layerName, layerName);
                            rasterizeLayer();
                            layerTransparencyToSelection();
                            executeAction(stringIDToTypeID("inverse"), undefined, DialogModes.NO);
                            app.activeDocument.selection.expand(UnitValue(1, 'px'));
                            contentAwareFill(false, false, false);
                            app.activeDocument.selection.deselect();
                            app.activeDocument.flatten();
                            // Save as TIFF
                            app.activeDocument.saveAs(new File(outputFolder + '/' + docName + ' ' + zeroPad(layerCounter, zeroPadLength) + '.tif'), tiffSaveOptions);
                            // Close the TIFF doc
                            app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                            // Increment the layer processing counter
                            layerCounter++
                            // Increment the file processing counter
                            outputCounter++
                        }
                    }

                    // Close the PSD/PSB doc
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

                }

                // Ensure Photoshop has focus before closing the running script notification window
                app.bringToFront();
                working.close();
                
                // End of script notification
                app.beep();
                alert('Script completed!' + '\r' + inputFolderList.length + ' source PSD/PSB files processed & ' + '\r' + outputCounter + ' TIFF files created.' + "\r" + "Run Time: " + timeDiff.getDiff() / 1000 + " seconds.");

                // Restore the Photoshop panels
                app.togglePalettes();

                // Open the output folder in Windows Explorer or the Mac Finder
                //outputFolder.execute();
                

                ///// Functions /////

                function dupeLayerToDoc(theNewDocName, theLayerName) {
                    var s2t = function (s) {
                        return app.stringIDToTypeID(s);
                    };
                    var descriptor = new ActionDescriptor();
                    var reference = new ActionReference();
                    var reference2 = new ActionReference();
                    reference2.putClass(s2t("document"));
                    descriptor.putReference(s2t("null"), reference2);
                    descriptor.putString(s2t("name"), theNewDocName);
                    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
                    descriptor.putReference(s2t("using"), reference);
                    descriptor.putString(s2t("layerName"), theLayerName);
                    executeAction(s2t("make"), descriptor, DialogModes.NO);
                }

                function rasterizeLayer() {
                    var s2t = function (s) {
                        return app.stringIDToTypeID(s);
                    };
                    var descriptor = new ActionDescriptor();
                    var reference = new ActionReference();
                    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
                    descriptor.putReference(s2t("null"), reference);
                    executeAction(s2t("rasterizeLayer"), descriptor, DialogModes.NO);
                }

                function layerTransparencyToSelection() {
                    var s2t = function (s) {
                        return app.stringIDToTypeID(s);
                    };
                    var descriptor = new ActionDescriptor();
                    var reference = new ActionReference();
                    var reference2 = new ActionReference();
                    reference.putProperty(s2t("channel"), s2t("selection"));
                    descriptor.putReference(s2t("null"), reference);
                    reference2.putEnumerated(s2t("channel"), s2t("channel"), s2t("transparencyEnum"));
                    descriptor.putReference(s2t("to"), reference2);
                    executeAction(s2t("set"), descriptor, DialogModes.NO);
                }

                function contentAwareFill(cafSampleAllLayers, cafScale, cafMirror) {
                    var s2t = function (s) {
                        return app.stringIDToTypeID(s);
                    };
                    var descriptor = new ActionDescriptor();
                    descriptor.putEnumerated(s2t("cafSamplingRegion"), s2t("cafSamplingRegion"), s2t("cafSamplingRegionRectangular"));
                    descriptor.putBoolean(s2t("cafSampleAllLayers"), cafSampleAllLayers);
                    descriptor.putEnumerated(s2t("cafColorAdaptationLevel"), s2t("cafColorAdaptationLevel"), s2t("cafColorAdaptationDefault"));
                    descriptor.putEnumerated(s2t("cafRotationAmount"), s2t("cafRotationAmount"), s2t("cafRotationAmountNone"));
                    descriptor.putBoolean(s2t("cafScale"), cafScale);
                    descriptor.putBoolean(s2t("cafMirror"), cafMirror);
                    descriptor.putEnumerated(s2t("cafOutput"), s2t("cafOutput"), s2t("cafOutputToCurrentLayer"));
                    executeAction(s2t("cafWorkspace"), descriptor, DialogModes.NO);
                }

                function zeroPad(num, digit) {
                    var tmp = num.toString();
                    while (tmp.length < digit) {
                        tmp = "0" + tmp;
                    }
                    return tmp;
                }

            } catch (err) {
                while (app.documents.length > 0) {
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                }
                alert("Error!" + "\r" + err + "\r" +'Line: ' + err.line);
            }

        } else {
            alert('Please close all open documents before running this script!');
        }

    }());

 

crehage2Author
Known Participant
August 22, 2024

Stephen, I don't know how to thank you, really. This is perfect and just what I needed! You are one of the best people ever, on par with whoever it was that decided to put coconut milk in the curry. Is there a way for me to remunerate you for your work?

Stephen Marsh
Community Expert
Community Expert
August 22, 2024

@crehage2 – You’re welcome! You can mark my previous reply with the full code as a correct answer, thanks.

Stephen Marsh
Community Expert
Community Expert
August 22, 2024

@crehage2 

 

Before investing further time in the script, I would like for you to test the basic process for a single active layer.

 

If this produces the result that you are after, I will continue with the code to batch process an input folder and loop over the layers.

 

/*
Proof of concept - active layer
https://community.adobe.com/t5/photoshop-ecosystem-discussions/quot-expand-quot-and-quot-content-aware-fill-quot-functions-are-not-working-via-javascript/td-p/14810803
*/

#target photoshop

    (function () {

        var saveFolder = Folder.selectDialog("Please select the folder to save to...");
        if (saveFolder === null) {
            //alert('Script cancelled!');
            return;
        }
        var docName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
        var layerName = app.activeDocument.activeLayer.name;

        // TIFF save options
        var tiffSaveOptions = new TiffSaveOptions();
        tiffSaveOptions.imageCompression = TIFFEncoding.NONE;
        tiffSaveOptions.embedColorProfile = true;
        tiffSaveOptions.byteOrder = ByteOrder.IBM;
        tiffSaveOptions.transparency = true;
        tiffSaveOptions.layers = false;
        tiffSaveOptions.layerCompression = LayerCompression.ZIP;
        tiffSaveOptions.interleaveChannels = true;
        tiffSaveOptions.alphaChannels = true;
        tiffSaveOptions.annotations = true;
        tiffSaveOptions.spotColors = true;
        tiffSaveOptions.saveImagePyramid = false;

        // Active layer processing
        dupeLayerToDoc(layerName, layerName);
        rasterizeLayer();
        layerTransparencyToSelection();
        executeAction(stringIDToTypeID("inverse"), undefined, DialogModes.NO);
        app.activeDocument.selection.expand(UnitValue(1, 'px'));
        contentAwareFill(false, false, false);
        app.activeDocument.selection.deselect();
        app.activeDocument.flatten();
        
        // Save as TIFF
        app.activeDocument.saveAs(new File(saveFolder + '/' + docName + ' 01' + '.tif'), tiffSaveOptions);
        app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);


        ///// Functions /////

        function dupeLayerToDoc(theNewDocName, theLayerName) {
            var s2t = function (s) {
                return app.stringIDToTypeID(s);
            };
            var descriptor = new ActionDescriptor();
            var reference = new ActionReference();
            var reference2 = new ActionReference();
            reference2.putClass(s2t("document"));
            descriptor.putReference(s2t("null"), reference2);
            descriptor.putString(s2t("name"), theNewDocName);
            reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
            descriptor.putReference(s2t("using"), reference);
            descriptor.putString(s2t("layerName"), theLayerName);
            executeAction(s2t("make"), descriptor, DialogModes.NO);
        }

        function rasterizeLayer() {
            var s2t = function (s) {
                return app.stringIDToTypeID(s);
            };
            var descriptor = new ActionDescriptor();
            var reference = new ActionReference();
            reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
            descriptor.putReference(s2t("null"), reference);
            executeAction(s2t("rasterizeLayer"), descriptor, DialogModes.NO);
        }

        function layerTransparencyToSelection() {
            var s2t = function (s) {
                return app.stringIDToTypeID(s);
            };
            var descriptor = new ActionDescriptor();
            var reference = new ActionReference();
            var reference2 = new ActionReference();
            reference.putProperty(s2t("channel"), s2t("selection"));
            descriptor.putReference(s2t("null"), reference);
            reference2.putEnumerated(s2t("channel"), s2t("channel"), s2t("transparencyEnum"));
            descriptor.putReference(s2t("to"), reference2);
            executeAction(s2t("set"), descriptor, DialogModes.NO);
        }

        function contentAwareFill(cafSampleAllLayers, cafScale, cafMirror) {
            var s2t = function (s) {
                return app.stringIDToTypeID(s);
            };
            var descriptor = new ActionDescriptor();
            descriptor.putEnumerated(s2t("cafSamplingRegion"), s2t("cafSamplingRegion"), s2t("cafSamplingRegionRectangular"));
            descriptor.putBoolean(s2t("cafSampleAllLayers"), cafSampleAllLayers);
            descriptor.putEnumerated(s2t("cafColorAdaptationLevel"), s2t("cafColorAdaptationLevel"), s2t("cafColorAdaptationDefault"));
            descriptor.putEnumerated(s2t("cafRotationAmount"), s2t("cafRotationAmount"), s2t("cafRotationAmountNone"));
            descriptor.putBoolean(s2t("cafScale"), cafScale);
            descriptor.putBoolean(s2t("cafMirror"), cafMirror);
            descriptor.putEnumerated(s2t("cafOutput"), s2t("cafOutput"), s2t("cafOutputToCurrentLayer"));
            executeAction(s2t("cafWorkspace"), descriptor, DialogModes.NO);
        }

    }());

 

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

crehage2Author
Known Participant
August 22, 2024

Hey Stephen. I tried it on an opened single layer PSD, and it worked! Wow!

Stephen Marsh
Community Expert
Community Expert
August 21, 2024
quote

Apply Content-Aware Fill with “rectangular sampling area”.


By @crehage2

 

 

Please provide a screenshot of the CAF interface with all options expanded/visible and set as you need them.

 

 

Save layer as 16bit tiff.


 

Save where? The same folder as the source layered file? Somewhere else?

 

What filename (layer name, original doc name + layer name etc)?

 

What TIFF save options? Please provide a screenshot with all options set as you need them.

crehage2Author
Known Participant
August 21, 2024

Hey Steven, thank you for being so kind. I tried posting a reply here, but it vanished somehow. Will try again.

 

So here is a series of screenshots to illustrate the steps - I initially wanted to share a sample document but that apparently prevented my reply from being published at all.

 

The routine I am looking for would be as follows:

1. prompt for folder containing PSDs (or PSBs)

2. prompt for target folder for TIFF files

3. open PSDs one after the other and apply routine

4. treat each layer, starting from the top, as following:

4.1. duplicate to new document

4.2.rasterize layer

4.3. select layer

4.4. invert selection

4.5. expand selection by 1 pixel

4.6. apply Content-Aware Fill with "rectangular sampling area"

4.7. deselect

4.8. flatten image

4.9. save layer as 16bit Tiff (naming convention: name of PSD from 3. plus number of layer from 4., i.e. "09 Georgia shades 01.tif"

4.10. close document

5. repeat on following layers

6. repeat on following PSDs

7. display message saying how many PSD files have been processed and how many TIFFs exported

 

I have about 1,000 PSD files containing about 10 layers each, which is why I would like to automate this process.

 

I am very grateful for any hints you can give me. 🙂

Stephen Marsh
Community Expert
Community Expert
August 21, 2024

@crehage2 

 

Thanks for the step-by-step breakdown.

 

Unfortunately, the screenshots don't help me that much. I asked for the following:

 

  • Please provide a screenshot of the CAF interface with all options expanded/visible and set as you need them.

 

  • What TIFF save options? Please provide a screenshot with all options set as you need them.

 

 

 

Stephen Marsh
Community Expert
Community Expert
August 20, 2024
quote
  1. Duplicate layer to new document. 
  2. Rasterize layer. 
  3. Select layer. 
  4. Invert selection.
  5. Expand selection by 1 pixel.
  6. Apply Content-Aware Fill with “rectangular sampling area”.
  7. Deselect. 
  8. Save layer as 16bit tiff.

By @crehage2

 

All of these steps should be possible with an action (apart from a "clean" document name when duplicating).

 

Why do you need a script?

 

Where are you stuck with scripting? Do you know how to script?

 

Are you looking for legacy ExtendScript or the new UXP scripting?

 

crehage2Author
Known Participant
August 20, 2024

Hey Stephen, thanks for your patience! No, I don't know much about these things actually. I found a guy who does JavaScript who said he could help me with it, but it seems as though we're not really getting anywhere. I have thousands of PSDs with about a dozen or so layers each, so some sort of automation would be very helpful. You think I should look into "actions", right?

Stephen Marsh
Community Expert
Community Expert
August 20, 2024

Actions should be able to automate the steps, but not the naming when duplicating the layer to a new document. You would still need a script to automate looping over all the layers if they varied in name or number/count, which an action could handle. There are various scripts to run an action over selected layers, all layers etc.

 

Are you using layer groups or artboards? Is it every pixel layer where you need this? Or should some layers be skipped, such as a special Background layer or adjustment layers, gradient or fill layers etc.

Legend
August 20, 2024

I'm unclear about what you mean by expand a mask. You can expand a selection but that simply adds pixels to that selection. Content-aware fill is not available for a layer mask.

crehage2Author
Known Participant
August 20, 2024

Thank you, Lumigraphics. I am sorry for not expressing myself more clearly. I want to have a JavaScript code that creates a selection from a layer, then expands the selection by 1 pixel and applies a Content Aware Fill to the selection.

Legend
August 20, 2024

Ok, how are you creating the selection? And when you do a content-aware fill, you have to manually specify what part of the image to use as source and the parameters/settings.

I don't think this is really something that can be scripted.

Stephen Marsh
Community Expert
Community Expert
August 20, 2024

Please provide before and after screenshots including any relevant panels and settings or sample files to clarify your post.

crehage2Author
Known Participant
August 20, 2024

Thanks, Stephen, and congrats on that awesome avatar! These are the two steps I would like to automate via JavaScript. Thanks for your help!