Skip to main content
Participating Frequently
March 11, 2023
해결됨

Is there a script to apply a series of alpha channels in bulk to a series of images?

  • March 11, 2023
  • 1 답변
  • 6237 조회

Hi everyone.

I have a series of numbered images (image001.jpg, image002.jpg etc) and I also have, in a different folder, their corresponding alpha channel images in B/W (image001_alpha, image002_alpha etc).

I would like to know whether there is a script that would open each and every image, then opening their corresponding alpha images, applying them, and then saving the results, following the numbering, in a series of psd files, each without the background layer and with a new layer including the image with its alpha mask created, applied but not merged. The script should stop when reaching the last numbered image. Would that be possible? Thanks

이 주제는 답변이 닫혔습니다.
최고의 답변: Stephen Marsh

Hi.

In response:

Alpha images are .jpg as well.

Alpha channels are layered (even if a version of the script with them flattened would come handy)

Colour mode is RGBAttaching 2 sample files.

 

 

 

 


@Víctor28824201coyo – The file names don't alphabetically sort/match:

 

ALPHA.Alpha.0000.jpg

image.RGB_color.0000.jpg

 

They need to for the current code.

 

I'll presume that the actual production files do have the same name prefix, such as:

 

0001.Alpha.0000.jpg

0001.RGB_color.0000.jpg

 

But much better than making presumptions, please qualify the exact names. This is why I asked for at least 2 copies of the image and 2 copies of the matching mask files.

 

Is the attached PSD result what you are looking for (resized to 50% px size to reduce file size for the forum upload)? I have a working version of the script for alphabetically sorting file names.

 

Edit: Here is a v1.0 script, it is probably better to get feedback at this point.

 

/*
Mask JPEG Images with JPEG Masks from 2 Separate Input Folders.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/is-there-a-script-to-apply-a-series-of-alpha-channels-in-bulk-to-a-series-of-images/td-p/13642975
v1.0 - 12 March 2023, Stephen Marsh
*/

#target photoshop

