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

Looking for a script or action to batch process 3400+ files. Need help!

Explorer ,
Jun 13, 2024 Jun 13, 2024

First, I filmed a video of what I need to do on a mass scale batch process. So that's attached. I've also attached a sample PSD and PNG file. 

 

I'm the Emoji Stickers guy and I need to create a mockup of a hand holding an emoji sticker for all 3400+ emojis. 

Here's what I do manually: 

I have a PSD open. In the PSD there are three (3) layers: 1. Background (Bottom Layer), 2. Hand (Middle Layer), and 3. Thumb/Fingers (Top Layer).  (This PSD is attached)

 

With the PSD open, it would import the Emoji Sticker PNG file, place it in it's own layer above the Hand layer and below the Fingers layer, resize it to 21%, center it on the artboard, and save as PNG. 

 

After saving, it would delete that layer, and repeat with the the next PNG in that folder. 

 

Also, would be amazing to name the newly exported PNG the same name as the original PNG (emoji) that was imported. 

 

Can this be done? Free emoji stickers to anymore that can figure this out 🤙

TOPICS
Actions and scripting , macOS
743
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Jun 13, 2024 Jun 13, 2024

@EmojiStickers.com 

 

Try this script. The template document must be open. You will be prompted to select the input folder containing the source emoji PNG files. You will be prompted to select the output folder to save the new combined PNG files to.

 

/*
Batch Emoji Mockup.jsx
v1.0 - 14th June 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/looking-for-a-script-or-action-to-batch-process-3400-files-need-help/td-p/14680348
*/

#target photoshop

if (app.document
...
Translate
Adobe
Community Expert ,
Jun 13, 2024 Jun 13, 2024

This could be done via an Action and the Batch command, including the correct naming (it just has to be setup opposite to most people's expectations) – however, a Script would be better.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jun 13, 2024 Jun 13, 2024

Do you have a script?

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 13, 2024 Jun 13, 2024
quote

Do you have a script?

 


By @EmojiStickers.com


It would need to be written for your specific work, this isn't generic.

 

Where is the PNG saved? Next to the PSD or elsewhere?

 

The uploaded PSD has 4 layers, there is a "Layer 1" with content moved outside of the canvas. Is this an error, you mentioned only 3 layers?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 13, 2024 Jun 13, 2024
quote

Do you have a script?

That’s kind of funny (in a strict interpretation of the question itself at least). 

I am sure @Stephen Marsh has more than one Script … 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 13, 2024 Jun 13, 2024
LATEST
quote
quote

Do you have a script?

That’s kind of funny (in a strict interpretation of the question itself at least). 

I am sure @Stephen Marsh has more than one Script … 


By @c.pfaffenbichler

 

Indeed, I started collecting them long before I finally got around to learning scripting!  ;]

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 13, 2024 Jun 13, 2024
Uses ExtendScript not AppleScript but you can convert it if need be. Just replace the path to your folder.


//Global Variables
var pngFolder = "C:/PathToYourPngFolder"
var doc = app.activeDocument

//Script
main();

//Functions
   
// Function to place and resize PNGs
function placeAndResizePNG(filePath, handLayer, fingersLayer, doc) {
    var pngFile = new File(filePath);
   
    activeDocument.activeLayer = doc.artLayers.getByName(handLayer);
    // Place PNG file
    app.open(pngFile);
    app.activeDocument.activeLayer.duplicate(doc);
    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
    var placedLayer = doc.activeLayer;

    // Move the layer to the above the hand layer
    placedLayer.move(doc.artLayers.getByName(handLayer), ElementPlacement.PLACEBEFORE);
    // Resize to 21%
    var bounds = placedLayer.bounds;
    var width = bounds[2] - bounds[0];
    var height = bounds[3] - bounds[1];
    var resizePercentage = 21;
    placedLayer.resize(resizePercentage, resizePercentage, AnchorPosition.MIDDLECENTER);

    // Center the layer
    placedLayer.translate(-(placedLayer.bounds[0] + placedLayer.bounds[2]) / 2 + doc.width / 2,
                          -(placedLayer.bounds[1] + placedLayer.bounds[3]) / 2 + doc.height / 2);

    //Save the file into a new folder nested in the original folder
    var saveFolder = new Folder(pngFolder + "/Resized");
    if (!saveFolder.exists) {
        saveFolder.create();
    }
    var saveFile = new File(saveFolder + "/" + pngFile.name);
    var pngSaveOptions = new PNGSaveOptions();
    pngSaveOptions.compression = 9;
    doc.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);
   
    // Delete the imported layer
    placedLayer.remove();
}

// Main function
function main() {
var doc = app.activeDocument;

    var handLayerName = "Hand Bottom"; // Update with your hand layer name
    var fingersLayerName = "Hand Top"; // Update with your fingers layer name

    var pngFiles = Folder(pngFolder).getFiles("*.png");

    for (var i = 0; i < pngFiles.length; i++) {
        placeAndResizePNG(pngFiles[i].fsName, handLayerName, fingersLayerName, doc);
    }
    doc.close(SaveOptions.DONOTSAVECHANGES);
}
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 13, 2024 Jun 13, 2024

@EmojiStickers.com 

 

Try this script. The template document must be open. You will be prompted to select the input folder containing the source emoji PNG files. You will be prompted to select the output folder to save the new combined PNG files to.

 

/*
Batch Emoji Mockup.jsx
v1.0 - 14th June 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/looking-for-a-script-or-action-to-batch-process-3400-files-need-help/td-p/14680348
*/

#target photoshop

