1

I am using a variant of the script on this Question to batch Photomerge a bunch of panoramic photo sets in different subfolders. However, the way I have my folder directories set up, the script can only process photos in one sub-directory at a time before requiring user input. For the working directory, see the image below.

directory

Each of these folders has further sub-folders called "pano01", "pano02" and so on, as shown below.

subfolders

What I would like to do is point the batch script at folder "process" and have it run Photomerge on any subfolder, regardless of how far down the directory, beginning with name "pano."

Here's the script:

// https://graphicdesign.stackexchange.com/questions/125106/multiple-panorama-automation-in-photoshop
var runphotomergeFromScript = true; // must be before Photomerge include
//@includepath "/C/Program Files/Adobe/Adobe Photoshop CS6 (64 Bit)/Presets/Scripts/"
//@include "Photomerge.jsx"
//@show include

var psdOpts = new PhotoshopSaveOptions();
psdOpts.embedColorProfile = true;
psdOpts.alphaChannels = true;
psdOpts.layers = true;

(function()
{
    var workFolder = Folder.selectDialog();
    if (workFolder == null) return false;

    var folders = workFolder.getFiles(function(file)
    {
        return file instanceof Folder;
    });

    if (folders.length == 0) return false

    for (var i = 0; i < folders.length; i++)
    {

        var fList = folders[i].getFiles('*.CR2');

        // override Photomerge.jsx settings. Default is "Auto". Uncomment to override the default.
        //photomerge.alignmentKey = "Auto";
        //photomerge.alignmentKey   = "Prsp";
        //photomerge.alignmentKey   = "cylindrical";
        //photomerge.alignmentKey   = "spherical";
        //photomerge.alignmentKey   = "sceneCollage";
        photomerge.alignmentKey = "translation"; // "Reposition" in layout dialog   

        // other setting that may need to be changed. Defaults below
        photomerge.advancedBlending = true; // 'Blend Images Together' checkbox in dialog
        photomerge.lensCorrection = true; // Geometric Distortion Correction'checkbox in dialog
        photomerge.removeVignette = true; // 'Vignette Removal' checkbox in dialog

        try
        {
            if (fList.length > 1)
            {
                photomerge.createPanorama(fList, false);
            }
        }
        catch (e)
        {
            alert(e + '\nLine: ' + e.line)
        }

        // https://stackoverflow.com/questions/45771379/how-can-i-merge-visible-to-a-layer-in-a-photoshop-script
        activeDocument.mergeVisibleLayers();
        activeDocument.activeLayer.autoContrast(); // Apply contrast

        // saving
        var saveFile = {
            name: folders[i].name,
            path: fList[0].parent
        }

        savePSD(saveFile)
        saveJPG(saveFile)

        activeDocument.close(SaveOptions.DONOTSAVECHANGES);
    }
})()

function saveJPG(data)
{
    if (data.path == undefined) return false;
    data.name = data.name == undefined ? activeDocument.name : data.name;
    data.quality == undefined && data.quality = 75

    //https://stackoverflow.com/questions/17580923/photoshop-javascript-to-resize-image-and-canvas-to-specific-not-square-sizes
    // these are our values for the END RESULT width and height (in pixels) of our image
    doc = app.activeDocument;      
    var fWidth = 1500;
    doc.resizeImage(UnitValue(fWidth,"px"),null,null,ResampleMethod.BICUBIC);

    var options = new ExportOptionsSaveForWeb(),
    jpgFile = new File(data.path + '/' + data.name + '.jpg');
    options.format = SaveDocumentType.JPEG;
    options.quality = data.quality;
    activeDocument.exportDocument(jpgFile, ExportType.SAVEFORWEB, options);

}

function savePSD(data)
{
    var desc = new ActionDescriptor();
    var descOptions = new ActionDescriptor();
    descOptions.putBoolean(stringIDToTypeID('maximizeCompatibility'), true);
    desc.putObject(charIDToTypeID('As  '), charIDToTypeID('Pht3'), descOptions);
    desc.putPath(charIDToTypeID('In  '), new File(data.path + "/" + data.name + ".psd"));
    executeAction(charIDToTypeID('save'), desc, DialogModes.NO);
} // end of savePSD()

1 Answer 1

2

Here's a modified version of that script. I changed the way folders are got: made a function that gets all subfolders with a specific mask instead (line 18).

// https://graphicdesign.stackexchange.com/questions/125106/multiple-panorama-automation-in-photoshop
// https://graphicdesign.stackexchange.com/questions/129569/batch-photomerge-only-process-images-in-folder-with-specific-title
var runphotomergeFromScript = true; // must be before Photomerge include
//@includepath "/C/Program Files/Adobe/Adobe Photoshop CS6 (64 Bit)/Presets/Scripts/"
//@include "Photomerge.jsx"
//@show include