(function () {

    if (app.documents.length === 0) {

        try {

            // Image input folder
            var folder1 = Folder.selectDialog("Select the image folder:");
            if (folder1 === null) {
                //alert('Script cancelled!');
                return;
            }

            // Mask input folder
            var folder2 = Folder.selectDialog("Select the mask folder:");
            if (folder2 === null) {
                //alert('Script cancelled!');
                return;
            }

            // Validate input folder selection
            var validateInputDir = (folder1.fsName === folder2.fsName);
            if (validateInputDir === true) {
                alert("Script cancelled as both the input folders are the same!");
                return;
            }

            // Limit the file input to jpg/jpeg, case insensitive
            var list1 = folder1.getFiles(/\.(jpg|jpeg)$/i);
            var list2 = folder2.getFiles(/\.(jpg|jpeg)$/i);

            // Alpha-numeric sort
            list1.sort();
            list2.sort();

            // Validate that folder 1 & 2 lists are not empty 
            var validateEmptyList = (list1.length > 0 && list2.length > 0);
            if (validateEmptyList === false) {
                alert("Script cancelled as one of the input folders is empty!");
                return;
            }

            // Validate that the item count in folder 1 & 2 matches
            var validateListLength = (list1.length === list2.length);
            if (validateListLength === false) {
                alert("Script cancelled as the input folders don't have equal quantities of images!");
                return;
            }

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

            // Save and set the dialog display settings
            var savedDisplayDialogs = app.displayDialogs;
            app.displayDialogs = DialogModes.NO;

            // PSD save options
            var psdOptions = new PhotoshopSaveOptions();
            psdOptions.embedColorProfile = true;
            psdOptions.alphaChannels = true;
            psdOptions.layers = true;
            psdOptions.spotColors = true;

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

            // Perform the stacking and saving
            for (var i = 0; i < list1.length; i++) {
                // Open the image and get the name
                var doc = open(list1[i]);
                var docName = doc.name.replace(/\.[^\.]+$/, '');
                // Place the mask as a layer
                placeFile(list2[i], 100);
                // Load the mask RGB channel as a selection
                channelSelection();
                // Remove the mask layer
                activeDocument.activeLayer.remove();
                // Add a layer mask from the selection to the image
                maskSelection("revealSelection");
                // Rename layer to image doc name
                activeDocument.activeLayer.name = docName;
                // Save and close the PSD version
                doc.saveAs(new File(saveFolder + '/' + docName + '.psd'), psdOptions);
                doc.close(SaveOptions.DONOTSAVECHANGES);
                // Increment the file processing counter for each file processed
                fileCounter++;
            }

            // End of script
            app.displayDialogs = savedDisplayDialogs;
            app.beep();
            alert('Script completed!' + '\r' + fileCounter + ' masked PSD files of ' + list1.length + ' input files saved to:' + '\r' + saveFolder.fsName);

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

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


    ///// Functions /////

    function placeFile(file, scale) {
        try {
            var idPlc = charIDToTypeID("Plc ");
            var desc2 = new ActionDescriptor();
            var idnull = charIDToTypeID("null");
            desc2.putPath(idnull, new File(file));
            var idFTcs = charIDToTypeID("FTcs");
            var idQCSt = charIDToTypeID("QCSt");
            var idQcsa = charIDToTypeID("Qcsa");
            desc2.putEnumerated(idFTcs, idQCSt, idQcsa);
            var idOfst = charIDToTypeID("Ofst");
            var desc3 = new ActionDescriptor();
            var idHrzn = charIDToTypeID("Hrzn");
            var idPxl = charIDToTypeID("#Pxl");
            desc3.putUnitDouble(idHrzn, idPxl, 0.000000);
            var idVrtc = charIDToTypeID("Vrtc");
            var idPxl = charIDToTypeID("#Pxl");
            desc3.putUnitDouble(idVrtc, idPxl, 0.000000);
            var idOfst = charIDToTypeID("Ofst");
            desc2.putObject(idOfst, idOfst, desc3);
            var idWdth = charIDToTypeID("Wdth");
            var idPrc = charIDToTypeID("#Prc");
            desc2.putUnitDouble(idWdth, idPrc, scale);
            var idHght = charIDToTypeID("Hght");
            var idPrc = charIDToTypeID("#Prc");
            desc2.putUnitDouble(idHght, idPrc, scale);
            var idAntA = charIDToTypeID("AntA");
            desc2.putBoolean(idAntA, true);
            executeAction(idPlc, desc2, DialogModes.NO);
        } catch (e) {}
    }

    function channelSelection() {
        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("grain"));
        descriptor.putReference(s2t("to"), reference2);
        executeAction(s2t("set"), descriptor, DialogModes.NO);
    }

    function maskSelection(maskParameter) {
        // Parameter = "revealSelection" or "hideSelection"
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var reference = new ActionReference();
        descriptor.putClass(s2t("new"), s2t("channel"));
        reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("mask"));
        descriptor.putReference(s2t("at"), reference);
        descriptor.putEnumerated(s2t("using"), s2t("userMaskEnabled"), s2t(maskParameter));
        executeAction(s2t("make"), descriptor, DialogModes.NO);
    }

}());

 

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

1 답변

Participating Frequently
March 11, 2023

Thanks so much.

I'll look into them.

Participating Frequently
March 12, 2023

@Víctor28824201coyo – The file names don't alphabetically sort/match:

 

ALPHA.Alpha.0000.jpg

image.RGB_color.0000.jpg

 

They need to for the current code.

 

I'll presume that the actual production files do have the same name prefix, such as:

 

0001.Alpha.0000.jpg

0001.RGB_color.0000.jpg

 

But much better than making presumptions, please qualify the exact names. This is why I asked for at least 2 copies of the image and 2 copies of the matching mask files.

 

Is the attached PSD result what you are looking for (resized to 50% px size to reduce file size for the forum upload)? I have a working version of the script for alphabetically sorting file names.

 

Edit: Here is a v1.0 script, it is probably better to get feedback at this point.

 

/*
Mask JPEG Images with JPEG Masks from 2 Separate Input Folders.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/is-there-a-script-to-apply-a-series-of-alpha-channels-in-bulk-to-a-series-of-images/td-p/13642975
v1.0 - 12 March 2023, Stephen Marsh
*/

#target photoshop

