Copy link to clipboard
Copied
Hello,
I'm trying to build a script (I don't know anything about coding in JavaScript) that grabs PSD from a folder and save them to PNG with color profile embedded, in a subfolder called PNG.
Like Image Processor does but for PNG.
I know you can do it with an action but I need more flexibility. I have tryied Image Processor Pro but do not give the option to set the compression.
Google can find a thread related to this argument but seams to be archived now.
https://forums.adobe.com/thread/1511528
Any help?
var inputFolder = Folder.selectDialog("Select a folder to process");
var fileList = inputFolder.getFiles("*.psd");
pngOptions = new PNGSaveOptions()
pngOptions.compression = 0
pngOptions.interlaced = false
savePath = File(originalDoc.path + "/" + originalDoc.name.replace(/\.[^\.]+$/, '.png'));
newDoc.saveAs(savePath, pngOptions, false, Extension.LOWERCASE)
newDoc.close()
app.activeDocument=originalDoc
Copy link to clipboard
Copied
I just hacked a script that I previously hacked from another script... Hope it helps (there is both a save for web and save as version):
https://gist.github.com/MarshySwamp/597818a60c2210f849ccc21c0e5e30b7
https://gist.github.com/MarshySwamp/a5135a6281632ac3316b66546dc39775
In the save as version, I found very large file sizes using pngOptions.compression = 0
Any value from 1 - 9 was preferrable
#target photoshop
// Batch Export SfW sRGB PNG.jsx
displayDialogs = DialogModes.NO
// raw.githubusercontent.com/jonahvsweb/Photoshop-Automated-Resize-to-Web.jsx/master/Automated%20Resize%20To%20Web.jsx
if (BridgeTalk.appName == "photoshop") {
app.bringToFront;
var inputFolder = Folder.selectDialog("Select the source folder that contains the PSD files for PNG export:");
if (inputFolder != null) {
var fileList = inputFolder.getFiles(/\.(psd)$/i);
var outputFolder = inputFolder ;
for (var i = 0; i < fileList.length; i++) {
if (fileList[i] instanceof File) {
var document = open (fileList [i]);
var documentName = fileList [i].name.replace(/\.[^\.]+$/, ''); // Regex remove filename extension
while (app.documents.length) {
var newFile = new File(decodeURI(outputFolder) + "/" + documentName + ".png");
// document.flatten (); // Disable flatten image step
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function ConvertTosRGBProfile() {
app.activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
exportOptions = new ExportOptionsSaveForWeb();
exportOptions.format = SaveDocumentType.PNG;
exportOptions.PNG8 = false; // false = PNG-24
exportOptions.transparency = true; // true = transparent
exportOptions.interlaced = false; // true = interlacing on
exportOptions.includeProfile = true; // false = don't embedd ICC profile
document.exportDocument(newFile, ExportType.SAVEFORWEB, exportOptions);
document.close(SaveOptions.DONOTSAVECHANGES);
}
}
if (i == fileList.length - 1) {
alert("All PSD files have been saved as PNG files!");
}
}
}
}
#target photoshop
// Batch Save As sRGB PNG.jsx
displayDialogs = DialogModes.NO
// raw.githubusercontent.com/jonahvsweb/Photoshop-Automated-Resize-to-Web.jsx/master/Automated%20Resize%20To%20Web.jsx
if (BridgeTalk.appName == "photoshop") {
app.bringToFront;
var inputFolder = Folder.selectDialog("Select the source folder that contains the PSD files for save as PNG:");
if (inputFolder != null) {
var fileList = inputFolder.getFiles(/\.(psd)$/i);
var outputFolder = inputFolder;
for (var i = 0; i < fileList.length; i++) {
if (fileList[i] instanceof File) {
var document = open(fileList[i]);
var documentName = fileList[i].name.replace(/\.[^\.]+$/, ''); // Regex remove filename extension
while (app.documents.length) {
var newFile = new File(decodeURI(outputFolder) + "/" + documentName + ".png");
// document.flatten (); // Disable flatten image step
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function ConvertTosRGBProfile() {
app.activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var pngOptions = new PNGSaveOptions();
pngOptions.compression = 0
pngOptions.interlaced = false;
app.activeDocument.saveAs(newFile, pngOptions, true, Extension.LOWERCASE);
app.activeDocument.close();
}
}
if (i == fileList.length - 1) {
alert("All PSD files have been saved as PNG files!");
}
}
}
}
Copy link to clipboard
Copied
It works but unfortunately this script converts everything to sRGB IEC61966-2.1. The PSD files I have are carrying different ICC Profile.
And seams that if I add this to the PNG expoert setting do not work as it should.
exportOptions.includeProfile = true
Copy link to clipboard
Copied
The sRGB conversation code block is clearly/obviously identified for easy removal.
I would be wary of a PNG file that was not in sRGB space.
Save as PNG does not support embedded ICC profiles, while Save for Web does.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Copy link to clipboard
Copied
I was jsut searching for a solution for my Proble saving as PNG but keep the icc profile embedded in any case. Unfortunatly this seems not possible with the PNGSaveOptions and it just uses the last manual used option (Which might be to no embed the icc profile).
Copy link to clipboard
Copied
Finally in v2022 Save As PNG now retains the ICC profile as well as the resolution metadata!
Export > Save for Web (Legacy) always embedded the ICC profile, however it strips the resolution metadata.
Copy link to clipboard
Copied
Thank you. Is it always including the ICC profile or is it optional if optional is there a new parameter for the PNGSaveOptions?
Copy link to clipboard
Copied
@JoeMedow wrote:
Thank you. Is it always including the ICC profile or is it optional if optional is there a new parameter for the PNGSaveOptions?
As far as I know, the last update to the scripting reference was in 2020, so there is no object model code for this.
In version 2022, one can use the scripting listener plug-in to record the PNG save process including the embedding of the ICC profile.
/*
PS2022 - Save As PNG with ICC Profile to Parent Folder.jsx
Based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-scripting/td-p/12934278
11th May 2022, v1.0 - Stephen Marsh
*/
#target photoshop
if (app.documents.length !== 0) {
// Remove the filename extension
var docName = activeDocument.name.replace(/\.[^\.]+$/, '');
try {
// Use the previously saved directory path
var docPath = activeDocument.path;
} catch (e) {
// If unsaved, prompt for the save path
var docPath = Folder.selectDialog('Unsaved file, select the save directory:');
}
// File Path & Naming
var saveForWebPNG = new File(docPath + '/' + docName + '.png');
// Conditional overwrite check
if (saveForWebPNG.exists) {
// true = 'No' as default active button
if (!confirm('File exists, overwrite: Yes or No?', true))
// throw alert('Script cancelled!');
throw null;
}
// PS2022 code to include profile
var idsave = stringIDToTypeID("save");
var desc268 = new ActionDescriptor();
var idas = stringIDToTypeID("as");
var desc269 = new ActionDescriptor();
var idmethod = stringIDToTypeID("method");
var idPNGMethod = stringIDToTypeID("PNGMethod");
var idquick = stringIDToTypeID("quick");
desc269.putEnumerated(idmethod, idPNGMethod, idquick);
var idPNGInterlaceType = stringIDToTypeID("PNGInterlaceType");
var idPNGInterlaceType = stringIDToTypeID("PNGInterlaceType");
var idPNGInterlaceNone = stringIDToTypeID("PNGInterlaceNone");
desc269.putEnumerated(idPNGInterlaceType, idPNGInterlaceType, idPNGInterlaceNone);
var idPNGFilter = stringIDToTypeID("PNGFilter");
var idPNGFilter = stringIDToTypeID("PNGFilter");
var idPNGFilterAdaptive = stringIDToTypeID("PNGFilterAdaptive");
desc269.putEnumerated(idPNGFilter, idPNGFilter, idPNGFilterAdaptive);
//
var idcompression = stringIDToTypeID("compression");
desc269.putInteger(idcompression, 6);
//
var idembedIccProfileLastState = stringIDToTypeID("embedIccProfileLastState");
var idembedOff = stringIDToTypeID("embedOff");
var idembedOn = stringIDToTypeID("embedOn");
desc269.putEnumerated(idembedIccProfileLastState, idembedOff, idembedOn);
//
var idPNGFormat = stringIDToTypeID("PNGFormat");
desc268.putObject(idas, idPNGFormat, desc269);
//
var idin = stringIDToTypeID("in");
desc268.putPath(idin, new File(docPath + '/' + docName + '.png'));
//
var iddocumentID = stringIDToTypeID("documentID");
desc268.putInteger(iddocumentID, 219);
//
var idcopy = stringIDToTypeID("copy");
desc268.putBoolean(idcopy, true);
//
var idlowerCase = stringIDToTypeID("lowerCase");
desc268.putBoolean(idlowerCase, true);
var idsaveStage = stringIDToTypeID("saveStage");
var idsaveStageType = stringIDToTypeID("saveStageType");
var idsaveSucceeded = stringIDToTypeID("saveSucceeded");
desc268.putEnumerated(idsaveStage, idsaveStageType, idsaveSucceeded);
executeAction(idsave, desc268, DialogModes.NO);
//activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// alert('PNG saved to: ' + '\r' + docPath.fsName);
// docPath.execute();
} else {
alert('You must have a document open!');
}
Copy link to clipboard
Copied
So I found this way around. It wokrs but you need to set Photoshop to preserve the embedded color profile.
function colorProfileType() {
app.activeDocument.colorProfileType = ColorProfile.custom;
}
Copy link to clipboard
Copied
I was wondering if there is a way to save the PNG into a SubFolder of the InputFolder named 'PNG'
Copy link to clipboard
Copied
The following script retains the original colour space and embeds the same ICC colour profile into the PNG, while saving to a subdirectory of the input folder named PNG:
#target photoshop
// Batch Export SfW PNG to PNG Subfolder.jsx
displayDialogs = DialogModes.NO
// raw.githubusercontent.com/jonahvsweb/Photoshop-Automated-Resize-to-Web.jsx/master/Automated%20Resize%20To%20Web.jsx
if (BridgeTalk.appName == "photoshop") {
app.bringToFront;
var inputFolder = Folder.selectDialog("Select the source folder that contains the files for PNG export:");
if (inputFolder != null) {
var fileList = inputFolder.getFiles(/\.psd$/i);
var outputFolder = new Folder(decodeURI(inputFolder) + "/PNG"); // Change the name of the output folder but dont remove the /forward slash
if (outputFolder.exists == false) outputFolder.create();
for (var i = 0; i < fileList.length; i++) {
if (fileList[i] instanceof File) {
var document = open (fileList [i]);
var documentName = fileList [i].name.replace(/\.[^\.]+$/, ''); // Regex remove filename extension
while (app.documents.length) {
var newFile = new File(decodeURI(outputFolder) + "/" + documentName + ".png");
// document.flatten (); // Disable flatten image step
///// <a href="https://github.com/LeZuse/photoshop-scripts/blob/master/default/Image%20Processor.jsx" target="_blank">https://github.com/LeZuse/photoshop-scripts/blob/master/default/Image%20Processor.jsx</a> ////////////////////////////////
/* function ConvertTosRGBProfile() {
app.activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
} */
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
exportOptions = new ExportOptionsSaveForWeb();
exportOptions.format = SaveDocumentType.PNG;
exportOptions.PNG8 = false; // false = PNG-24
exportOptions.transparency = true; // true = transparent
exportOptions.interlaced = false; // true = interlacing on
exportOptions.includeProfile = true; // false = don't embedd ICC profile
document.exportDocument(newFile, ExportType.SAVEFORWEB, exportOptions);
document.close(SaveOptions.DONOTSAVECHANGES);
}
}
if (i == fileList.length - 1) {
alert("All PSD files have been saved as PNG files!");
}
}
}
}
Copy link to clipboard
Copied