Copy Alpha Channels

Script for Adobe Photoshop

The script copies the alpha channels from images in one folder to matching images in another folder. The script also serves as a template for creating additional scripts that perform other tasks, easily accomplished by altering the 'processDoc()' function.

  • Copy channels from one set of images to another
  • Option to match names exactly or if name contains the other
  • Adapt open source to customize or create other scripts
Download
Copy Alpha Channels
Help me keep making new scripts by supporting my work. Click the PayPal button to contribute any amount you choose. Thank you. William Campbell

How to use the script

The interface has three sections: Source images, Target images, and Match file names, ignoring extension. Set desired options then click the OK button to begin. A progress bar is displayed as images are processed.

Section 1: Source images

Folder — select a folder of images with alpha channels to copy.

Section 2: Target images

Folder — select a folder of images to which alpha channels will be copied, if a file matching the name (based on options below) is found in the source images folder.

Section 3: Match file names, ignoring extension

Exact — the source and target base name (file name without extension) match exactly.

Contains source name — the target image base name contains the source image base name.

Contains target name — the source image base name contains the target image base name.

Source code

(download button below)

/*
Copy Alpha Channels
Copyright 2023 William Campbell
All Rights Reserved
https://www.marspremedia.com/contact

Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

(function () {

    var title = "Copy Alpha Channels";

    if (!/photoshop/i.test(app.name)) {
        alert("Script for Photoshop", title, false);
        return;
    }

    app.displayDialogs = DialogModes.ERROR;

    // Script variables.
    var doneMessage;
    var error;
    var filesSource;
    var filesTarget;
    var folderSource;
    var folderTarget;
    var progress;

    // Reusable UI variables.
    var g; // group
    var p; // panel
    var w; // window

    // Permanent UI variables.
    var btnCancel;
    var btnFolderSource;
    var btnFolderTarget;
    var btnOk;
    var rbMatchExact;
    var rbMatchSource;
    var rbMatchTarget;
    var txtFolderSource;
    var txtFolderTarget;

    // CREATE PROGRESS WINDOW

    progress = new Window("palette", "Progress");
    progress.t = progress.add("statictext");
    progress.t.preferredSize.width = 450;
    progress.b = progress.add("progressbar");
    progress.b.preferredSize.width = 450;
    progress.add("statictext", undefined, "Press ESC to cancel");
    progress.display = function (message) {
        message && (this.t.text = message);
        this.show();
        app.refresh();
    };
    progress.increment = function () {
        this.b.value++;
    };
    progress.set = function (steps) {
        this.b.value = 0;
        this.b.minvalue = 0;
        this.b.maxvalue = steps;
    };

    // CREATE USER INTERFACE

    w = new Window("dialog", title);
    w.alignChildren = "fill";

    // Panel 'Source images'
    p = w.add("panel", undefined, "Source images");
    p.margins = [18, 18, 18, 18];
    g = p.add("group");
    btnFolderSource = g.add("button", undefined, "Folder...");
    txtFolderSource = g.add("statictext", undefined, undefined, {
        truncate: "middle"
    });
    txtFolderSource.preferredSize.width = 350;

    // Panel 'Target images'
    p = w.add("panel", undefined, "Target images");
    p.margins = [18, 18, 18, 18];
    g = p.add("group");
    btnFolderTarget = g.add("button", undefined, "Folder...");
    txtFolderTarget = g.add("statictext", undefined, undefined, {
        truncate: "middle"
    });
    txtFolderTarget.preferredSize.width = 350;

    // Panel 'Match file names, ignoring extension'
    p = w.add("panel", undefined, "Match file names, ignoring extension");
    p.margins = [18, 18, 18, 18];
    p.alignChildren = "left";
    g = p.add("group");
    g.orientation = "row";
    rbMatchExact = g.add("radiobutton", undefined, "Exact");
    rbMatchExact.value = true;
    rbMatchSource = g.add("radiobutton", undefined, "Contains source name");
    rbMatchTarget = g.add("radiobutton", undefined, "Contains target name");

    // Action Buttons
    g = w.add("group");
    g.alignment = "center";
    btnOk = g.add("button", undefined, "OK");
    btnCancel = g.add("button", undefined, "Cancel");

    // Panel Copyright
    p = w.add("panel");
    p.add("statictext", undefined, "Copyright 2023 William Campbell");

    // UI ELEMENT EVENT HANDLERS

    btnFolderSource.onClick = function () {
        var f = Folder.selectDialog("Select folder of source images", txtFolderSource.text);
        if (f) {
            txtFolderSource.text = Folder.decode(f.fullName);
        }
    };

    btnFolderTarget.onClick = function () {
        var f = Folder.selectDialog("Select folder of target images", txtFolderTarget.text);
        if (f) {
            txtFolderTarget.text = Folder.decode(f.fullName);
        }
    };

    btnOk.onClick = function () {
        folderSource = new Folder(txtFolderSource.text);
        if (!(folderSource && folderSource.exists)) {
            alert("Select folder of source images", " ", false);
            return;
        }
        folderTarget = new Folder(txtFolderTarget.text);
        if (!(folderTarget && folderTarget.exists)) {
            alert("Select folder of target images", " ", false);
            return;
        }
        w.close(1);
    };

    btnCancel.onClick = function () {
        w.close(0);
    };

    // DISPLAY THE DIALOG

    if (w.show() == 1) {
        doneMessage = "";
        try {
            process();
            doneMessage = doneMessage || "Done";
        } catch (e) {
            if (/User cancel/.test(e.message)) {
                doneMessage = "Canceled";
            } else {
                error = error || e;
                doneMessage = "An error has occurred.\nLine " + error.line + ": " + error.message;
            }
        }
        app.bringToFront();
        progress.close();
        doneMessage && alert(doneMessage, title, error);
    }

    //====================================================================
    //               END PROGRAM EXECUTION, BEGIN FUNCTIONS
    //====================================================================

    function process() {
        var baseName;
        var baseNamesSource;
        var docSource;
        var docTarget;
        var source;
        var target;
        var i;
        var ii;
        app.displayDialogs = DialogModes.NO;
        progress.display("Reading folders...");
        try {
            // Gather collection of source files.
            filesSource = folderSource.getFiles(function (f) {
                if (f instanceof File && !f.hidden) {
                    return true;
                }
                return false;
            });
            // Gather collection of target files.
            filesTarget = folderTarget.getFiles(function (f) {
                if (f instanceof File && !f.hidden) {
                    return true;
                }
                return false;
            });
            if (!filesSource.length || !filesTarget.length) {
                doneMessage = "No files found in one or more selected folders";
                return;
            }
            // Compile array of source files names minus extension.
            baseNamesSource = [];
            for (i = 0; i < filesSource.length; i++) {
                baseNamesSource[i] = File.decode(filesSource[i].name).replace(/\.[^\.]*$/, "");
            }
            progress.set(filesTarget.length);
            // Loop through all files.
            for (i = 0; i < filesTarget.length; i++) {
                source = null;
                target = filesTarget[i];
                progress.increment();
                progress.display(File.decode(target.name));
                // Look for matching source file.
                // Same name minus extension.
                baseName = File.decode(target.name).replace(/\.[^\.]*$/, "");
                for (ii = 0; ii < baseNamesSource.length; ii++) {
                    if (rbMatchExact.value) {
                        // Match exact.
                        if (baseNamesSource[ii] == baseName) {
                            // Match.
                            source = filesSource[ii];
                            break;
                        }
                    } else if (rbMatchSource.value) {
                        // Match if target contains source.
                        if (baseName.indexOf(baseNamesSource[ii]) > -1) {
                            // Match.
                            source = filesSource[ii];
                            break;
                        }
                    } else if (rbMatchTarget.value) {
                        // Match if source contains target.
                        if (baseNamesSource[ii].indexOf(baseName) > -1) {
                            // Match.
                            source = filesSource[ii];
                            break;
                        }
                    }
                }
                if (source) {
                    // Found match. Open images and process.
                    docSource = app.open(source);
                    docTarget = app.open(target);
                    processDoc(docSource, docTarget);
                    docSource.close(SaveOptions.DONOTSAVECHANGES);
                    docTarget.close(SaveOptions.SAVECHANGES);
                }
            }
        } finally {
            app.displayDialogs = DialogModes.ERROR;
        }
    }

    function processDoc(docSource, docTarget) {
        var channel;
        var i;
        app.activeDocument = docSource;
        // Loop through channels looking for alpha channels.
        for (i = 0; i < docSource.channels.length; i++) {
            channel = docSource.channels[i];
            if (channel.kind == ChannelType.MASKEDAREA || channel.kind == ChannelType.SELECTEDAREA) {
                // Channel is alpha. Copy to target document.
                channel.duplicate(docTarget, ElementPlacement.PLACEATEND);
            }
        }
    }

})();
Help me keep making new scripts by supporting my work. Click the PayPal button to contribute any amount you choose. Thank you. William Campbell
Download
Copy Alpha Channels

For help installing scripts, see How to Install and Use Scripts in Adobe Creative Cloud Applications.

IMPORTANT: scripts are developed for the latest Adobe Creative Cloud applications. Many scripts work in CC 2018 and later, even some as far back as CS6, but may not perform as expected, or run at all, when used in versions prior to 2018. Photoshop features Select Subject and Preserve Details 2.0 definitely fail prior to CC 2018 (version 19) as the features do not exist in earlier versions. For best results use the latest versions of Adobe Creative Cloud applications.

IMPORTANT: by downloading any of the scripts on this page you agree that the software is provided without any warranty, express or implied. USE AT YOUR OWN RISK. Always make backups of important data.

IMPORTANT: fees paid for software products are the purchase of a non-exclusive license to use the software product and do not grant the purchaser any degree of ownership of the software code. Author of the intellectual property and copyright holder William Campbell retains 100% ownership of all code used in all software products regardless of the inspiration for the software product design or functionality.