if (app.documents.length) {

    (function () {

        try {
            // Select the source files
            /*
            var theFiles = File.openDialog('Select the file/s:', Multiselect = true);
            if (theFiles === null) {
                alert('Script cancelled!');
                return;
            }
            */
            
            // Select the input folder
            var theFiles = Folder.selectDialog("Select the folder containing the emoji PNG files:");
            if (theFiles === null) {
                alert('Script cancelled!');
                return;
            }
            var fileList = theFiles.getFiles(/\.(png)$/i);
            fileList.sort();

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

            // 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();

            // Set the file counter
            var counter = 0;

            // Get and set the ruler units
            var origRulerUnits = app.preferences.rulerUnits;
            app.preferences.rulerUnits = Units.PIXELS;

            // Set the active doc as the template doc
            var templateDoc = app.activeDocument;
            var templateDocName = app.activeDocument.name;

            // Ensure that the Hand Bottom layer is active
            if (app.activeDocument.activeLayer.name != 'Hand Bottom') {
                app.activeDocument.activeLayer = app.activeDocument.layers.getByName('Hand Bottom');
            }

            // Remove unnecessary metadata
            removeDocumentAncestorsMetadata();
            removeCRSmetadata();
            removeXMPmetadata();

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

                // Open each selected file
                app.open(File(fileList[i]));

                // Set the sourceDoc as the active document
                var sourceDoc = app.activeDocument;

                // Select the source layer
                app.activeDocument.activeLayer = app.activeDocument.layers[0];

                // Duplicate the source layer to the template doc
                dupeLayer(templateDocName, app.activeDocument.name.replace(/\.[^\.]+$/, ''));

                // Set the template doc as the active document
                app.activeDocument = templateDoc;

                // Centre the duped layer on the template canvas
                app.activeDocument.activeLayer.translate(app.activeDocument.width / 2 - (app.activeDocument.activeLayer.bounds[0] + app.activeDocument.activeLayer.bounds[2]) / 2,
                    app.activeDocument.height / 2 - (app.activeDocument.activeLayer.bounds[1] + app.activeDocument.activeLayer.bounds[3]) / 2);
                
                // Resize to 21% scale
                scaleLayer(21.0, 21.0);

                // Close the source doc
                sourceDoc.close(SaveOptions.DONOTSAVECHANGES);

                // File name from emoji layer name
                var docName = app.activeDocument.activeLayer.name.replace(/\.[^\.]+$/, '');

                // Save as PNG options
                var pngFile = new File(outputFolder + "/" + docName + ".png");
                var pngOptions = new PNGSaveOptions();
                pngOptions.compression = 9; // 0-9
                pngOptions.interlaced = false;
                app.activeDocument.saveAs(pngFile, pngOptions, true, Extension.LOWERCASE);

                // Delete the emoji layer
                app.activeDocument.activeLayer.remove();

                // Increment the file counter
                counter++
            }

            // Restore the original ruler units
            app.preferences.rulerUnits = origRulerUnits;

            // Close the template doc
            templateDoc.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' + counter + ' files saved to:' + '\r' + outputFolder);

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


            // Functions

            function dupeLayer(targetDocName, sourceLayerName) {
                function s2t(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"), targetDocName);
                descriptor.putReference(s2t("to"), reference2);
                descriptor.putString(s2t("name"), sourceLayerName);
                descriptor.putList(s2t("ID"), list);
                executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
            }

            function scaleLayer(width, height) {
                var s2t = function (s) {
                    return app.stringIDToTypeID(s);
                };
                var descriptor = new ActionDescriptor();
                var descriptor2 = new ActionDescriptor();
                var reference = new ActionReference();
                reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
                descriptor.putReference(s2t("null"), reference);
                descriptor.putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSAverage"));
                descriptor2.putUnitDouble(s2t("horizontal"), s2t("pixelsUnit"), 0);
                descriptor2.putUnitDouble(s2t("vertical"), s2t("pixelsUnit"), 0);
                descriptor.putObject(s2t("offset"), s2t("offset"), descriptor2);
                descriptor.putUnitDouble(s2t("width"), s2t("percentUnit"), width);
                descriptor.putUnitDouble(s2t("height"), s2t("percentUnit"), height);
                descriptor.putEnumerated(s2t("interfaceIconFrameDimmed"), s2t("interpolationType"), s2t("bicubicSmoother"));
                executeAction(s2t("transform"), descriptor, DialogModes.NO);
            }

            function removeXMPmetadata() {
                //https://community.adobe.com/t5/photoshop/script-to-remove-all-meta-data-from-the-photo/td-p/10400906
                if (!documents.length) return;
                if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
                XMPUtils.removeProperties(xmp, "", "", XMPConst.REMOVE_ALL_PROPERTIES);
                app.activeDocument.xmpMetadata.rawData = xmp.serialize();
            }

            function removeCRSmetadata() {
                //community.adobe.com/t5/photoshop/remove-crs-metadata/td-p/10306935
                if (!documents.length) return;
                if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                var xmp = new XMPMeta(app.activeDocument.xmpMetadata.rawData);
                XMPUtils.removeProperties(xmp, XMPConst.NS_CAMERA_RAW, "", XMPConst.REMOVE_ALL_PROPERTIES);
                app.activeDocument.xmpMetadata.rawData = xmp.serialize();
            }

            function removeDocumentAncestorsMetadata() {
                whatApp = String(app.name); //String version of the app name
                if (whatApp.search("Photoshop") > 0) { //Check for photoshop specifically, or this will cause errors
                    if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                    var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
                    // Begone foul Document Ancestors!
                    xmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "DocumentAncestors");
                    app.activeDocument.xmpMetadata.rawData = xmp.serialize();
                }
            }

        } catch (e) {
            alert('Error!' + '\r' + e + ', Line: ' + e.line);
        }

    })();

} else {
    alert('A document must be open to run this script!');
}

 

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines