Script or Automate two photos into one collage

New Here ,
Jul 06, 2022 Jul 06, 2022

Copy link to clipboard

Copied

Is it possible to run a script that combines two photos from two seperate folders into one new photo?  I have hundreds of family photos with writing on the back and I'm looking for some type of automation to expedite the process.  Any help would be greatly appreciated.  

 

Here is an example:

 

FastFoto_2286_b.jpg         

 

FastFoto_2286.jpg

 

New Pic.jpg

 

TOPICS
Windows

Views

65

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
community guidelines

correct answers 1 Correct answer

Adobe Community Professional , Jul 07, 2022 Jul 07, 2022

@Ryan251528664gwx 

 

Give this script a try, it works OK with the two samples, however, that will be part of the challenge, it is only based on a single pair of images and may not work as expected with other images that vary (please refer to my previous post).

 

The script is saving as layered PSD so that you can fine-tune the result.  It is of course possible to use a Batch Action or Image Processor to bulk convert the edited PSD output to JPEG after you make any required refinements. There is

...

Likes

Translate

Translate
Adobe Community Professional ,
Jul 06, 2022 Jul 06, 2022

Copy link to clipboard

Copied

You have hundreds of photos which actually have two images: one is front and another is back or something else? Can you post some screenshots so we can understand what exactly you have and what is end goal. I will tag some people who can help with script @c.pfaffenbichler @Stephen_A_Marsh @Kukurykus @r-bin @jazz-y 

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
community guidelines
Adobe Community Professional ,
Jul 07, 2022 Jul 07, 2022

Copy link to clipboard

Copied

@Bojan Živković - I have seen this request and the three example images from @Ryan251528664gwx indicate what is required... 

 

Edit: The two files are named –

 

FastFoto_2286.jpg

FastFoto_2286_b.jpg

 

As long as the images are consistently named as such, then a simple alphabetical sort from both input folders should correctly match the front to the appropriate back.

 

Both files are different pixel sizes and print sizes:

 

The front image is 1000x997px, 2.1x2.1cm @ 1200ppi

The back image is 4031x4168px, 8.5x8.8cm @ 1200ppi

 

Why such different sizes? I would have thought that they were scanned with the same settings.

 

Will the back image always have a higher pixel count than the front image?

 

Are all of the images meant to be square, or will you have a mixture of square/landscape/portrait scans?

 

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
community guidelines
Adobe Community Professional ,
Jul 07, 2022 Jul 07, 2022

Copy link to clipboard

Copied

@Ryan251528664gwx 

 

Give this script a try, it works OK with the two samples, however, that will be part of the challenge, it is only based on a single pair of images and may not work as expected with other images that vary (please refer to my previous post).

 

The script is saving as layered PSD so that you can fine-tune the result.  It is of course possible to use a Batch Action or Image Processor to bulk convert the edited PSD output to JPEG after you make any required refinements. There is JPEG placeholder code in there if the result was "close enough" on every image so that the save would be direct to JPEG rather than PSD.

 

Anyway, this is more of a proof of concept than anything else as there are a lot of unknowns and I am having to make some assumptions.

 

/*
2up Front & Back Photo Scan Vertical Stacker.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-or-automate-two-photos-into-one-collage/m-p/13054361#M656157
Stephen Marsh, v1.0 - 7th July 2022
*/

#target photoshop

