Skip to main content
Known Participant
July 16, 2024
Answered

bulk action solution needed

  • July 16, 2024
  • 4 replies
  • 4002 views

Does anyone know a way to bulk stack pairs of photos (raw and edited jpeg) so they can be auto aligned and then blended via opacity change in one? Prefer adobe based platform but don't think it's possible.

Was ideally looking at doing this from LR to PS, but honestly don't care how it's done. Pretty simple but only know how to do this for one pair of photos at a time. 

 

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

@jonathanb67250519 

 

You can try this first draft script. It's mostly there and should only require cosmetic tweaking, such as removing the manual save folder selection step if you want to save the merged files to the TIFF input folder or automatically create a new merged output folder alongside or within the TIFF input folder.

 

Notes:

* Saves a layered TIFF file, change the boolean from true to false to save a flattened TIFF file  [line 71]

* Layer opacity at 40%  [line 108]

* Optional feature to crop to transparency, remove the leading double-forward slash // comments to enable  [line 111]

* Adds a '_Merged' filename suffix to the saved TIFF file, you could change this name or remove the content inside the single quotes ''  [line 112]

 

I'm happy to make other modifications if required.

 

/*
Stack and Blend 2 Input Folder Files to TIFF.jsx
v1.0, 17th July 2024 - Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/bulk-action-solution-needed/td-p/14741490
*/

