Copy link to clipboard
Copied
Hello:
Searching hasn't found this needed workflow.
Not sure this is the most efficient as it's legacy, but I use Save for Web to output needed images daily. I'd like the "save as" dialog to include month & day followed by and underscore
(ex. 0611_) already included in the file name. It would output a JPG, Quality 50%, Optimized, Convert to sRGB.
Not sure this is possible, but would appreciate any help/direction given.
Thanks!
I like how this script is coming together, it is giving me the opportunity to implement some new ideas. This 1.4 version is back to a single script, there is no need for a two part script.
Hold down SHIFT when running the script to set the save location to the preference file.
Run the script WITHOUT shift to save to the location saved in the preference file.
There is now an error check if the preference file exists (it does not check if the content is valid). I have noticed that if one cance
...Copy link to clipboard
Copied
Where in the filename? At the beginning? Do you need a dialog to possibly refine the rename, or is it simply enough to export the file automatically including the prefix MMDD_ without any window popping up? Where to save to? Do you want a prompt? To the source folder of the current open/saved file? What if the source file is not saved?
Copy link to clipboard
Copied
Hi:
Yes, I'll need to add some other file info before saving, which would be after date and underscore (0611_Subject.jpg)
Thanks!
Copy link to clipboard
Copied
The script will automatically prefix MMDD_ before the existing filename.
So if you don't need to make any further edits to the base filename, you can skip a step.
But if you do need to potentially edit the filename further, then you will need the prompt.
Can the original image be closed without saving, or do you need the original image to remain open after the export?
Copy link to clipboard
Copied
The original will need to stay open as it's a template I use throughout the day.
Copy link to clipboard
Copied
OK, thanks, the script is mostly done, at least for a v1.0, as I hope to offer some refinements...
Are you using copy/paste from another document into the template or file/place embedded or linked in this template multiple times during the day?
Copy link to clipboard
Copied
Just to confirm before I complete the script:
(1) Save location:
Are you happy to have a prompt appear so that you can manually select the location to save the file? If so, should there be a default location where the save location defaults to, such as your Documents folder? Do you have a different requirement?
(2) Filename:
If the template file is named "my_Template.psd" and the prefix is "MMDD_" and the default name produced by the script is "MMDD_myTemplate.jpg" is there any need to edit the filename, or can the script directly save this filename without any interaction? If you do need to edit the name, what sort of manual edits are you making and could these possibly be performed by the script as well? For example, if you were saving the JPG into a folder named after a specific project, the script could use the folder name as part of the saved file name.
Copy link to clipboard
Copied
I save the image into a dated folder, so that would be the default folder to save to. I add a one or two word description of the subject matter. Could the you mimic the dated folder to create the date in the file name? Just curious if that's possible. I really appreciate your help with this!
Copy link to clipboard
Copied
It sounds like you will still need to manually navigate to the directory and subdirectory required. The script will add the MMDD_ anyway so there is no need to use that from the dated folder as it is already prefixed as you originally required.
Let's say you have a directory structure of:
+ Documents
++ Customer-A
++ Customer-B
etc
By selecting the directory for Customer A, the automatically generated filename could use that directory name:
MMDD_templatePSDname someOtherManualText Customer-A.jpg
What I was also asking is that perhaps the script could start in the Documents or Desktop or some other folder to help with the navigation to the main folder, before you select a sub folder.
Anyway, that is icing on the cake, I'll just post the v1.0 script and then we can see what else is possible...
Copy link to clipboard
Copied
Try this v1.0 script.
Please note:
* Existing files of the same name will be overwritten without warning (I can't get the code to work to verify, perhaps somebody else with scripting knowledge can help?)
* A prompt will be offered for you to fine tune the filename, by default it will prefix the MMDD_ before the existing document name (don't use any file extensions).
* A separate window will then open asking where to save the file, no default path to a specific folder is provided .
* photoshop:DocumentAncestors metadata that may accumulate in the template is removed.
/*
Save for Web with Month & Day Script?
https://community.adobe.com/t5/photoshop/save-for-web-with-month-amp-day-script/td-p/12108287
This script exports a Save for Web JPEG to a user selected-folder with a MMDD_ prefix
!!! ATTENTION: Any files with the same name will be overwritten without warning !!!
Export S4W JPG MMDD_ Prefix.jsx
Stephen Marsh, 12th June 2021 - v1.0
*/
#target photoshop
if (app.documents.length !== 0) {
// Date & time variables
// community.adobe.com/t5/photoshop/photoshop-script-save-as-jpg-with-current-date-and-time/td-p/11115756
var dateObj = new Date();
var year = dateObj.getFullYear().toString().substr(-2);
var month = ("0" + (dateObj.getMonth() + 1)).slice(-2);
var date = ("0" + dateObj.getDate()).slice(-2);
var time = dateObj.getTime();
var hours = dateObj.getHours();
var minutes = dateObj.getMinutes();
var seconds = dateObj.getSeconds();
var completeTime = hours.toString() + minutes.toString() + seconds.toString();
var completeDate = year.toString() + month.toString() + date.toString();
// MMDD_ prefix
var mmDDprefix = month.toString() + date.toString() + '_';
// Set the active document variable
var doc = app.activeDocument;
// Name & path related options
var docName = doc.name.replace(/\.[^\.]+$/, '');
var docNameInput = prompt('Enter a filename (without extension):', mmDDprefix + docName);
var docNameOutput = docNameInput.replace(/\.[^\.]+$/, '');
var docPath = Folder.selectDialog('Select a folder to save the JPEG image to...');
// JPEG S4W Options
function SaveForWeb(saveFileJPEG) {
var sfwOptions = new ExportOptionsSaveForWeb();
sfwOptions.format = SaveDocumentType.JPEG;
sfwOptions.includeProfile = true;
sfwOptions.interlaced = 0;
sfwOptions.optimized = true;
sfwOptions.quality = 50;
doc.exportDocument(saveFileJPEG, ExportType.SAVEFORWEB, sfwOptions);
}
// File path & naming
var saveFileJPEG = new File(docPath + '/' + docNameOutput + '.jpg');
// Convert to sRGB
doc.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
// Export
SaveForWeb(saveFileJPEG);
// Delete last history step (sRGB conversion)
var iddelete = stringIDToTypeID("delete");
var desc1497 = new ActionDescriptor();
var idnull = stringIDToTypeID("null");
var ref22 = new ActionReference();
var idhistoryState = stringIDToTypeID("historyState");
var idordinal = stringIDToTypeID("ordinal");
var idlast = stringIDToTypeID("last");
ref22.putEnumerated(idhistoryState, idordinal, idlast);
desc1497.putReference(idnull, ref22);
executeAction(iddelete, desc1497, DialogModes.NO);
// As this is a template, remove photoshop:DocumentAncestors metadata that may build up and bloat the file
// https://prepression.blogspot.com/2017/06/metadata-bloat-photoshopdocumentancestors.html
deleteDocumentAncestorsMetadata();
function deleteDocumentAncestorsMetadata() {
// https://forums.adobe.com/message/8456985#8456985
if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
xmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "DocumentAncestors");
app.activeDocument.xmpMetadata.rawData = xmp.serialize();
}
// Optional end of script message
alert(docNameOutput + '.jpg' + '\r' + 'Saved to:' + '\r' + '\r' + docPath.fsName);
} else {
alert('You must have a document open to use this script!');
}
Downloading and Installing Adobe Scripts
Copy link to clipboard
Copied
Hey, thanks Stephen! Much appreciated!
I'll try it out tomorrow.
-Rob
Copy link to clipboard
Copied
Please let me know how it goes...
I found the issue with the code that checks if a file of the existing name exists, the code was fine, however my S4W settings had inexplicably changed to use a setting with OS compatibility to replace word spaces with hyphens, while my code was expecting word spaces.
If your filenames use hyphens instead of word spaces, the code is easily changed by modifying one character.
I have a new 1.1 code version ready if there are no major changes required.
Copy link to clipboard
Copied
Hey Stephen-
Script works great! Just what I was hoping for!
Any way it can save to the last selected folder without prompting?
Not a big deal if it can't.
Again, I really appreciate the work you put into this!
Big Thanks,
Rob
Copy link to clipboard
Copied
I'm glad it works for you.
As for remembering the last save location, it is possible by writing to a log file, but it is easier said than done (for me) – I'll look into it as I have never done this before. This is why I previously asked if there was at least a fixed location that does not change where the save folder could start.
I'll post the v1.1 version which will offer a prompt asking to answer Yes or No if the export is going to overwrite an existing file (if certain conditions are met).
Copy link to clipboard
Copied
Major changes in v1.1 from the original v1.0 code:
/*
Export S4W sRGB JPG MMDD_ Prefix.jsx
Stephen Marsh, 13th June 2021 - v1.1
Save for Web with Month & Day Script?
https://community.adobe.com/t5/photoshop/save-for-web-with-month-amp-day-script/td-p/12108287
This script exports a Save for Web JPEG to a user selected-folder with a 'MMDD_' prefix
Features:
* Check for overwriting an existing file, validation requires that the file name contains spaces, not hyphens
* Conditional conversion to sRGB ICC profile
* Removal of photoshop:DocumentAncestors metadata that may build up and bloat the template
* NOTE: JPEG Quality value = 50%
*/
#target photoshop
if (app.documents.length !== 0) {
// Date & time variables, this script only uses the month and date (day) variables
// community.adobe.com/t5/photoshop/photoshop-script-save-as-jpg-with-current-date-and-time/td-p/11115756
var dateObj = new Date();
var year = dateObj.getFullYear().toString().substr(-2);
var month = ("0" + (dateObj.getMonth() + 1)).slice(-2);
var date = ("0" + dateObj.getDate()).slice(-2);
var time = dateObj.getTime();
var hours = dateObj.getHours();
var minutes = dateObj.getMinutes();
var seconds = dateObj.getSeconds();
var completeTime = hours.toString() + minutes.toString() + seconds.toString();
var completeDate = year.toString() + month.toString() + date.toString();
// MMDD_ prefix
var mmDDprefix = month.toString() + date.toString() + '_';
// Set the active document variable
var doc = app.activeDocument;
// Name & path related options
// Depending on S4W filename compatibility settings, you may need to replace the space with a hyphen:
// .replace(/ /g, '-');
var docName = doc.name.replace(/\.[^\.]+$/, '').replace(/ /g, ' '); // See above
var docNameInput = prompt('Enter a filename (without extension):', mmDDprefix + docName);
var docNameOutput = docNameInput.replace(/\.[^\.]+$/, '');
var docPath = Folder.selectDialog('Select a folder to save the JPEG image to...');
// JPEG S4W Options
function SaveForWeb(saveFileJPEG) {
var sfwOptions = new ExportOptionsSaveForWeb();
sfwOptions.format = SaveDocumentType.JPEG;
sfwOptions.includeProfile = true;
sfwOptions.optimized = true;
sfwOptions.quality = 50;
doc.exportDocument(saveFileJPEG, ExportType.SAVEFORWEB, sfwOptions);
}
// File path & naming
var saveFileJPEG = new File(docPath + '/' + docNameOutput + '.jpg');
// Confirm overwrite - name validation is dependent on SFW filename compatibility settings
if (saveFileJPEG.exists) {
// true = 'No' as default active button
if (!confirm("File exists, overwrite: Yes or No?", true))
// Optional - swap the throw alert for " throw null; " to remove the alert message
throw alert("Script cancelled!");
}
// Conditional colour space handling
// Check for untagged image
if (doc.colorProfileType === ColorProfile.NONE) {
// alert("Untagged");
// Call the function
sRGBprocessing();
// Check for any profile name which does not contain sRGB
} else if (doc.colorProfileName.match(/\bsRGB\b/) === null) {
// else if (doc.colorProfileName !== "sRGB IEC61966-2.1")
// alert("sRGB = False");
// Call the function
sRGBprocessing();
// Check for any profile name which contains sRGB
} else if (doc.colorProfileName.match(/\bsRGB\b/) !== null) {
// else if (doc.colorProfileName === "sRGB IEC61966-2.1")
// alert("sRGB = True");
// Export
SaveForWeb(saveFileJPEG);
} else { }
function sRGBprocessing() {
// Convert to profile - sRGB (profile, intent, BPC, dither)
doc.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
// Export
SaveForWeb(saveFileJPEG);
// Delete convert to sRGB history step
deleteLastHistoryStep();
function deleteLastHistoryStep() {
var iddelete = stringIDToTypeID("delete");
var desc1497 = new ActionDescriptor();
var idnull = stringIDToTypeID("null");
var ref22 = new ActionReference();
var idhistoryState = stringIDToTypeID("historyState");
var idordinal = stringIDToTypeID("ordinal");
var idlast = stringIDToTypeID("last");
ref22.putEnumerated(idhistoryState, idordinal, idlast);
desc1497.putReference(idnull, ref22);
executeAction(iddelete, desc1497, DialogModes.NO);
}
}
// As this is a template, remove photoshop:DocumentAncestors metadata that may build up and bloat the file
// https://prepression.blogspot.com/2017/06/metadata-bloat-photoshopdocumentancestors.html
deleteDocumentAncestorsMetadata();
function deleteDocumentAncestorsMetadata() {
// https://forums.adobe.com/message/8456985#8456985
if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
xmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "DocumentAncestors");
app.activeDocument.xmpMetadata.rawData = xmp.serialize();
}
// Optional end of script message, comment out or remove as required
alert(docNameOutput + '.jpg' + '\r' + 'Saved to:' + '\r\r' + docPath.fsName);
// Optional end of script alert, comment out or remove as required
// app.beep();
} else {
alert('You must have a document open to use this script!');
}
Copy link to clipboard
Copied
Great! Thanks, Stephen!
Copy link to clipboard
Copied
Where does the script prompt to select a save folder default to, if not the last used folder?
I have tested in CC2021 on both Mac (Big Sur) and Widows (10) and the previous directory used in the script is used, however, I'm not doing anything else in between.
What OS/Version are you using?
What version of Photoshop?
I'll need to think about this. Presumably you can't use the template.psd location. The save folder is not static, you therefore need a prompt to manually select the save folder, yes? So I'd suggest that you still would use a prompt, it is just that the prompt would default to the last saved location, which still gives you flexibility to change the location if needed.
Copy link to clipboard
Copied
It's no big deal. I've been using it all this morning and it's working well.
It's probably better there's a 'save to' dialog going forward.
I'm using Windows 10/PS 22.3.0.
If I get a chance later, I'll load in on my MB Air and see if it produces the same behavior.
But really, thanks again! It's working great!
Rob
Copy link to clipboard
Copied
I'm guessing that my simplistic back-to-back testing of the script does not match your daily workflow, so somewhere in your daily tasks the last used folder is chaning.
I added a preference file option yesterday. It is the first time that I have created a preference file to read/write a file save path. It may not be bullet-proof or robust, however, it appears to work as intended. Testing was not easy as in my tests the last folder was used anyway, so I had to manually update the path in the preference file to ensure that it was actually being used.
I'll post the 1.2 version, please let me know how this one goes.
Copy link to clipboard
Copied
This 1.2 version will read/write to a prererence text file saved to the user home folder.
/*
Export S4W sRGB JPG MMDD_ Prefix.jsx
Stephen Marsh, 14th June 2021 - v1.2
Save for Web with Month & Day Script?
https://community.adobe.com/t5/photoshop/save-for-web-with-month-amp-day-script/td-p/12108287
This script exports a Save for Web JPEG to a user selected-folder with a 'MMDD_' prefix
Features:
* Previous save location written/read from a custom preference text file '_MMDD_Pref-File.pref' in the user home folder
* Check for overwriting an existing file, validation requires that the file name contains spaces, not hyphens
* Conditional conversion to sRGB ICC profile
* Removal of photoshop:DocumentAncestors metadata that may build up and bloat the template
* NOTE: JPEG Quality value = 50%
*/
#target photoshop
if (app.documents.length !== 0) {
// Date & time variables, this script only uses the month and date (day) variables
// community.adobe.com/t5/photoshop/photoshop-script-save-as-jpg-with-current-date-and-time/td-p/11115756
var dateObj = new Date();
var year = dateObj.getFullYear().toString().substr(-2);
var month = ("0" + (dateObj.getMonth() + 1)).slice(-2);
var date = ("0" + dateObj.getDate()).slice(-2);
var time = dateObj.getTime();
var hours = dateObj.getHours();
var minutes = dateObj.getMinutes();
var seconds = dateObj.getSeconds();
var completeTime = hours.toString() + minutes.toString() + seconds.toString();
var completeDate = year.toString() + month.toString() + date.toString();
// MMDD_ prefix
var mmDDprefix = month.toString() + date.toString() + '_';
// Set the active document variable
var doc = app.activeDocument;
// Name options
// Depending on S4W filename compatibility settings, you may need to replace the space with a hyphen:
// .replace(/ /g, '-');
var docName = doc.name.replace(/\.[^\.]+$/, '').replace(/ /g, ' '); // See above
var docNameInput = prompt('Enter a filename (without extension):', mmDDprefix + docName);
var docNameOutput = docNameInput.replace(/\.[^\.]+$/, '');
// Preference File Step 1 - Read the last save path preference file in the user home folder
// It's OK if the pref file doesn't exist in the first use
// Pref file location
var prefFileRead = File('~/_MMDD-Script_Pref-File.pref');
// Open the pref file: r = read mode | w = write mode | a = append | e = edit
var openPrefFile = prefFileRead.open('r');
// Read the value
var prefFileValue = prefFileRead.readln();
// Use the variable from the preference file for the save path
//alert('Preference file path:' + '\r' + prefFileValue);
var docPath = Folder.selectDialog('Select a folder to save the JPEG image to...', prefFileValue);
// Preference File Step 2 - Write the last save path preference file in the user home folder
var prefFile = new File('~/_MMDD-Script_Pref-File.pref');
// Write the directory path to the pref file
// r = read mode | w = write mode | a = append | e = edit
prefFile.open('w');
prefFile.write(docPath.fsName);
prefFile.close();
prefFile.encoding = 'UTF-8';
// LineFeed options
// prefFile.lineFeed = "Unix";
// prefFile.lineFeed = "Windows";
// prefFile.lineFeed = "Macintosh";
//alert('Preference file path:' + '\r' + docPath.fsName);
// JPEG S4W Options
function SaveForWeb(saveFileJPEG) {
var sfwOptions = new ExportOptionsSaveForWeb();
sfwOptions.format = SaveDocumentType.JPEG;
sfwOptions.includeProfile = true;
sfwOptions.optimized = true;
sfwOptions.quality = 50;
doc.exportDocument(saveFileJPEG, ExportType.SAVEFORWEB, sfwOptions);
}
// File path & naming
var saveFileJPEG = new File(docPath + '/' + docNameOutput + '.jpg');
// Confirm overwrite - name validation is dependent on SFW filename compatibility settings
if (saveFileJPEG.exists) {
// true = 'No' as default active button
if (!confirm("File exists, overwrite: Yes or No?", true))
// Optional - swap the throw alert for " throw null; " to remove the alert message
throw alert("Script cancelled!");
}
// Conditional colour space handling
// Check for untagged image
if (doc.colorProfileType === ColorProfile.NONE) {
// alert("Untagged");
// Call the function
sRGBprocessing();
// Check for any profile name which does not contain sRGB
} else if (doc.colorProfileName.match(/\bsRGB\b/) === null) {
// else if (doc.colorProfileName !== "sRGB IEC61966-2.1")
// alert("sRGB = False");
// Call the function
sRGBprocessing();
// Check for any profile name which contains sRGB
} else if (doc.colorProfileName.match(/\bsRGB\b/) !== null) {
// else if (doc.colorProfileName === "sRGB IEC61966-2.1")
// alert("sRGB = True");
// Export
SaveForWeb(saveFileJPEG);
} else { }
function sRGBprocessing() {
// Convert to profile - sRGB (profile, intent, BPC, dither)
doc.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
// Export
SaveForWeb(saveFileJPEG);
// Delete convert to sRGB history step
deleteLastHistoryStep();
function deleteLastHistoryStep() {
var iddelete = stringIDToTypeID("delete");
var desc1497 = new ActionDescriptor();
var idnull = stringIDToTypeID("null");
var ref22 = new ActionReference();
var idhistoryState = stringIDToTypeID("historyState");
var idordinal = stringIDToTypeID("ordinal");
var idlast = stringIDToTypeID("last");
ref22.putEnumerated(idhistoryState, idordinal, idlast);
desc1497.putReference(idnull, ref22);
executeAction(iddelete, desc1497, DialogModes.NO);
}
}
// As this is a template, remove photoshop:DocumentAncestors metadata that may build up and bloat the file
// https://prepression.blogspot.com/2017/06/metadata-bloat-photoshopdocumentancestors.html
deleteDocumentAncestorsMetadata();
function deleteDocumentAncestorsMetadata() {
// https://forums.adobe.com/message/8456985#8456985
if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
xmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "DocumentAncestors");
app.activeDocument.xmpMetadata.rawData = xmp.serialize();
}
// Optional end of script message, comment out or remove as required
alert(docNameOutput + '.jpg' + '\r' + 'Saved to:' + '\r\r' + docPath.fsName);
// Optional end of script alert, comment out or remove as required
// app.beep();
} else {
alert('You must have a document open to use this script!');
}
Copy link to clipboard
Copied
Awesome! Thanks again, Stephen!
Copy link to clipboard
Copied
So, did the last save location written and read from the file work?
Copy link to clipboard
Copied
I haven't checked that yet, because I'd need to close PS to activate the script and I'm in the middle of work.
One anomaly I have discovered.
When I use another template that saves to a different image size, and use the save4web script, it will default to that image size of that template going forward.
This is with the 1.1 script.
Is there a way to have it not do that and just respect the image size of whatever template is being used, when saving?
Copy link to clipboard
Copied
One can use the File / Scripts/ Browse option to run an adhoc script without installing the script. This is less convenient as a keyboard shortcut can't be mapped, but it is possible to record into an action.
As for the sizing there is nothing explicitly set in the script to change the pixel dimensions of the active image.
What happens if you S4W manually, is the size different?
Copy link to clipboard
Copied
I just tested:
Doc 1 = 1000x1000px, the script saved the same px dimension file
Doc 2 = 500x760px, the script saved the same px dimension file
Doc 3 = 2000x200px, the script saved the same px dimension file
I obviously can't duplicate this issue.
Perhaps a 3rd party can try the 1.1 version of the script and report back on whether it remembers the last save location and whether the original image sizes are being changed.