Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tannerhodges/2ac807fd44d032667c3e341bacebe867 to your computer and use it in GitHub Desktop.
Save tannerhodges/2ac807fd44d032667c3e341bacebe867 to your computer and use it in GitHub Desktop.
Photoshop script to save multiple sizes of an image to the desktop
/* Resize and Save to Desktop */
/* @@@BUILDINFO@@@ Resize and Save to Desktop.jsx 0.1.0 */
/* jshint ignore:start */
// Enable double clicking from Macintosh Finder or Windows Explorer
#target photoshop
/* jshint ignore:end */
/*
Automatically use local translations where available
@see "Enabling automatic localization" on page 104 of https://www.adobe.com/content/dam/Adobe/en/devnet/scripting/pdfs/javascript_tools_guide.pdf
*/
$.localize = true;
/*
Debug (uncomment to launch debugger)
*/
// $.level = 1; // 0-2 (0:disable, 1:break on error, 2:break at beginning)
// debugger;
// ------------------------------
// Global variables
// ------------------------------
/**
* Version
* @type {Number}
*/
gVersion = '0.1.0';
/**
* Export sizes.
* @type {Array}
*/
gExportSizes = [
{ 'width': 1920, 'suffix': '@2x' },
{ 'width': 1260, 'suffix': 's@2x' },
{ 'width': 938, 'suffix': 'm@2x' },
{ 'width': 600, 'suffix': 'x@2x' }
];
/**
* Params.
* @type {Object}
*/
gParams = {
'source' : '',
'quality' : 50,
};
// Local translations
strMustUse = localize('$$$/JavaScript/ResizeAndSaveToDesktop/MustUse=Sorry, you need Photoshop CS2 or later to run this script.');
strNoOpenFiles = localize('$$$/JavaScript/ResizeAndSaveToDesktop/NoOpenFiles=Sorry, I can’t find any open documents.\nTry opening an image first, then run this script again.');
strCannotWriteToFolder = localize('$$$/JavaScript/ResizeAndSaveToDesktop/CannotWriteToFolder=Whoops! I’m having trouble saving files to your desktop.\nDouble check that your account has permission to write files to ');
gScriptResult = undefined;
gFoundFileToProcess = false;
// Remember dialog modes
gSaveDialogMode = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
// ------------------------------
// Helpers - OS
// ------------------------------
/**
* Require at least Photoshop CS2 (9.0).
* @see https://en.wikipedia.org/wiki/Adobe_Photoshop_version_history
* @return {void}
*/
function CheckVersion() {
var numberArray = version.split('.');
if (numberArray[0] < 9) {
// alert(strMustUse);
throw strMustUse;
}
}
/**
* Require at least Photoshop CS2 (9.0).
* @see https://en.wikipedia.org/wiki/Adobe_Photoshop_version_history
* @return {void}
*/
function CheckOpenDocument() {
try {
var x = app.activeDocument;
} catch(e) {
// alert(strNoOpenFiles);
throw strNoOpenFiles;
}
}
// ------------------------------
// Helpers - Files and folders
// ------------------------------
/**
* Is folder writable?
* @param {String} folder
* @return {Boolean}
*/
function IsFolderWritable(folder) {
var isWritable = false;
var f = File(folder + 'deleteme.txt');
if (f.open('w', 'TEXT', '????')) {
if (f.write('delete me')) {
if (f.close()) {
if (f.remove()) {
isWritable = true;
}
}
}
}
return isWritable;
}
/**
* Save for web JPG.
* @see https://forums.adobe.com/message/4239152#4239152
* @see Page 108 of http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/photoshop/pdfs/photoshop_cs5_javascript_ref.pdf
* @param {String} fileName
* @param {Number} quality
* @return {void}
*/
function SaveForWebJPG(fileName, quality) {
var sfwOptions = new ExportOptionsSaveForWeb();
sfwOptions.format = SaveDocumentType.JPEG;
sfwOptions.includeProfile = true;
sfwOptions.interlaced = false;
sfwOptions.optimized = true;
sfwOptions.quality = quality;
app.activeDocument.exportDocument(File(fileName), ExportType.SAVEFORWEB, sfwOptions);
}
// ------------------------------
// Helpers - Image Manipulation
// ------------------------------
/**
* Remove alpha channels.
* @return {void}
*/
function RemoveAlphaChannels() {
var channels = app.activeDocument.channels;
var channelCount = channels.length - 1;
while (channels[channelCount].kind != ChannelType.COMPONENT) {
channels[channelCount].remove();
channelCount--;
}
}
/**
* Set curront document to sRGB profile.
* @return {void}
*/
function ConvertTosRGBProfile() {
app.activeDocument.convertProfile('sRGB IEC61966-2.1', Intent.RELATIVECOLORIMETRIC, true, true);
}
/**
* Resize current document (in pixels).
* @param {Number} width
* @param {Number} height
* @return {Boolean}
*/
function ResizeImage(width, height) {
var startRulerUnits = app.displayDialogs;
var startTypeUnits = app.preferences.rulerUnits;
var startDisplayDialogs = app.preferences.typeUnits;
try {
app.displayDialogs = DialogModes.NO;
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits = TypeUnits.PIXELS;
app.activeDocument.resizeImage(width, height, 72, ResampleMethod.BICUBIC);
app.displayDialogs = startDisplayDialogs;
app.preferences.rulerUnits = startRulerUnits;
app.preferences.typeUnits = startTypeUnits;
} catch (e) {
return false;
}
// Reset
if (startDisplayDialogs !== undefined) { app.displayDialogs = startDisplayDialogs; }
if (startRulerUnits !== undefined) { app.preferences.rulerUnits = startRulerUnits; }
if (startTypeUnits !== undefined) { app.preferences.typeUnits = startTypeUnits; }
return true;
}
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
/**
* Save file as JPEG.
* @param {String} fileName
* @param {String} folderLocation
*/
function SaveFile(fileName, folderLocation) {
var lastDot = fileName.lastIndexOf('.');
if (lastDot == -1) {
lastDot = fileName.length;
}
var fileNameNoPath = fileName.substr(0, lastDot);
var lastSlash = fileNameNoPath.lastIndexOf('/');
fileNameNoPath = fileNameNoPath.substr(lastSlash + 1, fileNameNoPath.length);
var filePathNoName = fileName.substr(0, lastSlash);
var subFolderText;
var historyState;
// Save JPEG
subFolderText = folderLocation;
subFolderText += '/';
Folder(subFolderText).create();
historyState = app.activeDocument.activeHistoryState;
app.activeDocument.flatten();
app.activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
RemoveAlphaChannels();
ConvertTosRGBProfile();
if (!IsFolderWritable(subFolderText)) {
alert(strCannotWriteToFolder + File(subFolderText).fsName);
} else {
var fileNameNoPathClean = fileNameNoPath.replace(/[:\/\\*\?\"<>\|]/g, '-');
var newFileName;
for (var i = 0; i < gExportSizes.length; i++) {
// Resize
ResizeImage(gExportSizes[i].width);
// Save
newFileName = subFolderText + fileNameNoPathClean + gExportSizes[i].suffix + '.jpg';
SaveForWebJPG(newFileName, gParams.quality);
}
}
app.activeDocument.activeHistoryState = historyState;
}
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
try {
CheckVersion();
CheckOpenDocument();
app.bringToFront(); // In case we double clicked the file
var inputFiles = [app.activeDocument];
var fileName;
for (var i = 0; i < inputFiles.length; i++) {
try {
fileName = inputFiles[i].fullName.absoluteURI.toString();
gParams.source = inputFiles[i].path.toString();
gParams.source = Folder(gParams.source).absoluteURI.toString();
} catch (e) {
if (e.number !== 8103) {
throw e;
}
}
try {
app.activeDocument = inputFiles[i];
app.activeDocument.duplicate();
var docName = app.activeDocument.name.replace(/(-? ?copy)+$/, '');
SaveFile(fileName || docName, Folder.desktop.fsName);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
gFoundFileToProcess = true;
} catch (e) {
// alert(e + ': ' + e.line);
alert(e);
}
}
if (!gFoundFileToProcess) {
alert(strNoOpenFiles);
}
$.gc(); // Garbage collect to avoid crashing the app on quit
} catch (e) {
if (e.number != 8007) { // Don't report error on user cancel
// alert(e + ': ' + e.line);
alert(e);
}
gScriptResult = 'cancel'; // Return 'cancel' to prevent the Actions palette from recording our script
}
// Restore dialog modes
app.displayDialogs = gSaveDialogMode;
// Important: Script result must be the last execution
/* jshint ignore:start */
gScriptResult;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment