Copy link to clipboard
Copied
Hi,
I have a night timelapse consisting of single images where the foreground is very noisy. What I want to do is open three images, create a smartobject and then use the stackmode median to reduce noise. Then photoshop should move foreward one image and yet again open three images. Is there a way to automate this using actions and the batch editing? I didn't find a way to open more than one image automatically...
Thanks for your help!
Jakob
Try this script. It will pull the files from a folder on your desktop called "source," but you can change the folder by editing the path in the code. It will save to a subfolder, called done, in the same folder. It will append the files with "median" so files don't get over written. It will also save the files as jpgs, and only open jpgs. You can change the file type by changing the extension in the line:
var mask = '*.jpg'
#target photoshop
var srcFolder = new Folder('~/desktop/source/');
vaAs suggested by Chuck, here is the modified script for mean blending:
/* 
https://community.adobe.com/t5/photoshop/batch-median-noise-reduction/m-p/10758011?page=1#M285346
Batch Median Noise Reduction
*/
#target photoshop
var srcFolder = new Folder('~/desktop/source/');
var doneFolder = new Folder(srcFolder + '/done/');
if (!doneFolder.exists) {
    doneFolder.create()
};
var jpgOptions = new JPEGSaveOptions();
jpgOptions.quality = 8
var mask = '*.jpg'
var fList = srcFolder.getFiles(mask);Copy link to clipboard
Copied
Did you shoot three shots for each frame, or are you wanting to combing the two frames before and after the selected frame?
Copy link to clipboard
Copied
Yes, I want to combine them with the one before and after the selected frame
Copy link to clipboard
Copied
"I didn't find a way to open more than one image automatically..."
File > Scripts > Load Files into Stack command can open multiple files and position them one above another in the Layers panel if I understand what you want to ask.
Copy link to clipboard
Copied
Yes, that's what I want, but automated. So Photoshop should open file 1, 2 and 3 then create a Smartobject with these three layers, use stack mode median and save the image. Then I want to open files 2, 3 and 4 and do the same, then 3, 4 and 5 and so on... I have about 350 frames so it would take ages if I had to do it manually... I'm sorry if my explanation is a bit hard to understand, but English isn't my first language.
Copy link to clipboard
Copied
Try this script. It will pull the files from a folder on your desktop called "source," but you can change the folder by editing the path in the code. It will save to a subfolder, called done, in the same folder. It will append the files with "median" so files don't get over written. It will also save the files as jpgs, and only open jpgs. You can change the file type by changing the extension in the line:
var mask = '*.jpg'
#target photoshop
var srcFolder = new Folder('~/desktop/source/');
var doneFolder = new Folder(srcFolder + '/done/');
if(!doneFolder.exists){doneFolder.create()};
var jpgOptions = new JPEGSaveOptions();
jpgOptions.quality = 8
var mask = '*.jpg'
var fList = srcFolder.getFiles (mask);
for(var i=0;i<fList.length;i++){
    try{
        open(fList[i])
        }
    catch(e){};
    try{
        open(fList[i -1])
        }
    catch(e){};
    try{
        open(fList[i +1])
        }
    catch(e){};
    
    var base = activeDocument = app.documents[0];
    base.flatten();
    base.layers[0].isBackgroundLayer = false;
    var docNum = app.documents.length;
    for(var j=1;j<docNum;j++){
        var nextDoc = activeDocument = app.documents[1];
        nextDoc.flatten();
        nextDoc.activeLayer.duplicate (base.layers[0], ElementPlacement.PLACEBEFORE);
        nextDoc.close(SaveOptions.DONOTSAVECHANGES);
        }
    
    base.layers[base.layers.length -1].isBackgroundLayer = false;
    selectAllLayers ();
    makeSO ();
    makeMedian ();
    base.flatten();
    var fName = base.name.split('.')[0];
    base.saveAs (new File(doneFolder + '/Median-' + fName + '.jpg'), jpgOptions);
    base.close(SaveOptions.DONOTSAVECHANGES);
    };//end loop
function selectAllLayers(){
    var idselectAllLayers = stringIDToTypeID( "selectAllLayers" );
        var desc3 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idLyr = charIDToTypeID( "Lyr " );
            var idOrdn = charIDToTypeID( "Ordn" );
            var idTrgt = charIDToTypeID( "Trgt" );
            ref1.putEnumerated( idLyr, idOrdn, idTrgt );
        desc3.putReference( idnull, ref1 );
    executeAction( idselectAllLayers, desc3, DialogModes.NO );
    }
