Copy link to clipboard
Copied
Hi all! This time things got even more difficult for my knowledge of Actions and scripts. The situation is as follows: I receive jpeg and png files, in different folders and subfolders. PNGs are clipping masks, which must be applied to JPEGs. The files have the same name, what changes is only the extension. Is it possible for a script, action, or both to open the jpegs, get the corresponding PNGs in the other folder, apply them as a mask on the JPEG to remove the background, and save the file as jpeg (final) in another folder?
It could be separated too, the most important thing is to apply the PNG masks to the JPEGs. A script that recognizes the same names in the folder, opens and places the PNG inside the JPEG, would be of great help. The rest I think would be possible with Actions/Batch, right?
Thank you all for the help!
A common request, so a fairly quick edit to a previous script delivered the following script. I have added an _Masked to the filename to avoid accidentally overwriting existing files. If this is unwanted, it should be easy to remove with the example in lines 80-81.
/*
Mask JPG files using PNG files from 2 input folders.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/png-and-jpeg-clipping-mask/m-p/12730278#M621037
Stephen Marsh, v1.0 - 5th February 2022
*/
#target photoshop
...
Copy link to clipboard
Copied
Copy link to clipboard
Copied
A common request, so a fairly quick edit to a previous script delivered the following script. I have added an _Masked to the filename to avoid accidentally overwriting existing files. If this is unwanted, it should be easy to remove with the example in lines 80-81.
/*
Mask JPG files using PNG files from 2 input folders.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/png-and-jpeg-clipping-mask/m-p/12730278#M621037
Stephen Marsh, v1.0 - 5th February 2022
*/
#target photoshop
(function () {
if (app.documents.length === 0) {
try {
// JPG image input folder
var folder1 = Folder.selectDialog("Select the JPG image folder:");
if (folder1 === null) {
alert('Script cancelled!');
return;
}
// PNG image input folder
var folder2 = Folder.selectDialog("Select the PNG mask folder to layer:");
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 formats
var list1 = folder1.getFiles(/\.(jpg|jpeg)$/i);
var list2 = folder2.getFiles(/\.(png)$/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 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 = 11;
// Perform the stacking and saving
for (var i = 0; i < list1.length; i++) {
var doc = open(list1[i]);
var docName = doc.name.replace(/\.[^\.]+$/, '');
placeFile(list2[i], 100);
channelSelection();
app.activeDocument.activeLayer.remove();
maskSelection("revealSelection");
doc.saveAs(new File(saveFolder + '/' + docName + '_Masked' + '.jpg'), jpgOptions);
//doc.saveAs(new File(saveFolder + '/' + docName + '.jpg'), jpgOptions);
doc.close(SaveOptions.DONOTSAVECHANGES);
}
// End of script
app.displayDialogs = savedDisplayDialogs;
app.beep();
var listCount = list1.length;
alert('Script completed!' + '\r' + listCount + ' JPEG 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 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) {}
}
function channelSelection() {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putProperty(s2t("channel"), s2t("selection"));
descriptor.putReference(s2t("null"), reference);
reference2.putEnumerated(s2t("channel"), s2t("channel"), s2t("grain"));
descriptor.putReference(s2t("to"), reference2);
executeAction(s2t("set"), descriptor, DialogModes.NO);
}
function maskSelection(maskParameter) {
// Parameter = "revealSelection" or "hideSelection"
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"), s2t("userMaskEnabled"), s2t(maskParameter));
executeAction(s2t("make"), descriptor, DialogModes.NO);
}
}());
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html
Copy link to clipboard
Copied
Thank you Stephen and Kukurykus. The script works, but only if I have the files separated into folders, with the same number of images. Unfortunately, the files are in subfolders, scattered around, and together with other files. Is it possible to do something like a droplet, and throw all the folders, and the script recognize the JPEGs and PNGs by name in the subfolders, and apply the masks?
thanks again
Copy link to clipboard
Copied
Maybe you could post meaningful screenshots to illustrate the file and folder naming and locations?
Copy link to clipboard
Copied
Is it possible that you move or copy the files to conform to the script?
Copy link to clipboard
Copied
So you don't have 2 subfolders, one for .png's and second for jpg's, where beside matching files by their name there are some other files of same format? Any way you can easily modify my script if you have 2 subfolders. 'A' with png's and 'B' with jpg's on desktop (or other location if you change their path in the script). They don't have to have the same amount of files, and the names of the rest files don't have to match the ones from the other folder.
If the files have the same dimension & resolution use your values instead of 2550, 3300 & 300.
Aditionally change:
B = File(pth + 'B').getFiles('*.png');
to:
B = pth + 'B/';
and:
while(A.length) parng(shft = A.shift(), 'dLayerRelinkToFile'), parng(B.shift(), 'Event'),
to:
while(A.length)(jpg=File(B+(shft=A.shift()).name.slice(0, -3)+'jpg'),
jpg.exists) && (parng(shft,'dLayerRelinkToFile'),parng(jpg,'Event'),
Copy link to clipboard
Copied
We made some changes to the folders so the script works as we need it. Thanks to all of you for the huge help!