Highlighted

Batch process groups of files based on numbering

Explorer ,
Dec 18, 2019

Copy link to clipboard

Copied

Hello,

so here is the problem:

I have set of files:

OldImage0001.jpg, OldImage0002.jpg etc. going to OldImage0252.jpg lets say (252 files)

Then I have

Mask0001.jpg, Mask0002.jpg etc. going to Mask0252.jpg

And finally

NewImage0001.jpg, NewImage0002.jpg etc. going to NewImage0252.jpg lets say (252 files)

 

How do I do this:
Open OldImage0001.jpg put over NewImage0001.jpg and mask it with Mask0001.jpg - merge everything and produce FinishedImage0001.jpg.
Then let this to be done over all 252 image groups?


Thank you.

Adobe Community Professional
Correct answer by Stephen_A_Marsh | Adobe Community Professional

Here is my take, it could be optimized and have error checking added, however it works as expected in my tests using three random sets of image sequence numbers.

 

 

 

 

/* Combine Old - New - Mask Images to JPEG.jsx

//community.adobe.com/t5/photoshop/batch-process-groups-of-files-based-on-numbering/td-p/10809093

NOTE: There is no error checking, the 3 input folders must all contain the same quantity of images! 

Input files are expected to have filenames such as: 
OldImage0001.jpg, OldImage0002.jpg etc.
Mask0001.jpg, Mask0002.jpg etc.
NewImage0001.jpg, NewImage0002.jpg etc.

Output files will be modified from the input name:
FinishedImage0001.jpg, FinishedImage0002.jpg etc.

The mask data is based off the RGB composite channel as there was no other info to go by...

It is also assumed that the old/new/mask files all have the same width/height/resolution.

*/

// Prompt for input and output folders
var oldImages = Folder.selectDialog('Select the old images folder...', '~/desktop/'); // select the old images folder
var newImages = Folder.selectDialog('Select the new images folder...', '~/desktop/'); // select the new images folder
var maskImages = Folder.selectDialog('Select the mask images folder...', '~/desktop/'); // select the mask images folder 
var outFolder = Folder.selectDialog('Select the save/output folder...', '~/desktop/'); // select the output images folder

// JPG Search Mask
var searchMask = '*.jpg';
var fileList1 = oldImages.getFiles(searchMask);
var fileList2 = newImages.getFiles(searchMask);
var fileList3 = maskImages.getFiles(searchMask);

// Force an alpha-numeric sort
fileList1.sort();
fileList2.sort();
fileList3.sort();

// JPEG Options
var jpegOptions = new JPEGSaveOptions();
jpegOptions.quality = 12; // Quality Level
jpegOptions.embedColorProfile = true; // or false
jpegOptions.formatOptions = FormatOptions.STANDARDBASELINE;
jpegOptions.matte = MatteType.NONE;

// Input Loop
for (var i = 0; i < fileList1.length; i++) {
    var doc1 = open(fileList1[i]);
    var doc2 = open(fileList2[i]);
    var doc3 = open(fileList3[i]);

    // Start - Doing stuff to open files

    var maskDoc = app.documents[2];
    var newDoc = app.documents[1];
    var oldDoc = app.documents[0];

    app.activeDocument.selection.selectAll();
    app.activeDocument.selection.copy(); // Copy the third image 'mask'
    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
    app.activeDocument = oldDoc; // Target first image 'old'
    app.activeDocument.paste();

    app.activeDocument = newDoc; // Target second image 'new'
    app.activeDocument.selection.selectAll();
    app.activeDocument.selection.copy(); // Copy the third image 'mask'
    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
    app.activeDocument = oldDoc; // Target first image 'old'
    app.activeDocument.paste();

    // Add layer mask (Clean SL)
    makeLayermask();

    function makeLayermask() {
        var c2t = function (s) {
            return app.charIDToTypeID(s);
        };
        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"), c2t("UsrM"), s2t("revealAll"));
        executeAction(s2t("make"), descriptor, DialogModes.NO);
    }

    // Apply image mask layer (Clean SL)
    applyImage(true);

    function applyImage(preserveTransparency) {
        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();
        reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("RGB"));
        reference.putName(s2t("layer"), "Layer 1");
        descriptor2.putReference(s2t("to"), reference);
        descriptor2.putBoolean(s2t("preserveTransparency"), preserveTransparency);
        descriptor.putObject(s2t("with"), c2t("Clcl"), descriptor2);
        executeAction(s2t("applyImageEvent"), descriptor, DialogModes.NO);
    }

    app.activeDocument.activeLayer = app.activeDocument.layers.getByName("Layer 1");
    app.activeDocument.activeLayer.remove();

    // Finish - Doing stuff to open files

    // Save JPEG
    var docName = app.activeDocument.name.replace(/^Old/i, '');
    app.activeDocument.flatten();
    app.activeDocument.saveAs(new File(outFolder + '/' + 'Finished' + docName.split('.')[0] + '.jpg'), jpegOptions);
    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}