#target photoshop

    (function () {

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

            try {

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

                // TIFF Input folder
                var folder2 = Folder.selectDialog("Select the TIFF image 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
                var list1 = folder1.getFiles(/\.(jpg|jpeg)$/i);
                var list2 = folder2.getFiles(/\.(tif|tiff)$/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...");

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

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

                // 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 processing counter
                var counter = 0;

                // Perform the stacking and saving
                for (var i = 0; i < list1.length; i++) {
                    var doc = open(list1[i]);
                    var docName = doc.name.replace(/\.[^\.]+$/, '');
                    placeFile(list2[i], 100);
                    resetTransforms();
                    app.runMenuItem(stringIDToTypeID('rasterizePlaced'));
                    app.activeDocument.activeLayer.opacity = 40; // Layer opacity
                    selectAllLayers();
                    autoAlign();
                    cropTransparency(); // Optional crop
                    app.activeDocument.saveAs(new File(saveFolder + '/' + docName + '_Merged' + '.tif'), tiffSaveOptions);
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                    counter++; // Increment the counter
                }

                // Ensure Photoshop has focus before closing the running script notification window
                app.bringToFront();
                working.close();

                // End of script notification
                app.displayDialogs = savedDisplayDialogs;
                app.beep();
                alert('Script completed!' + '\r' + counter + ' merged TIFF files saved to:' + '\r' + saveFolder.fsName);

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

            } catch (err) {
                while (app.documents.length > 0) {
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                }
                alert("Error!" + "\r" + err + ' ' + err.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 resetTransforms() {
            try {
                var idplacedLayerResetTransforms = stringIDToTypeID("placedLayerResetTransforms");
                executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);
            } catch (e) {
                //alert("Error!" + "\r" + e + ' ' + e.line); // Errors in 2019 version
                app.refresh();
            }
        }

        function selectAllLayers() {
            try {
                var c2t = function (s) {
                    return app.charIDToTypeID(s);
                };
                var s2t = function (s) {
                    return app.stringIDToTypeID(s);
                };
                var descriptor = new ActionDescriptor();
                var descriptor2 = new ActionDescriptor();
                var reference = new ActionReference();
                var reference2 = new ActionReference();
                reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
                descriptor.putReference(c2t("null"), reference2);
                executeAction(s2t("selectAllLayers"), descriptor, DialogModes.NO);
                // Add the Background layer if it exists
                reference.putProperty(s2t("layer"), s2t("background"));
                descriptor2.putReference(c2t("null"), reference);
                descriptor2.putEnumerated(s2t("selectionModifier"), s2t("selectionModifierType"), s2t("addToSelection"));
                descriptor2.putBoolean(s2t("makeVisible"), false);
                executeAction(s2t("select"), descriptor2, DialogModes.NO);
            } catch (e) {
                alert("Error!" + "\r" + e + ' ' + e.line);
            }
        }

        function autoAlign() {
            try {
                var desc = new ActionDescriptor();
                var ref = new ActionReference();
                ref.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
                desc.putReference(charIDToTypeID('null'), ref);
                desc.putEnumerated(charIDToTypeID('Usng'), charIDToTypeID('ADSt'), stringIDToTypeID('ADSContent'));
                desc.putEnumerated(charIDToTypeID('Aply'), stringIDToTypeID('projection'), charIDToTypeID('Auto'));
                desc.putBoolean(stringIDToTypeID('vignette'), false);
                desc.putBoolean(stringIDToTypeID('radialDistort'), false);
                executeAction(charIDToTypeID('Algn'), desc, DialogModes.NO);
            } catch (e) {
                alert("Error!" + "\r" + e + ' ' + e.line);
            }
        }

        function cropTransparency() {
            try {
                var s2t = function (s) {
                    return app.stringIDToTypeID(s);
                };
                var descriptor = new ActionDescriptor();
                var descriptor2 = new ActionDescriptor();
                var descriptor3 = new ActionDescriptor();
                var descriptor4 = new ActionDescriptor();
                var descriptor5 = new ActionDescriptor();
                var descriptor6 = new ActionDescriptor();
                var reference = new ActionReference();
                var reference2 = new ActionReference();
                var reference3 = new ActionReference();
                var reference4 = new ActionReference();
                // Dupe layers to temp merged layer
                descriptor.putBoolean(s2t("duplicate"), true);
                executeAction(s2t("mergeLayersNew"), descriptor, DialogModes.NO);
                // Load selection from layer transparency
                reference.putProperty(s2t("channel"), s2t("selection"));
                descriptor2.putReference(s2t("null"), reference);
                reference2.putEnumerated(s2t("channel"), s2t("channel"), s2t("transparencyEnum"));
                descriptor2.putReference(s2t("to"), reference2);
                executeAction(s2t("set"), descriptor2, DialogModes.NO);
                // Enter quick mask mode
                reference3.putProperty(s2t("property"), s2t("quickMask"));
                reference3.putEnumerated(s2t("document"), s2t("ordinal"), s2t("targetEnum"));
                descriptor3.putReference(s2t("null"), reference3);
                // Threshold to 255 levels
                executeAction(s2t("set"), descriptor3, DialogModes.NO);
                descriptor4.putInteger(s2t("level"), 255);
                executeAction(s2t("thresholdClassEvent"), descriptor4, DialogModes.NO);
                // Exit quick mask mode
                reference4.putProperty(s2t("property"), s2t("quickMask"));
                reference4.putEnumerated(s2t("document"), s2t("ordinal"), s2t("targetEnum"));
                descriptor5.putReference(s2t("null"), reference4);
                // Crop selection
                executeAction(s2t("clearEvent"), descriptor5, DialogModes.NO);
                descriptor6.putBoolean(s2t("delete"), true);
                executeAction(s2t("crop"), descriptor6, DialogModes.NO);
                // Clean up
                app.activeDocument.activeLayer.remove();
                app.activeDocument.selection.deselect();
            } catch (e) {
                alert("Error!" + "\r" + e + ' ' + e.line);
            }
        }

    }());

 

Instructions for saving and use:

 

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

 

4 replies

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
July 16, 2024

@jonathanb67250519 

 

You can try this first draft script. It's mostly there and should only require cosmetic tweaking, such as removing the manual save folder selection step if you want to save the merged files to the TIFF input folder or automatically create a new merged output folder alongside or within the TIFF input folder.

 

Notes:

* Saves a layered TIFF file, change the boolean from true to false to save a flattened TIFF file  [line 71]

* Layer opacity at 40%  [line 108]

* Optional feature to crop to transparency, remove the leading double-forward slash // comments to enable  [line 111]

* Adds a '_Merged' filename suffix to the saved TIFF file, you could change this name or remove the content inside the single quotes ''  [line 112]

 

I'm happy to make other modifications if required.

 

/*
Stack and Blend 2 Input Folder Files to TIFF.jsx
v1.0, 17th July 2024 - Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/bulk-action-solution-needed/td-p/14741490
*/

#target photoshop

    (function () {

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

            try {

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

                // TIFF Input folder
                var folder2 = Folder.selectDialog("Select the TIFF image 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
                var list1 = folder1.getFiles(/\.(jpg|jpeg)$/i);
                var list2 = folder2.getFiles(/\.(tif|tiff)$/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...");

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

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

                // 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 processing counter
                var counter = 0;

                // Perform the stacking and saving
                for (var i = 0; i < list1.length; i++) {
                    var doc = open(list1[i]);
                    var docName = doc.name.replace(/\.[^\.]+$/, '');
                    placeFile(list2[i], 100);
                    resetTransforms();
                    app.runMenuItem(stringIDToTypeID('rasterizePlaced'));
                    app.activeDocument.activeLayer.opacity = 40; // Layer opacity
                    selectAllLayers();
                    autoAlign();
                    cropTransparency(); // Optional crop
                    app.activeDocument.saveAs(new File(saveFolder + '/' + docName + '_Merged' + '.tif'), tiffSaveOptions);
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                    counter++; // Increment the counter
                }

                // Ensure Photoshop has focus before closing the running script notification window
                app.bringToFront();
                working.close();

                // End of script notification
                app.displayDialogs = savedDisplayDialogs;
                app.beep();
                alert('Script completed!' + '\r' + counter + ' merged TIFF files saved to:' + '\r' + saveFolder.fsName);

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

            } catch (err) {
                while (app.documents.length > 0) {
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                }
                alert("Error!" + "\r" + err + ' ' + err.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 resetTransforms() {
            try {
                var idplacedLayerResetTransforms = stringIDToTypeID("placedLayerResetTransforms");
                executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);
            } catch (e) {
                //alert("Error!" + "\r" + e + ' ' + e.line); // Errors in 2019 version
                app.refresh();
            }
        }

        function selectAllLayers() {
            try {
                var c2t = function (s) {
                    return app.charIDToTypeID(s);
                };
                var s2t = function (s) {
                    return app.stringIDToTypeID(s);
                };
                var descriptor = new ActionDescriptor();
                var descriptor2 = new ActionDescriptor();
                var reference = new ActionReference();
                var reference2 = new ActionReference();
                reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
                descriptor.putReference(c2t("null"), reference2);
                executeAction(s2t("selectAllLayers"), descriptor, DialogModes.NO);
                // Add the Background layer if it exists
                reference.putProperty(s2t("layer"), s2t("background"));
                descriptor2.putReference(c2t("null"), reference);
                descriptor2.putEnumerated(s2t("selectionModifier"), s2t("selectionModifierType"), s2t("addToSelection"));
                descriptor2.putBoolean(s2t("makeVisible"), false);
                executeAction(s2t("select"), descriptor2, DialogModes.NO);
            } catch (e) {
                alert("Error!" + "\r" + e + ' ' + e.line);
            }
        }

        function autoAlign() {
            try {
                var desc = new ActionDescriptor();
                var ref = new ActionReference();
                ref.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
                desc.putReference(charIDToTypeID('null'), ref);
                desc.putEnumerated(charIDToTypeID('Usng'), charIDToTypeID('ADSt'), stringIDToTypeID('ADSContent'));
                desc.putEnumerated(charIDToTypeID('Aply'), stringIDToTypeID('projection'), charIDToTypeID('Auto'));
                desc.putBoolean(stringIDToTypeID('vignette'), false);
                desc.putBoolean(stringIDToTypeID('radialDistort'), false);
                executeAction(charIDToTypeID('Algn'), desc, DialogModes.NO);
            } catch (e) {
                alert("Error!" + "\r" + e + ' ' + e.line);
            }
        }

        function cropTransparency() {
            try {
                var s2t = function (s) {
                    return app.stringIDToTypeID(s);
                };
                var descriptor = new ActionDescriptor();
                var descriptor2 = new ActionDescriptor();
                var descriptor3 = new ActionDescriptor();
                var descriptor4 = new ActionDescriptor();
                var descriptor5 = new ActionDescriptor();
                var descriptor6 = new ActionDescriptor();
                var reference = new ActionReference();
                var reference2 = new ActionReference();
                var reference3 = new ActionReference();
                var reference4 = new ActionReference();
                // Dupe layers to temp merged layer
                descriptor.putBoolean(s2t("duplicate"), true);
                executeAction(s2t("mergeLayersNew"), descriptor, DialogModes.NO);
                // Load selection from layer transparency
                reference.putProperty(s2t("channel"), s2t("selection"));
                descriptor2.putReference(s2t("null"), reference);
                reference2.putEnumerated(s2t("channel"), s2t("channel"), s2t("transparencyEnum"));
                descriptor2.putReference(s2t("to"), reference2);
                executeAction(s2t("set"), descriptor2, DialogModes.NO);
                // Enter quick mask mode
                reference3.putProperty(s2t("property"), s2t("quickMask"));
                reference3.putEnumerated(s2t("document"), s2t("ordinal"), s2t("targetEnum"));
                descriptor3.putReference(s2t("null"), reference3);
                // Threshold to 255 levels
                executeAction(s2t("set"), descriptor3, DialogModes.NO);
                descriptor4.putInteger(s2t("level"), 255);
                executeAction(s2t("thresholdClassEvent"), descriptor4, DialogModes.NO);
                // Exit quick mask mode
                reference4.putProperty(s2t("property"), s2t("quickMask"));
                reference4.putEnumerated(s2t("document"), s2t("ordinal"), s2t("targetEnum"));
                descriptor5.putReference(s2t("null"), reference4);
                // Crop selection
                executeAction(s2t("clearEvent"), descriptor5, DialogModes.NO);
                descriptor6.putBoolean(s2t("delete"), true);
                executeAction(s2t("crop"), descriptor6, DialogModes.NO);
                // Clean up
                app.activeDocument.activeLayer.remove();
                app.activeDocument.selection.deselect();
            } catch (e) {
                alert("Error!" + "\r" + e + ' ' + e.line);
            }
        }

    }());

 

Instructions for saving and use:

 

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

 

Known Participant
July 17, 2024

It works! I never knew an automated process like this was possible, it's a huge time saver. Thank you very much! Now that I know this is possible, will try to think of additional ways to streamline my editing process. 

Legend
July 24, 2024

It is difficult to trouble shoot, when I manually blend step by step or via my action it blends fine. I haven't tried to repeat the script on the handful of images that were blurry, to see if I reran the script if it would work on a second run. Need to try that. As long as the script auto aligns on the auto option it should be identical to my action. 

If anyone has a suggestion to easily blend in the ambient light/shadows/etc to an edited photo I'm open to suggestions. There is a movement back to a more naturalistic look for real estate photography so editors are starting to blend in more ambient light into their edits. That said, the ultra rendered look is still most popular and the naturalistic blend is going for nearly twice the cost. Calculate 1000s of photos a year and that adds up. Hence, my automated blend to keep costs down.

 


I'll admit to being completely lost as to your workflow. The WHOLE REASON to retouch photos is to get the look you want. I would never ever ever finish a photo and then blend it with an unedited copy. I've never heard of anyone doing this, ever.

Legend
July 16, 2024

Why not just use an HDR feature for blending? And I don't get why you would blend an edited and unedited shot.

I just use adjustment layers with masking and am able to get pretty much any effect. Its rare that I blend multiple exposures unless I'm doing a panorama.

Stephen Marsh
Community Expert
Community Expert
July 16, 2024

@jonathanb67250519 

 

I have a couple of generic batch scripts posted here:

 

 
The scripts are designed to fast-track the development of custom scripts, as they perform the basic processing. These versions don't auto-align, they expect that the files are the same size and that the content is aligned. The script assumes alphabetically sorting file pairs from a single folder or top-level folder + sub-folders. It's also possible to select 2 different source folders. It's hard to make a generic script cover all workflows, however, I am happy to change things as needed if you can't adapt your workflow to the script.
 
You will first need to use Lr or ACR to batch render the raw files to an appropriate format such as TIFF or PSD.
 
The script can call an action, so if you find it easier to do the processing of the two stacked layers via an action then you don't need to know how to script those steps.
 
I did look at auto-align in this script:
 
 
c.pfaffenbichler
Community Expert
Community Expert
July 16, 2024

I wonder, though, to what end one would need to align the RAW and the jpg – which makes me wonder whether I understood the OP’s intended process. 

Known Participant
July 16, 2024

I shoot in raw, multiple brackets. Want to blend in the base ambient bracket (can be saved as a different file with a basic preset) into an edit from outsourcing. Helps with producing a consistent product, with natural ambient light/shadows/etc  to an otherwise commonly produced and over rendered style. Cost and time is major players in why this would be needed

 

c.pfaffenbichler
Community Expert
Community Expert
July 16, 2024

Please provide sample images or at least meaningful screenshots to illustrate the process, the imagery, the file structure and the naming convention. 

 

It sounds like a case for Photoshop Scripting; several Scripts have been posted about combining X images.