(function () {

    if (app.documents.length === 0) {

        try {

            // Image input folder
            var folder1 = Folder.selectDialog("Select the image folder:");
            if (folder1 === null) {
                //alert('Script cancelled!');
                return;
            }

            // Mask input folder
            var folder2 = Folder.selectDialog("Select the mask folder:");
            if (folder2 === null) {
                //alert('Script cancelled!');
                return;
            }

            // Validate input folder selection
            var validateInputDir = (folder1.fsName === folder2.fsName);
            if (validateInputDir === true) {
                alert("Script cancelled as both the input folders are the same!");
                return;
            }

            // Limit the file input to jpg/jpeg, case insensitive
            var list1 = folder1.getFiles(/\.(jpg|jpeg)$/i);
            var list2 = folder2.getFiles(/\.(jpg|jpeg)$/i);

            // Alpha-numeric sort
            list1.sort();
            list2.sort();

            // Validate that folder 1 & 2 lists are not empty 
            var validateEmptyList = (list1.length > 0 && list2.length > 0);
            if (validateEmptyList === false) {
                alert("Script cancelled as one of the input folders is empty!");
                return;
            }

            // Validate that the item count in folder 1 & 2 matches
            var validateListLength = (list1.length === list2.length);
            if (validateListLength === false) {
                alert("Script cancelled as the input folders don't have equal quantities of images!");
                return;
            }

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

            // Save and set the dialog display settings
            var savedDisplayDialogs = app.displayDialogs;
            app.displayDialogs = DialogModes.NO;

            // PSD save options
            var psdOptions = new PhotoshopSaveOptions();
            psdOptions.embedColorProfile = true;
            psdOptions.alphaChannels = true;
            psdOptions.layers = true;
            psdOptions.spotColors = true;

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

            // Perform the stacking and saving
            for (var i = 0; i < list1.length; i++) {
                // Open the image and get the name
                var doc = open(list1[i]);
                var docName = doc.name.replace(/\.[^\.]+$/, '');
                // Place the mask as a layer
                placeFile(list2[i], 100);
                // Load the mask RGB channel as a selection
                channelSelection();
                // Remove the mask layer
                activeDocument.activeLayer.remove();
                // Add a layer mask from the selection to the image
                maskSelection("revealSelection");
                // Rename layer to image doc name
                activeDocument.activeLayer.name = docName;
                // Save and close the PSD version
                doc.saveAs(new File(saveFolder + '/' + docName + '.psd'), psdOptions);
                doc.close(SaveOptions.DONOTSAVECHANGES);
                // Increment the file processing counter for each file processed
                fileCounter++;
            }

            // End of script
            app.displayDialogs = savedDisplayDialogs;
            app.beep();
            alert('Script completed!' + '\r' + fileCounter + ' masked PSD files of ' + list1.length + ' input files saved to:' + '\r' + saveFolder.fsName);

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

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


    ///// Functions /////

    function placeFile(file, scale) {
        try {
            var idPlc = charIDToTypeID("Plc ");
            var desc2 = new ActionDescriptor();
            var idnull = charIDToTypeID("null");
            desc2.putPath(idnull, new File(file));
            var idFTcs = charIDToTypeID("FTcs");
            var idQCSt = charIDToTypeID("QCSt");
            var idQcsa = charIDToTypeID("Qcsa");
            desc2.putEnumerated(idFTcs, idQCSt, idQcsa);
            var idOfst = charIDToTypeID("Ofst");
            var desc3 = new ActionDescriptor();
            var idHrzn = charIDToTypeID("Hrzn");
            var idPxl = charIDToTypeID("#Pxl");
            desc3.putUnitDouble(idHrzn, idPxl, 0.000000);
            var idVrtc = charIDToTypeID("Vrtc");
            var idPxl = charIDToTypeID("#Pxl");
            desc3.putUnitDouble(idVrtc, idPxl, 0.000000);
            var idOfst = charIDToTypeID("Ofst");
            desc2.putObject(idOfst, idOfst, desc3);
            var idWdth = charIDToTypeID("Wdth");
            var idPrc = charIDToTypeID("#Prc");
            desc2.putUnitDouble(idWdth, idPrc, scale);
            var idHght = charIDToTypeID("Hght");
            var idPrc = charIDToTypeID("#Prc");
            desc2.putUnitDouble(idHght, idPrc, scale);
            var idAntA = charIDToTypeID("AntA");
            desc2.putBoolean(idAntA, true);
            executeAction(idPlc, desc2, DialogModes.NO);
        } catch (e) {}
    }

    function channelSelection() {
        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("grain"));
        descriptor.putReference(s2t("to"), reference2);
        executeAction(s2t("set"), descriptor, DialogModes.NO);
    }

    function maskSelection(maskParameter) {
        // Parameter = "revealSelection" or "hideSelection"
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var reference = new ActionReference();
        descriptor.putClass(s2t("new"), s2t("channel"));
        reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("mask"));
        descriptor.putReference(s2t("at"), reference);
        descriptor.putEnumerated(s2t("using"), s2t("userMaskEnabled"), s2t(maskParameter));
        executeAction(s2t("make"), descriptor, DialogModes.NO);
    }

}());

 

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


Thanks so much.

I will test this script. In the meantime, I am attaching several low-res renamed files. Hope they work for you. Thanks again.