alert('Script completed!');

 

 

 

 

 

 

TOPICS
Actions and scripting, How to

Views

432

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

Batch process groups of files based on numbering

Explorer ,
Dec 18, 2019

Copy link to clipboard

Copied

Hello,

so here is the problem:

I have set of files:

OldImage0001.jpg, OldImage0002.jpg etc. going to OldImage0252.jpg lets say (252 files)

Then I have

Mask0001.jpg, Mask0002.jpg etc. going to Mask0252.jpg

And finally

NewImage0001.jpg, NewImage0002.jpg etc. going to NewImage0252.jpg lets say (252 files)

 

How do I do this:
Open OldImage0001.jpg put over NewImage0001.jpg and mask it with Mask0001.jpg - merge everything and produce FinishedImage0001.jpg.
Then let this to be done over all 252 image groups?


Thank you.

Adobe Community Professional
Correct answer by Stephen_A_Marsh | Adobe Community Professional

Here is my take, it could be optimized and have error checking added, however it works as expected in my tests using three random sets of image sequence numbers.

 

 

 

 

/* Combine Old - New - Mask Images to JPEG.jsx

//community.adobe.com/t5/photoshop/batch-process-groups-of-files-based-on-numbering/td-p/10809093

NOTE: There is no error checking, the 3 input folders must all contain the same quantity of images! 

Input files are expected to have filenames such as: 
OldImage0001.jpg, OldImage0002.jpg etc.
Mask0001.jpg, Mask0002.jpg etc.
NewImage0001.jpg, NewImage0002.jpg etc.

Output files will be modified from the input name:
FinishedImage0001.jpg, FinishedImage0002.jpg etc.

The mask data is based off the RGB composite channel as there was no other info to go by...

It is also assumed that the old/new/mask files all have the same width/height/resolution.

*/

// Prompt for input and output folders
var oldImages = Folder.selectDialog('Select the old images folder...', '~/desktop/'); // select the old images folder
var newImages = Folder.selectDialog('Select the new images folder...', '~/desktop/'); // select the new images folder
var maskImages = Folder.selectDialog('Select the mask images folder...', '~/desktop/'); // select the mask images folder 
var outFolder = Folder.selectDialog('Select the save/output folder...', '~/desktop/'); // select the output images folder

// JPG Search Mask
var searchMask = '*.jpg';
var fileList1 = oldImages.getFiles(searchMask);
var fileList2 = newImages.getFiles(searchMask);
var fileList3 = maskImages.getFiles(searchMask);

// Force an alpha-numeric sort
fileList1.sort();
fileList2.sort();
fileList3.sort();

// JPEG Options
var jpegOptions = new JPEGSaveOptions();
jpegOptions.quality = 12; // Quality Level
jpegOptions.embedColorProfile = true; // or false
jpegOptions.formatOptions = FormatOptions.STANDARDBASELINE;
jpegOptions.matte = MatteType.NONE;