(function () {

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

        try {

            // Input folder 1
            var folder1 = Folder.selectDialog("Select the first input folder (photo front scan):");
            if (folder1 === null) {
                //alert('Script cancelled!');
                return;
            }

            // Input folder 2
            var folder2 = Folder.selectDialog("Select the second input folder (photo back scan)):");
            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(/\.(jpg|jpeg)$/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 output folder to save to...");

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

            /*
            // JPEG save options
            var jpgOptions = new JPEGSaveOptions();
            jpgOptions.formatOptions = FormatOptions.STANDARDBASELINE;
            jpgOptions.embedColorProfile = true;
            jpgOptions.matte = MatteType.NONE;
            jpgOptions.quality = 12;
            */

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

            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(/\.[^\.]+$/, '');
                doc.activeLayer.isBackgroundLayer = false;
                doc.activeLayer.name = docName;
                placeFile(list2[i], 100);
                moveLayerRelativeStack("back");
                relativeCanvasSize(true, 100);
                align2SelectAll('AdBt');
                resizeToDocWidth();
                doc.saveAs(new File(saveFolder + '/' + docName + '_2up' + '.psd'), psdOptions);
                doc.close(SaveOptions.DONOTSAVECHANGES);
                counter++;
            }

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

        } catch (err) {
            while (app.documents.length > 0) {
                app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
            }
            alert("An unexpected error has occurred!");
        }

    } else {
        alert('Please close all open documents before running this script!');
    }

    // Functions

    function moveLayerRelativeStack(relPos) {
        // "previous" or "next" or "front" or "back"
        var c2t = function (s) {
            return app.charIDToTypeID(s);
        };
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var reference = new ActionReference();
        var reference2 = new ActionReference();
        reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
        descriptor.putReference(c2t("null"), reference);
        reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t(relPos));
        descriptor.putReference(s2t("to"), reference2);
        executeAction(s2t("move"), descriptor, DialogModes.NO);
    }

    function resizeToDocWidth() {
        /* 
        https://community.adobe.com/t5/photoshop-ecosystem-discussions/trying-to-do-text-to-fit-the-width-of-the-canvas-dimensions/m-p/11589399
        */
        if (!documents.length) return;
        var startRulerUnits = app.preferences.rulerUnits;
        app.preferences.rulerUnits = Units.PIXELS;
        var doc = app.activeDocument;
        // var res = doc.resolution;
        var dWidth = doc.width;
        var LB = activeDocument.activeLayer.bounds;
        var Width = LB[2].value - LB[0].value;
        var onePix = 100 / Width;
        var newSize = onePix * dWidth;
        doc.activeLayer.resize(newSize, newSize, AnchorPosition.MIDDLECENTER);
        app.preferences.rulerUnits = startRulerUnits;
    }

    function relativeCanvasSize(relative, height) {
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        descriptor.putBoolean(s2t("relative"), relative);
        descriptor.putUnitDouble(s2t("height"), s2t("percentUnit"), height);
        descriptor.putEnumerated(s2t("vertical"), s2t("verticalLocation"), s2t("top"));
        executeAction(s2t("canvasSize"), descriptor, DialogModes.NO);
    }

    function align2SelectAll(method) {
        /* https://gist.github.com/MarshySwamp/df372e342ac87854ffe08e79cbdbcbb5 */

        //www.ps-scripts.com/viewtopic.php?f=66&t=7036&p=35273&hilit=align+layer#p35273
        /* 
        //macscripter.net/viewtopic.php?id=38890
        AdLf = Align Left
        AdRg = Align Right
        AdCH = Align Centre Horizontal
        AdTp = Align Top
        AdBt = Align Bottom
        AdCV = Align Centre Vertical
        */

        app.activeDocument.selection.selectAll();

        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"), charIDToTypeID(method));
        try {
            executeAction(charIDToTypeID("Algn"), desc, DialogModes.NO);
        } catch (e) {}

        app.activeDocument.selection.deselect();

    }

    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) {}
    }

}());

 

  1. Copy the code text to the clipboard
  2. Open a new blank file in a plain-text editor (not in a word processor)
  3. Paste the code in
  4. Save the text file as .txt
  5. Rename the file extension from .txt to .jsx
  6. Install or browse to the .jsx file to run:

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

 

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
community guidelines
New Here ,
Jul 07, 2022 Jul 07, 2022

Copy link to clipboard

Copied

Thank you so much for helping me with this project.  I just ran the script and it processed the files exactly like I needed them!  I can't thank you enough!    

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
community guidelines
Adobe Community Professional ,
Jul 07, 2022 Jul 07, 2022

Copy link to clipboard

Copied

LATEST

Great if you're happy, I'm happy!

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
community guidelines