function makeSO(){
    var idnewPlacedLayer = stringIDToTypeID( "newPlacedLayer" );
    executeAction( idnewPlacedLayer, undefined, DialogModes.NO );    
    }
function makeMedian(){
    var idapplyImageStackPluginRenderer = stringIDToTypeID( "applyImageStackPluginRenderer" );
        var desc6 = new ActionDescriptor();
        var idimageStackPlugin = stringIDToTypeID( "imageStackPlugin" );
        var idmedn = charIDToTypeID( "medn" );
        desc6.putClass( idimageStackPlugin, idmedn );
        var idNm = charIDToTypeID( "Nm  " );
        desc6.putString( idNm, """Median""" );
    executeAction( idapplyImageStackPluginRenderer, desc6, DialogModes.NO );    
    }
Copy link to clipboard
Copied
Wow, thank you so much! It works perfectly.
Copy link to clipboard
Copied
So, I'm curious how the end video looked by combining the layers in this way? No odd artifacts from ghosting images?
Copy link to clipboard
Copied
Sorry for the late reply... So I didn't apply this technique to the shot I intended to, but I used it for the shot at 0:14 https://youtu.be/Nqcr3E8KZHE
Most of the planes are gone, just one looking a bit odd and I added a satellite back in with After Effects. I did however change your script to work with tif files and I stacked 5 images. I think it looks awesome and I would use this technique again.
Copy link to clipboard
Copied
Very nice!
Copy link to clipboard
Copied
Thanks again, you definitely saved that shot with your script, it was so noisy before that I wouldn't have included it in the final video.
Copy link to clipboard
Copied
Hi Chuck,
I'd like to change the script to use stackmode mean instead of median, what do I have to change? I tried changing a few of the settings but I only got errors in photoshop...
Thanks!
Copy link to clipboard
Copied
It would be best to use scriptListener and record stacking the images using mean, then replace the code for median, in the last function in the above script.
Copy link to clipboard
Copied
As suggested by Chuck, here is the modified script for mean blending:
/* 
https://community.adobe.com/t5/photoshop/batch-median-noise-reduction/m-p/10758011?page=1#M285346
Batch Median Noise Reduction
*/
#target photoshop
var srcFolder = new Folder('~/desktop/source/');
var doneFolder = new Folder(srcFolder + '/done/');
if (!doneFolder.exists) {
    doneFolder.create()
};
var jpgOptions = new JPEGSaveOptions();
jpgOptions.quality = 8
var mask = '*.jpg'
var fList = srcFolder.getFiles(mask);
for (var i = 0; i < fList.length; i++) {
    try {
        open(fList[i])
    } catch (e) { };
    try {
        open(fList[i - 1])
    } catch (e) { };
    try {
        open(fList[i + 1])
    } catch (e) { };
    var base = activeDocument = app.documents[0];
    base.flatten();
    base.layers[0].isBackgroundLayer = false;
    var docNum = app.documents.length;
    for (var j = 1; j < docNum; j++) {
        var nextDoc = activeDocument = app.documents[1];
        nextDoc.flatten();
        nextDoc.activeLayer.duplicate(base.layers[0], ElementPlacement.PLACEBEFORE);
        nextDoc.close(SaveOptions.DONOTSAVECHANGES);
    }
    base.layers[base.layers.length - 1].isBackgroundLayer = false;
    selectAllLayers();
    makeSO();
    makeMean();
    base.flatten();
    var fName = base.name.split('.')[0];
    base.saveAs(new File(doneFolder + '/Median-' + fName + '.jpg'), jpgOptions);
    base.close(SaveOptions.DONOTSAVECHANGES);
}; //end loop
function selectAllLayers() {
    var idselectAllLayers = stringIDToTypeID("selectAllLayers");
    var desc3 = new ActionDescriptor();
    var idnull = charIDToTypeID("null");
    var ref1 = new ActionReference();
    var idLyr = charIDToTypeID("Lyr ");
    var idOrdn = charIDToTypeID("Ordn");
    var idTrgt = charIDToTypeID("Trgt");
    ref1.putEnumerated(idLyr, idOrdn, idTrgt);
    desc3.putReference(idnull, ref1);
    executeAction(idselectAllLayers, desc3, DialogModes.NO);
}
function makeSO() {
    var idnewPlacedLayer = stringIDToTypeID("newPlacedLayer");
    executeAction(idnewPlacedLayer, undefined, DialogModes.NO);
}
function makeMean() {
    var idapplyImageStackPluginRenderer = stringIDToTypeID("applyImageStackPluginRenderer");
    var desc252 = new ActionDescriptor();
    var idimageStackPlugin = stringIDToTypeID("imageStackPlugin");
    var idavrg = charIDToTypeID("avrg");
    desc252.putClass(idimageStackPlugin, idavrg);
    var idNm = charIDToTypeID("Nm  ");
    desc252.putString(idNm, """Mean""");
    executeAction(idapplyImageStackPluginRenderer, desc252, DialogModes.NO);
}
Copy link to clipboard
Copied
Thanks guys! I tried "mean" as the charID, but that didn't work, "avrg" it is 😄
Copy link to clipboard
Copied
Hi,
I am new here. I was looking for a simmilar script in google and found this.
I would like to open 4 16 bit TIFF files at the time, do median and save as 16 bit TIFF (no layers); then move to the next 4 files until done.
Can someone please edit this script to do so?
Thanks in advance
Copy link to clipboard
Copied
Are the input files flattened Background images, or do they only contain a single layer?
EDIT: Don't worry, I have made sure that both will produce the same result.
Copy link to clipboard
Copied
Try the following code and let me know how it goes. It will combine files into sets of 4 and merge into a smart object stack with median blend mode. A new directory will be created within the input folder where the files are saved. File names are based off either the 4th, 8th etc file name in each set of 4 – or it is easily modified to use the 1st, 5th name etc.
Filenames are expected to be in correct alpha/numeric sorting order.
/* 
Stack Sets of 4 Images with Median Blend.jsx
Stephen Marsh - 17th April 2021
This script is based around alpha/numeric sorting files
Batch Median Noise Reduction
https://community.adobe.com/t5/photoshop/batch-median-noise-reduction/m-p/11960956#M529922
*/
#target photoshop
if (app.documents.length === 0) {
    try {
        // Save and disable dialogs
        var restoreDialogMode = app.displayDialogs;
        app.displayDialogs = DialogModes.NO;
        batchSetProcessing();
        function batchSetProcessing() {
            // Select the input folder
            inputFolder = Folder.selectDialog('Please select the folder with files to process');
            if (inputFolder === null) return;
            // Create the output sub-directory
            var outputFolder = Folder(decodeURI(inputFolder + '/Output Sets Folder'));
            if (!outputFolder.exists) outputFolder.create();
            // Limit the file format input
            var fileList = inputFolder.getFiles(/\.(tif|tiff)$/i);
            // Force alpha-numeric list sort
            // Use .reverse() for the first filename in the merged file
            // Remove .reverse() for the last filename in the merged file
            fileList.sort().reverse();
            // Images per set
            var setQty = 4;
            // Validate the input count vs. output count
            var inputCount = fileList.length;
            // Thanks to Kukurykus for the advice to test using % modulus
            var cancelScript = !(inputCount % setQty);
            alert(inputCount + ' input files stacked into sets of ' + setQty + ' will produce ' + inputCount / setQty + ' file sets.');
            // Test if false, then terminate the script
            if (cancelScript === false) {
                alert('Script cancelled as the quantity of input files are not evenly divisible by the set quantity.');
                return;
            }
            // Loop through and open the file sets
            while (fileList.length) {
                // Sets of N files
                for (var a = 0; a < setQty; a++) {
                    try {
                        app.open(fileList.pop());
                    } catch (e) { }
                }
                processOpenImages();
            }
            // End of script notification
            var outputList = outputFolder.getFiles(/\.(tif|tiff)$/i);
            alert('Script completed!' + '\n' + outputList.length + ' combined files saved to:' + '\n' + outputFolder.fsName);
            // Restore saved dialogs
            app.displayDialogs = restoreDialogMode;
            function processOpenImages() {
                try {
                    app.activeDocument = documents[0];
                    docNameToLayerName();
                    // Combine open docs to base doc
                    while (app.documents.length) {
                        app.activeDocument = documents[1];
                        docNameToLayerName();
                        app.activeDocument.activeLayer.duplicate(documents[0]);
                        app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                    }
                    app.activeDocument.flatten();
                    function docNameToLayerName() {
                        var layerName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                        app.activeDocument.activeLayer.name = layerName;
                    }
                } catch (e) { }
                // Select all layers
                app.runMenuItem(stringIDToTypeID("selectAllLayers"));
                // Create a smart object from all selected layers
                makeSO();
                // Smart object median stack blend mode
                makeMedian();
                // Save name+suffix & save path
                var Name = app.activeDocument.name.replace(/\.[^\.]+$/, '');
                var saveFile = File(outputFolder + '/' + Name + '_MedianBlend' + '.tif');
                // Call the save function
                saveTIFF(saveFile);
                // Close all open files without saving
                while (app.documents.length) {
                    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                }
                // Functions
                function makeSO() {
                    var idnewPlacedLayer = stringIDToTypeID("newPlacedLayer");
                    executeAction(idnewPlacedLayer, undefined, DialogModes.NO);
                }
                function makeMedian() {
                    var idapplyImageStackPluginRenderer = stringIDToTypeID("applyImageStackPluginRenderer");
                    var desc6 = new ActionDescriptor();
                    var idimageStackPlugin = stringIDToTypeID("imageStackPlugin");
                    var idmedn = charIDToTypeID("medn");
                    desc6.putClass(idimageStackPlugin, idmedn);
                    var idNm = charIDToTypeID("Nm  ");
                    desc6.putString(idNm, """Median""");
                    executeAction(idapplyImageStackPluginRenderer, desc6, DialogModes.NO);
                }
                function saveTIFF(saveFile) {
                    tiffSaveOptions = new TiffSaveOptions();
                    tiffSaveOptions.embedColorProfile = true;
                    tiffSaveOptions.byteOrder = ByteOrder.IBM;
                    tiffSaveOptions.transparency = true;
                    // Change .layers to true to preserve layers
                    tiffSaveOptions.layers = false;
                    tiffSaveOptions.layerCompression = LayerCompression.ZIP;
                    tiffSaveOptions.interleaveChannels = true;
                    tiffSaveOptions.alphaChannels = true;
                    tiffSaveOptions.annotations = true;
                    tiffSaveOptions.spotColors = true;
                    tiffSaveOptions.saveImagePyramid = false;
                    // Image compression = NONE | JPEG | TIFFLZW | TIFFZIP
                    tiffSaveOptions.imageCompression = TIFFEncoding.TIFFLZW;
                    // Save as
                    app.activeDocument.saveAs(saveFile, tiffSaveOptions, true, Extension.LOWERCASE);
                }
            }
        }
    } catch (e) {
        // Restore saved dialogs
        app.displayDialogs = restoreDialogMode;
    }
} else {
    alert('Please close all open documents before running this script!');
}
Copy link to clipboard
Copied
Thank you so much!! I will try it tomorrow and let you know
I want to use it macro shots with focus stacking, hopping to get lower noise/better DR as noise is treated by stacking software as detail. Kind of pseudo high resolution mode some modern cameras have.
Copy link to clipboard
Copied
I may sound dumb but how I convert this text to a script file photoshop recognizes? I have not used this feature before..
Copy link to clipboard
Copied
That's pretty easy, just save the file as a .js or .jsx file. I hope it works!
Jakob
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hi,
Thanks for the extra tips, it was easy and it runs and saves the files.
Unfortunately it does not work well, is not doing the median thing (maybe there is some error on the script?). When the TIFF is saving I can see top layer blending mode is set to "Normal".
Also, do the layers aling before blending? in case there is some movent between layers, just a couple of pixels would be enough to give the output TIFF an unsharp look
Copy link to clipboard
Copied
Hi,
I double checked and even on top of a microscope the shutter shake can cause camera to move a few microns (pixels), so I would need layers to aling before median blending
Copy link to clipboard
Copied
One more thing, for the stacking software to work all images need to be same size, when aligning image size changes by few pixels. I would need to add change canvas size (not image size) to 6000x4000 pixels before saving
I am woorking at magnifications up to 100:1, this is why shutter shock can move the camera a bit
 
					
				
				
			
		
 
					
				
				
			
		
Find more inspiration, events, and resources on the new Adobe Community
Explore Now