Copy link to clipboard
Copied
I want to combine three images (each 300 px by 500 px) into a single long portrait image, keeping their original dimensions intact. The goal is to automatically align them vertically, one below the other, as though they are stitched together.
While "Load Files into Stack" allows me to import them as a single file without altering their size, I still have to manually enlarge the canvas and align the images myself. When I have just three images, it's easy to manage them, but it becomes frustrating when I have 20 images to deal with.
On the other hand, "Contact Sheet" somewhat accomplishes this task, but it requires me to calculate the total height and ends up changing the original size while also leaving gaps between the images.
I saved the code as "StackAlign.js" I'm unsure about the script extension, whether it should be JS or JSX, but it worked. A massive thanks!
🙏
Copy link to clipboard
Copied
You can use Contact Sheet without gaps, but you do need to determine what the end size should be.
In this example, I made 3 rectangles that were 6 x 4 inches @ 72 ppi, so
Copy link to clipboard
Copied
Three key issues:
1. To calculate the total height of the stacked images, I have to open each image individually and sum their heights. This method is time-consuming, especially when dealing with many images (e.g., 10 or more).
2. There is a minimal gap between the images. Even when I uncheck the spacing option, the images are still not the same height, with a height difference of about 1 to 5 pixels. Sometimes, images do not have the same height, so calculating the final height by multiplying one size by the quantity does not work. I need to stitch them together seamlessly, without any gaps.
3. Adding a layer mask to each layer creates an additional complication, as I must apply the mask (Apply Layer Mask) one by one.
Copy link to clipboard
Copied
I understand about the difference in heights and calculating them if you have more than the 3 from your original example.
I would mention that the screenshot I added shows the result directly from Contact Sheet II. It automatically added the layer masks as a part of the process.
Copy link to clipboard
Copied
I was aware of "Contact Sheet" auto masking but didn't mention the entire scenario, including all pros and cons, in my first post. Thank you for your time.
Copy link to clipboard
Copied
You could write a script for this. Read the height of each image, create a new canvas the total size, and then place each image at the correct offset. Or look for an image tiling script, I bet something is available online.
Copy link to clipboard
Copied
I do not have any experience with script writing, but I am looking for a script that functions like "Load into Stack" while also automatically aligning and arranging the images one below the other.
Copy link to clipboard
Copied
I have written scripts for such tasks. Let me dig up the link...
Copy link to clipboard
Copied
Copy link to clipboard
Copied
I saved the code as "StackAlign.js" I'm unsure about the script extension, whether it should be JS or JSX, but it worked. A massive thanks!
🙏
Copy link to clipboard
Copied
I saved the code as "StackAlign.js" I'm unsure about the script extension, whether it should be JS or JSX, but it worked. A massive thanks!
🙏
By @Ten.10
You're welcome!
Copy link to clipboard
Copied
Edit: Just saw Stephen's reply appear after I posted this. His script looks superior if you don't have the files already imported as layers. The one below might still be useful if you want to stack all the existing layers in an existing document.
I used AI whip up this script, it seems to work based on my testing.
It works with layers even if they're all different sizes. It will set the canvas width to the widest image.
It also has true/false options at the top for how to align layers if they aren't all the same width, specifically whether to center them or left-align them, and whether to align to the nearest pixel if centering them.
The script assumes the layers are already all loaded into the same document and in the order you want to stack them. So you can keep using "Load files into stack" if you have a lot of them.
#target photoshop
/*
Script: Stack Layers Vertically
Description: Stacks layers vertically with options for alignment (Left vs Center).
*/
// ================= CONFIGURATION ================= //
var ALIGN_CENTER = true; // Set to true to center layers horizontally, false to align left
var SNAP_TO_PIXEL = true; // When centering, whether to align the position to the nearest whole pixel. Only applies if ALIGN_CENTER is true.
// ================================================= //
function main() {
if (app.documents.length === 0) {
alert("Please open a document with layers first.");
return;
}
var doc = app.activeDocument;
// Save original ruler units to restore later
var originalUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var layers = doc.layers;
var totalHeight = 0;
var maxWidth = 0;
var visibleLayers = [];
// 1. Gather Data and Calculate Canvas Size
for (var i = 0; i < layers.length; i++) {
var layer = layers[i];
// We only care about visible layers (ignores backgrounds/hidden drafts)
if (layer.visible) {
visibleLayers.push(layer);
var bounds = layer.bounds; // [left, top, right, bottom]
var w = bounds[2].value - bounds[0].value;
var h = bounds[3].value - bounds[1].value;
totalHeight += h;
if (w > maxWidth) {
maxWidth = w;
}
}
}
// 2. Resize the canvas
// We resize to the calculated total height and max width found.
// Anchor is TOPCENTER if centering, TOPLEFT if not.
var anchor = ALIGN_CENTER ? AnchorPosition.TOPCENTER : AnchorPosition.TOPLEFT;
doc.resizeCanvas(maxWidth, totalHeight, anchor);
// 3. Move layers into position
var currentY = 0;
for (var i = 0; i < visibleLayers.length; i++) {
var layer = visibleLayers[i];
var bounds = layer.bounds;
var currentLeft = bounds[0].value;
var currentTop = bounds[1].value;
var layerWidth = bounds[2].value - bounds[0].value;
var layerHeight = bounds[3].value - bounds[1].value;
// Calculate Target X
var targetX = 0;
if (ALIGN_CENTER) {
// (Canvas Width - Layer Width) / 2
targetX = (maxWidth - layerWidth) / 2;
} else {
// Left align means X is always 0
targetX = 0;
}
// Snap to nearest pixel if requested
if (ALIGN_CENTER && SNAP_TO_PIXEL) {
targetX = Math.round(targetX);
}
// Calculate Delta (How much to move)
var deltaX = targetX - currentLeft;
var deltaY = currentY - currentTop;
layer.translate(deltaX, deltaY);
// Advance Y cursor
currentY += layerHeight;
}
// Restore original units
app.preferences.rulerUnits = originalUnits;
}
// Run the function wrapped in suspendHistory for a single Undo step
app.activeDocument.suspendHistory("Stack Layers Vertically", "main()");
Copy link to clipboard
Copied
Thank you for your help. However, it seems that your "vibe coded" script (the AI-assisted script) has an error.
I would prefer a one-click solution. Your approach is good, but it requires me to first use "Load Files into Stack" before applying your script to align the images vertically or horizontally based on the currently loaded stack.
Copy link to clipboard
Copied
While on the general/related topic of stacking multiple source docs to a single doc (not creating a horizontal or vertical layout):
Copy link to clipboard
Copied
I haven't encountered this problem yet, but I saved this script just in case! I have a feeling it will come in handy someday!
I think you are the Godzilla of coding. God bless you. I'm envious of you!
🙏
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more