Copy link to clipboard
Copied
Hello,
Is it possible to combine few tiff's from a folder (mostly 8 but sometimes less) as a one new tiff containing all those tiff's from a folder as layers (names of the layers can be the names of the tiffs)?
Would be perfect is this could be done by a droplet (i put desired folder onto a droplet and as a result i get a signle tiff with multiple layers)
Copy link to clipboard
Copied
With a script it can be done. There most likely are scripts that have been posted to the forum that can do something like this.
Copy link to clipboard
Copied
Photoshop has a script – File > Scripts: "Load Files Into Stack"
This can also be scripted without the interface:
Copy link to clipboard
Copied
Many thanks for the answer.
I've checked that post above and I replied to You there.
That script is very promising but i can't get it work with 1-bit tiff.
Copy link to clipboard
Copied
1bit images (in Photoshop aka »Bitmap images«) cannot have Layers.
Copy link to clipboard
Copied
I know. The result file can be in gray/8 bit.
Copy link to clipboard
Copied
So you need to amend the Script – which Script are you using?
What is giving you problems?
Copy link to clipboard
Copied
I tried this script:
/*
Stacker - Place Embedded.jsx
Stephen Marsh, v1.0
https://community.adobe.com/t5/photoshop-ecosystem-discussions/layers-creating-layers/td-p/13252109
*/
#target photoshop
if (app.documents.length === 0) {
(function () {
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
var origUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var inputFolder = Folder.selectDialog('Please select the input folder:');
if (inputFolder === null) {
app.beep();
return;
}
var inputFiles = inputFolder.getFiles(/\.(jpg|jpeg|tif|tiff|png|psd|psb|gif)$/i);
// inputFiles.sort().reverse;
inputFiles.sort();
app.displayDialogs = DialogModes.NO;
var baseDoc = open(inputFiles[0]);
var baseDoc = activeDocument;
baseDoc.duplicate("Stacker", false);
baseDoc.close(SaveOptions.DONOTSAVECHANGES);
for (var i = 0; i < inputFiles.length; i++) {
placeFile(new File(inputFiles[i]), false, 0, 0);
// Remove the filename extension from the layer name
activeDocument.activeLayer.name = inputFiles[i].name.replace(/\.[^\.]+$/, '');
//align2SelectAll('AdCH');
//align2SelectAll('AdCV');
}
activeDocument.activeLayer = activeDocument.backgroundLayer;
activeDocument.activeLayer.remove();
//app.runMenuItem(stringIDToTypeID("selectAllLayers"));
//reverseLayerStack();
app.beep();
alert(inputFiles.length + ' files stacked!');
app.displayDialogs = savedDisplayDialogs;
app.preferences.rulerUnits = origUnits;
// Functions
function placeFile(null2, linked, horizontal, vertical) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var AD = new ActionDescriptor();
AD.putInteger(s2t("ID"), 1);
AD.putPath(s2t("null"), null2);
AD.putBoolean(s2t("linked"), linked); // false for embedded
AD.putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSAverage"));
AD.putUnitDouble(s2t("horizontal"), s2t("pixelsUnit"), horizontal);
AD.putUnitDouble(s2t("vertical"), s2t("pixelsUnit"), vertical);
AD.putObject(s2t("offset"), s2t("offset"), AD);
executeAction(s2t("placeEvent"), AD, DialogModes.NO);
}
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);
}
function align2SelectAll(method) {
/*
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();
}
})();
} else {
alert('Please close all open files before running this script...');
}
Problem is that this scipt don't work with 1-bit tiff.
The result tiff can be gray/8-bit
Copy link to clipboard
Copied
Could the script convert the TIFFs to 8bpc before combining them?
Copy link to clipboard
Copied
Many thanks for the answer.
I've checked that post above and I replied to You there.
That script is very promising but i can't get it work with 1-bit tiff.
By @Michal278606593tfz
It wasn't designed to stack 1-bit images.
Yes, scripts can be modified... Which one were you using:
Stacker - Place Linked.jsx
or
Stacker - Place Embedded.jsx
As both of these work with smart objects, you would need to take that into account before converting to grayscale/8-bpc.
EDIT: I do have another version that doesn't use smart objects.
Copy link to clipboard
Copied
You can try this version that doesn't use smart objects, I have updated it to convert bitmap mode files to grayscale:
/*
Stacker - Dupe.jsx
Stephen Marsh, v1.2
*/
#target photoshop
if (app.documents.length === 0) {
(function () {
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
var origUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var inputFolder = Folder.selectDialog('Please select the input folder:');
if (inputFolder === null) {
return;
}
var inputFiles = inputFolder.getFiles(/\.(jpg|jpeg|tif|tiff|png|psd|psb|gif)$/i);
// inputFiles.sort().reverse;
inputFiles.sort();
var firstFile = app.open(File(inputFiles[0]));
var firstFileName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
app.activeDocument.duplicate("Stacker", false);
if (activeDocument.mode === DocumentMode.BITMAP) {
activeDocument.changeMode(ChangeMode.GRAYSCALE);
} else if (activeDocument.mode === DocumentMode.INDEXEDCOLOR) {
activeDocument.changeMode(ChangeMode.RGB);
}
firstFile.close(SaveOptions.DONOTSAVECHANGES);
var docStack = app.documents[0];
app.activeDocument = docStack;
docStack.activeLayer.name = firstFileName;
for (var i = 1; i < inputFiles.length; i++) {
var remainingFiles = app.open(File(inputFiles[i]));
if (activeDocument.mode === DocumentMode.BITMAP) {
activeDocument.changeMode(ChangeMode.GRAYSCALE);
} else if (activeDocument.mode === DocumentMode.INDEXEDCOLOR) {
activeDocument.changeMode(ChangeMode.RGB);
}
var fileName = remainingFiles.name.replace(/\.[^\.]+$/, '');
remainingFiles.activeLayer.name = fileName;
remainingFiles.layers[0].duplicate(docStack, ElementPlacement.PLACEATBEGINNING);
remainingFiles.close(SaveOptions.DONOTSAVECHANGES);
//align2SelectAll('AdCH');
//align2SelectAll('AdCV');
}
//app.runMenuItem(stringIDToTypeID("selectAllLayers"));
//reverseLayerStack();
app.beep();
alert(inputFiles.length + ' files stacked!');
app.displayDialogs = savedDisplayDialogs;
app.preferences.rulerUnits = origUnits;
// Functions
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);
}
function align2SelectAll(method) {
/*
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();
}
})();
} else {
alert('Please close all open files before running this script...');
}
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html
Copy link to clipboard
Copied
Thank You so much for help. Your script makes what I wrote but..
I made some mistake 😞 It occurs that I need those tiffs not on Layers but on Channels.
Do You think it is possible to achive?
So I have few (max 8) 1-bit tiff's and I need one tiff (can be flattened) but with Channels.
Copy link to clipboard
Copied
I don’t think a droplet for Folders is plausible for Photoshop but other than that: How experienced are you with JavaScript and Photoshop’s DOM?
Maybe JJMack’s PhotoCollageToolkit can prove useful to you:
Copy link to clipboard
Copied
Well I can't write a script but at least I know how to use them 😉
I asked about the droplet because the script won't speed up/automate too much, but of course it will be helpful.
I was hoping that what I need is not too complicated and I can automate it.
In a nutshell, the idea is to merge several tiff files (1-bit/bitmap) into one with layers (gray/cmyk whatever)
Copy link to clipboard
Copied
I was going to suggest the same thing Christophe, but was not sure if his site was still up. I'll bookmark the github link for sure. I found a thread with some ideas on and the same people contributing, so I am not sure how useful it would be here?
Copy link to clipboard
Copied
If you are on a Mac, you can use Automator to target specific folders and run Droplets on the contents like an app.
Copy link to clipboard
Copied
Hi @Michal278606593tfz are you on a Mac? If so, you could use Automator to run droplets on designated folders.
Copy link to clipboard
Copied
Hi, I'm on PC. I don't have access to Mac.
And I described wrong what I need.
I need one tiff with as many channels as there are 1-bit tiff files in the folder.
Converting those 1-bit tiff's into a channels takes so much time that it would help me so much if it could be automated.
Copy link to clipboard
Copied
I took the liberty of adapting @Stephen Marsh ’s code, see if this helps.
// 2023, use it at your own risk;
/*
adaption of
Stacker - Dupe.jsx
Stephen Marsh, v1.2
*/
if (app.documents.length === 0) {
(function () {
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
var origUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var inputFolder = Folder.selectDialog('Please select the input folder:');
if (inputFolder === null) {
return;
}
var inputFiles = inputFolder.getFiles(/\.(jpg|jpeg|tif|tiff|png|psd|psb|gif)$/i);
// inputFiles.sort().reverse;
inputFiles.sort();
var firstFile = app.open(File(inputFiles[0]));
var firstFileName = app.activeDocument.name.replace(/\.[^\.]+$/, '');
app.activeDocument.duplicate("Stacker", false);
if (activeDocument.mode === DocumentMode.BITMAP) {
activeDocument.changeMode(ChangeMode.GRAYSCALE);
} else if (activeDocument.mode === DocumentMode.INDEXEDCOLOR) {
activeDocument.changeMode(ChangeMode.RGB);
}
firstFile.close(SaveOptions.DONOTSAVECHANGES);
var docStack = app.documents[0];
app.activeDocument = docStack;
docStack.activeLayer.name = firstFileName;
for (var i = 0; i < inputFiles.length; i++) {
var remainingFiles = app.open(File(inputFiles[i]));
if (activeDocument.mode === DocumentMode.BITMAP) {
activeDocument.changeMode(ChangeMode.GRAYSCALE);
} else if (activeDocument.mode === DocumentMode.INDEXEDCOLOR) {
activeDocument.changeMode(ChangeMode.RGB);
}
var fileName = remainingFiles.name.replace(/\.[^\.]+$/, '');
remainingFiles.activeLayer.name = fileName;
app.activeDocument = docStack;
doCalculation (remainingFiles.name);
activeDocument.channels[activeDocument.channels.length - 1].name = fileName;
app.activeDocument = remainingFiles;
remainingFiles.close(SaveOptions.DONOTSAVECHANGES);
}
app.beep();
alert(inputFiles.length + ' files stacked!');
app.displayDialogs = savedDisplayDialogs;
app.preferences.rulerUnits = origUnits;
// Functions
function doCalculation (theFileName) {
var idchannel = stringIDToTypeID( "channel" );
var idordinal = stringIDToTypeID( "ordinal" );
var idtargetEnum = stringIDToTypeID( "targetEnum" );
var iddocument = stringIDToTypeID( "document" );
var desc18 = new ActionDescriptor();
desc18.putClass( stringIDToTypeID( "new" ), idchannel );
var desc19 = new ActionDescriptor();
var ref5 = new ActionReference();
ref5.putEnumerated( idchannel, idordinal, idtargetEnum );
ref5.putEnumerated( stringIDToTypeID( "layer" ), idordinal, stringIDToTypeID( "merged" ) );
ref5.putName( iddocument, theFileName );
desc19.putReference( stringIDToTypeID( "to" ), ref5 );
var ref6 = new ActionReference();
ref6.putEnumerated( idchannel, idordinal, idtargetEnum );
ref6.putEnumerated( stringIDToTypeID( "layer" ), idordinal, stringIDToTypeID( "merged" ) );
ref6.putName( iddocument, theFileName );
desc19.putReference( stringIDToTypeID( "source2" ), ref6 );
desc18.putObject( stringIDToTypeID( "using" ), stringIDToTypeID( "calculation" ), desc19 );
executeAction( stringIDToTypeID( "make" ), desc18, DialogModes.NO );
};
function align2SelectAll(method) {
/*
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();
}
})();
} else {
alert('Please close all open files before running this script...');
}
Copy link to clipboard
Copied
@c.pfaffenbichler sorry for tha late response... but Thank You! Your script does wonders, many thanks for the support 😉
All that's missing for complete happiness is that the first channel will be deleted (it is duplicated first channel) and then saved with any name.