// Input Loop
for (var i = 0; i < fileList1.length; i++) {
    var doc1 = open(fileList1[i]);
    var doc2 = open(fileList2[i]);
    var doc3 = open(fileList3[i]);

    // Start - Doing stuff to open files

    var maskDoc = app.documents[2];
    var newDoc = app.documents[1];
    var oldDoc = app.documents[0];

    app.activeDocument.selection.selectAll();
    app.activeDocument.selection.copy(); // Copy the third image 'mask'
    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
    app.activeDocument = oldDoc; // Target first image 'old'
    app.activeDocument.paste();

    app.activeDocument = newDoc; // Target second image 'new'
    app.activeDocument.selection.selectAll();
    app.activeDocument.selection.copy(); // Copy the third image 'mask'
    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
    app.activeDocument = oldDoc; // Target first image 'old'
    app.activeDocument.paste();

    // Add layer mask (Clean SL)
    makeLayermask();

    function makeLayermask() {
        var c2t = function (s) {
            return app.charIDToTypeID(s);
        };
        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"), c2t("UsrM"), s2t("revealAll"));
        executeAction(s2t("make"), descriptor, DialogModes.NO);
    }

    // Apply image mask layer (Clean SL)
    applyImage(true);

    function applyImage(preserveTransparency) {
        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();
        reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("RGB"));
        reference.putName(s2t("layer"), "Layer 1");
        descriptor2.putReference(s2t("to"), reference);
        descriptor2.putBoolean(s2t("preserveTransparency"), preserveTransparency);
        descriptor.putObject(s2t("with"), c2t("Clcl"), descriptor2);
        executeAction(s2t("applyImageEvent"), descriptor, DialogModes.NO);
    }

    app.activeDocument.activeLayer = app.activeDocument.layers.getByName("Layer 1");
    app.activeDocument.activeLayer.remove();

    // Finish - Doing stuff to open files

    // Save JPEG
    var docName = app.activeDocument.name.replace(/^Old/i, '');
    app.activeDocument.flatten();
    app.activeDocument.saveAs(new File(outFolder + '/' + 'Finished' + docName.split('.')[0] + '.jpg'), jpegOptions);
    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}

alert('Script completed!');

 

 

 

 

 

 

TOPICS
Actions and scripting, How to

Views

433

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Dec 18, 2019 0
Adobe Community Professional ,
Dec 18, 2019

Copy link to clipboard

Copied

You would have to do that with a script. Using the plugin scriptListener, you can get much of the code that you need. There have been other threads that want to do things somewhat similar, in which you can find some rough examples.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 18, 2019 0
Most Valuable Participant ,
Dec 18, 2019

Copy link to clipboard

Copied

Jpeg files have a single background layer that does not support transparency so can not have a mask. If you were to paste a new image in the open old image  jpeg background layer from a second open new image jpeg a new layer would be added over the background layer it would contain no transparency. Depending on its size it would cover all or part of the document canvas. So all or part if the old image will be covered.  The second layer will be a normal raster image layer that can be masked.  If you mask that layer using the third jpeg  image luminosity  part or the second image layer will contain transparency which will reveal parts of the  old image below it.  Saving this as a jpeg you will have a composite of the old and new image. Is this what you want to do?

JJMack

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 18, 2019 0
Adobe Community Professional ,
Dec 21, 2019

Copy link to clipboard

Copied

The first question that pops into mind is – are the source images in 3 separate folders, or in a single folder?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 21, 2019 0
Explorer ,
Dec 21, 2019

Copy link to clipboard

Copied

Hello,

thank you.

will try scriptListener but would be cool to see example even here 🙂

I can put files in separate folder - no problem.

do you know how to do it then?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 21, 2019 0
Adobe Community Professional ,
Dec 22, 2019

Copy link to clipboard

Copied

I have some ideas and might be able to help, however, this may be a little advanced for my scripting level.

 

can you provide download links to 3 sets of images?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 22, 2019 0
Adobe Community Professional ,
Dec 22, 2019

Copy link to clipboard

Copied

Try this. There is no error checking, so you have to set things up exactly with 4 folders on your desktop, labeled: "old images," "new images," "mask images," and "done images." You can edit the code to place the folders whereever you want. Each folder has to have the same number of files in them, except the done folder - obivously. You could also have all the files in one folder, but then you would have to create a new mask for each getFiles command. So instead of '*.jpg' it would be 'NewImage????.jpg' etc.

#target photoshop
var oldFolder = new Folder('~/desktop/old images/');
var newFolder = new Folder('~/desktop/new images/');
var maskFolder = new Folder('~/desktop/mask images/');
var doneFolder = new Folder('~/desktop/done images/');

var mask = '*.jpg';
var oldFiles = oldFolder.getFiles (mask);
var newFiles = newFolder.getFiles (mask);
var maskFiles = maskFolder.getFiles (mask);

var jpegOptions = new JPEGSaveOptions();
jpegOptions.quality = 8;

var count = 10001

for(var i=0;i<oldFiles.length;i++){
    var doc = open(oldFiles[i]);
    var newF = open(newFiles[i]);
    newF.activeLayer.duplicate (doc.activeLayer, ElementPlacement.PLACEBEFORE);
    newF.close(SaveOptions.DONOTSAVECHANGES);
    var maskF = open(maskFiles[i]);
    activeDocument = doc;
    var mLay = doc.activeLayer = doc.layers[0];
    addMask ();
    addMaskImage (maskF.name);
    maskF.close(SaveOptions.DONOTSAVECHANGES);
    doc.flatten();
    doc.saveAs (new File(doneFolder+'/done-'+count.toString().substr (1, 4)),jpegOptions)
    count++
    doc.close(SaveOptions.DONOTSAVECHANGES);
    }

