How to combine images horizontally via batch?

New Here ,
Jan 29, 2022 Jan 29, 2022

Copy link to clipboard

Copied

I want to combine several thousand thin images horizontally into one Photoshop file using Batch.

I have looked at the contract sheet tool and it only goes to 100 and also leaves a 1 pixel gap.

Is there way to automatically add an image to the right of the last resizing the canvas as it goes? I managed to get resizing working but can't work out how to add +X to the width of an image with each new image, place it at the right then repeat. 

Any batch experts know how to do this?

TOPICS
Actions and scripting

Views

110

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
Community Expert ,
Jan 29, 2022 Jan 29, 2022

Copy link to clipboard

Copied

I believe that you can use a script developed by the late JJMack for this task:

 

http://www.mouseprints.net/old/dpr/PasteImageRoll.html


Edit: I wrote a different script for vertical stacking, should be easy enough to adapt when I have time.

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
Community Expert ,
Jan 29, 2022 Jan 29, 2022

Copy link to clipboard

Copied

I changed all references from vertical to horizontal and height to width and the alignment options etc... It seems to work as expected, but it has not been extensivly tested:

 

/*
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-combine-images-horizontally-via-batch/m-p/12716190#M619600
Files to Horizontally Stacked Layers.jsx
based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-create-one-big-png-image-from-multiple-png-images/td-p/12359415
Files to Vertically Stacked Layers.jsx
*/

#target photoshop

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

    (function () {

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

        // Capture the original ruler units and set the ruler units to pixels
        var origUnits = app.preferences.rulerUnits;
        app.preferences.rulerUnits = Units.PIXELS;

        // Select the input folder
        var inputFolder = Folder.selectDialog('Please select the input folder:');
        // Test if Cancel button returns null, then do nothing
        if (inputFolder === null) {
            app.beep();
            return;
        }

        // Supported file formats
        var inputFiles = inputFolder.getFiles(/\.(jpg|jpeg|tif|tiff|png|psd|psb)$/i);
        // Alpha numeric sort
        // inputFiles.sort().reverse;
        inputFiles.sort();

        // Process the first "base" file
        var firstFile = app.open(File(inputFiles[0]));
        var firstFileName = app.activeDocument.name;
        app.activeDocument.duplicate("Horizontal-Stacker", false);
        firstFile.close(SaveOptions.DONOTSAVECHANGES);
        var docStack = app.documents[0];
        app.activeDocument = docStack;
        docStack.activeLayer.name = firstFileName;
        var baseHeight = app.activeDocument.width.value;

        // Process the remaining file layers to the "base" file
        for (var i = 1; i < inputFiles.length; i++) {
            var remainingFiles = app.open(File(inputFiles[i]));
            var fileName = remainingFiles.name;
            remainingFiles.activeLayer.name = fileName;
            remainingFiles.layers[0].duplicate(docStack, ElementPlacement.PLACEATBEGINNING);
            remainingFiles.close(SaveOptions.DONOTSAVECHANGES);
            relativeCanvasSize(true, baseHeight);
            align2SelectAll('AdCV');
            align2SelectAll('AdLf');
        }

        app.runMenuItem(stringIDToTypeID("selectAllLayers"));
        reverseLayerStack();
        app.activeDocument.flatten();

        app.beep();
        alert(inputFiles.length + ' files horizontally stacked!');

        // Restore the dialogs
        app.displayDialogs = savedDisplayDialogs;

        // Return the original ruler units
        app.preferences.rulerUnits = origUnits;


        // Functions

        function relativeCanvasSize(relative, width) {
            var s2t = function (s) {
                return app.stringIDToTypeID(s);
            };

            var descriptor = new ActionDescriptor();

            descriptor.putBoolean(s2t("relative"), relative);
            descriptor.putUnitDouble(s2t("width"), s2t("pixelsUnit"), width);
            descriptor.putEnumerated(s2t("horizontal"), s2t("horizontalLocation"), s2t("top"));
            executeAction(s2t("canvasSize"), descriptor, DialogModes.NO);
        }

        function align2SelectAll(method) {

            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 reverseLayerStack() {
            var idreverse = stringIDToTypeID("reverse");
            var desc4653 = new ActionDescriptor();
            var idnull = stringIDToTypeID("null");
            var ref2335 = new ActionReference();
            var idlayer = stringIDToTypeID("layer");
            var idordinal = stringIDToTypeID("ordinal");
            var idtargetEnum = stringIDToTypeID("targetEnum");
            ref2335.putEnumerated(idlayer, idordinal, idtargetEnum);
            desc4653.putReference(idnull, ref2335);
            executeAction(idreverse, desc4653, DialogModes.NO);
        }


    })();

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

 

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

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
Community Expert ,
Jan 29, 2022 Jan 29, 2022

Copy link to clipboard

Copied

You can alternatively use the File > Scripts > Load files into stack script to produce a single file with all of the layers, presuming that they sort alphabetically in the correct order.

 

Change the canvas width to the required size.

 

Move the last layer to the right hand side of the canvas edge.

 

Next select all layers in the layers panel and then use the move tool's align/distribute option to distribute all layers horizontally.

 

EDIT: To automate the above, simply run the following script. I have updated the code to automatically run the load files into stack script, so it is now fully automated.

 

/*
Combine Images Horizontally.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-combine-images-horizontally-via-batch/td-p/12716190
Stephen Marsh, v1.0 - 31st January 2022
*/

$.evalFile(File(app.path + '/Presets/Scripts/Load Files into Stack.jsx'));
var newWidth = app.activeDocument.layers.length * 100;
canvasSize(newWidth);
align2SelectAll('AdRg');
app.runMenuItem(stringIDToTypeID('selectAllLayers'));
distributeHorizontally();


// Functions

function distributeHorizontally() {
	var s2t = function (s) {
		return app.stringIDToTypeID(s);
	};
	var descriptor = new ActionDescriptor();
	var reference = new ActionReference();
	reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
	descriptor.putReference( s2t( "null" ), reference );
	descriptor.putEnumerated( s2t( "using" ), s2t( "alignDistributeSelector" ), s2t( "ADSDistH" ));
	executeAction( s2t( "distort" ), descriptor, DialogModes.NO );
}

function canvasSize(width) {
	var s2t = function (s) {
		return app.stringIDToTypeID(s);
	};

	var descriptor = new ActionDescriptor();

	descriptor.putUnitDouble( s2t( "width" ), s2t( "percentUnit" ), width );
	descriptor.putEnumerated( s2t( "horizontal" ), s2t( "horizontalLocation" ), s2t( "left" ));
	executeAction( s2t( "canvasSize" ), descriptor, DialogModes.NO );
}

function align2SelectAll(method) {

   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();

}

 

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

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
Community Expert ,
Jan 29, 2022 Jan 29, 2022

Copy link to clipboard

Copied

You can also try the following scripts here, just use a row value of 1 with a column value as required. You may wish to work in smaller batches, not sure how things would work on "thousands of images" even if they are small:

 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/creating-duplicate-images-for-multi-p...

 

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 ,
Jan 30, 2022 Jan 30, 2022

Copy link to clipboard

Copied

Thank you for giving me multiple options here. I'll give each a go and see which one works the best. This is for a long term art project I've been putting off.  This has been very helpful.

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
Community Expert ,
Jan 30, 2022 Jan 30, 2022

Copy link to clipboard

Copied

LATEST

Thanks, feedback on each of the proposed solutions would be appreciated. This all presumes that each separate file is the same width. 

P.S. Batch/Action isn't really designed for this task, it may be possible but wouldn't be my preferred approach when scripts are available.

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