var psdOpts = new PhotoshopSaveOptions();
psdOpts.embedColorProfile = true;
psdOpts.alphaChannels = true;
psdOpts.layers = true;

(function()
{
    var workFolder = Folder.selectDialog();
    if (workFolder == null) return false;

    var folders = getSubfolders(workFolder, 'pano');

    if (folders.length == 0) return false

    for (var i = 0; i < folders.length; i++)
    {

        var fList = folders[i].getFiles('*.CR2');
        if (fList.length == 0) continue;

        // override Photomerge.jsx settings. Default is "Auto". Uncomment to override the default.
        //photomerge.alignmentKey = "Auto";
        //photomerge.alignmentKey   = "Prsp";
        //photomerge.alignmentKey   = "cylindrical";
        //photomerge.alignmentKey   = "spherical";
        //photomerge.alignmentKey   = "sceneCollage";
        photomerge.alignmentKey = "translation"; // "Reposition" in layout dialog   

        // other setting that may need to be changed. Defaults below
        photomerge.advancedBlending = true; // 'Blend Images Together' checkbox in dialog
        photomerge.lensCorrection = true; // Geometric Distortion Correction'checkbox in dialog
        photomerge.removeVignette = true; // 'Vignette Removal' checkbox in dialog

        try
        {
            if (fList.length > 1)
            {
                photomerge.createPanorama(fList, false);
            }
        }
        catch (e)
        {
            alert(e + '\nLine: ' + e.line)
        }

        // https://stackoverflow.com/questions/45771379/how-can-i-merge-visible-to-a-layer-in-a-photoshop-script
        activeDocument.mergeVisibleLayers();
        activeDocument.activeLayer.autoContrast(); // Apply contrast

        // saving
        var saveFile = {
            name: folders[i].name,
            path: fList[0].parent
        }

        savePSD(saveFile)
        saveJPG(saveFile)

        activeDocument.close(SaveOptions.DONOTSAVECHANGES);
    }
})()

function saveJPG(data)
{
    if (data.path == undefined) return false;
    data.name = data.name == undefined ? activeDocument.name : data.name;
    data.quality == undefined && data.quality = 75

    //https://stackoverflow.com/questions/17580923/photoshop-javascript-to-resize-image-and-canvas-to-specific-not-square-sizes
    // these are our values for the END RESULT width and height (in pixels) of our image
    doc = app.activeDocument;      
    var fWidth = 1500;
    doc.resizeImage(UnitValue(fWidth,"px"),null,null,ResampleMethod.BICUBIC);

    var options = new ExportOptionsSaveForWeb(),
    jpgFile = new File(data.path + '/' + data.name + '.jpg');
    options.format = SaveDocumentType.JPEG;
    options.quality = data.quality;
    activeDocument.exportDocument(jpgFile, ExportType.SAVEFORWEB, options);

}

function savePSD(data)
{
    var desc = new ActionDescriptor();
    var descOptions = new ActionDescriptor();
    descOptions.putBoolean(stringIDToTypeID('maximizeCompatibility'), true);
    desc.putObject(charIDToTypeID('As  '), charIDToTypeID('Pht3'), descOptions);
    desc.putPath(charIDToTypeID('In  '), new File(data.path + "/" + data.name + ".psd"));
    executeAction(charIDToTypeID('save'), desc, DialogModes.NO);
} // end of savePSD()

function getSubfolders(folder, mask)
{ // folder object, RegExp or string  
    if (mask == undefined) mask = "";
    var sFolders = [];
    var targetFolders = [];
    sFolders[0] = folder;
    for (var j = 0; j < sFolders.length; j++)
    {
        var procFiles = sFolders[j].getFiles();
        for (var i = 0; i < procFiles.length; i++)
        {
            if (procFiles[i] instanceof Folder)
            {
                if (procFiles[i].fullName.search(mask) != -1) targetFolders.push(procFiles[i]);
                sFolders.push(procFiles[i]);
                getSubfolders(procFiles[i], mask);
            }
        }
    }
    return targetFolders
} // end of getSubfolders()
2
  • This is great, thanks! Is there a way to have it skip a "pano" folder if no .CR2 files are detected in the folder?
    – grfrazee
    Sep 15, 2019 at 16:23
  • 1
    sure, I updated my answer: if fList is empty the folder will be ignored. Sep 15, 2019 at 19:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.