function addMask(){
    var idMk = charIDToTypeID( "Mk  " );
        var desc572 = new ActionDescriptor();
        var idNw = charIDToTypeID( "Nw  " );
        var idChnl = charIDToTypeID( "Chnl" );
        desc572.putClass( idNw, idChnl );
        var idAt = charIDToTypeID( "At  " );
            var ref76 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idChnl = charIDToTypeID( "Chnl" );
            var idMsk = charIDToTypeID( "Msk " );
            ref76.putEnumerated( idChnl, idChnl, idMsk );
        desc572.putReference( idAt, ref76 );
        var idUsng = charIDToTypeID( "Usng" );
        var idUsrM = charIDToTypeID( "UsrM" );
        var idRvlA = charIDToTypeID( "RvlA" );
        desc572.putEnumerated( idUsng, idUsrM, idRvlA );
    executeAction( idMk, desc572, DialogModes.NO );    
    }

function addMaskImage(fName){
    var idAppI = charIDToTypeID( "AppI" );
        var desc576 = new ActionDescriptor();
        var idWith = charIDToTypeID( "With" );
            var desc577 = new ActionDescriptor();
            var idT = charIDToTypeID( "T   " );
                var ref77 = new ActionReference();
                var idChnl = charIDToTypeID( "Chnl" );
                var idChnl = charIDToTypeID( "Chnl" );
                var idRGB = charIDToTypeID( "RGB " );
                ref77.putEnumerated( idChnl, idChnl, idRGB );
                var idLyr = charIDToTypeID( "Lyr " );
                var idBckg = charIDToTypeID( "Bckg" );
                ref77.putProperty( idLyr, idBckg );
                var idDcmn = charIDToTypeID( "Dcmn" );
                ref77.putName( idDcmn, fName );
            desc577.putReference( idT, ref77 );
            var idPrsT = charIDToTypeID( "PrsT" );
            desc577.putBoolean( idPrsT, true );
        var idClcl = charIDToTypeID( "Clcl" );
        desc576.putObject( idWith, idClcl, desc577 );
    executeAction( idAppI, desc576, DialogModes.NO );    
    }

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 22, 2019 0
Adobe Community Professional ,
Dec 24, 2019

Copy link to clipboard

Copied

Hi Chuck, I get the following error when running your script (Mac OS Mojave 10.14.6) with CC 2019:

 

error.png

 

In addition to the error, it is also incorrectly combining two images from different sequence numbers.

 

EDIT: I see that the crappy new forum software has resized the image into illegibility, sigh.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 24, 2019 0
Adobe Community Professional ,
Dec 24, 2019

Copy link to clipboard

Copied

Open in new tab or after clicking on an image press on Windows Ctrl + few times.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 24, 2019 0
Adobe Community Professional ,
Dec 24, 2019

Copy link to clipboard

Copied

Stephen, is your mask, grayscale? I just used a rgb file, so that would throw an error. If the files are out of sequence,  then a sort on each of the arrays should fix that.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 24, 2019 0
Adobe Community Professional ,
Dec 25, 2019

Copy link to clipboard

Copied

Yes, the JPEG mask files are RGB, no alphas or layers. Happy to share them if needed, they work fine with my script.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 25, 2019 0
Adobe Community Professional ,
Dec 25, 2019

Copy link to clipboard

Copied

Sent you a PM, Stephen, about the files.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 25, 2019 0
Adobe Community Professional ,
Dec 26, 2019

Copy link to clipboard

Copied

I had the same problem in both CC2018 and CC2019, so this appears to be a Mac issue related to file input that is different to Windows.

 

I did as you suggested Chuck, although there were a number of false starts as I was not sure where to apply the sorts...

 

In the end everything worked fine when I added the following code after the variables were created, before the jpegOptions variable block:

 

oldFiles.sort();
newFiles.sort();
maskFiles.sort();

 

So, what I am taking away from this is:

 

For a cross-platform script that relies on the input sort order being correct, one should always include a sort!

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 26, 2019 0
Adobe Community Professional ,
Dec 26, 2019

Copy link to clipboard

Copied

Yes, that's what I would have done with the sorts, on each array list. Never had issues with sort order on Win, so never thought about it.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 26, 2019 0