Photoshop Scripts #1
Working in Photoshop over time, I came up with a few scripts to make my work easier. I’ve attached them all here in case other people can use them or at least learn from them – personally, examples helped me the most while learning how to code scripts.
Most of these I have assigned to keyboard shortcuts which really speeds things up.
Enjoy!
![]() |
CutToGuidesXY.jsx |
Cut the image into tiles defined by the guides. The code first reads all the guidelines in the document, then duplicates it, merges all the visible layers and crops the image to match the first tile. Once the file is saved, the duplicate document is closed without saving and a new copy is made for the next tile and so on.
[expand title=”Click here to see the actual code”]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
// CutToGuide // Cuts the current file according to guides (both horizontal and vertical) and save each one of the tiles var doc = app.activeDocument; var newDoc; var savedRuler = app.preferences.rulerUnits; app.preferences.rulerUnits = Units.PIXELS; var w = doc.width; var h = doc.height; var guidelines = []; var selectionArray = []; //////////////////////////////////////////////////////////////////////////////////////////////// function getHorizontalGuides(doc) { var i, l; var g, d; var guidelines = []; //add the first line to crop - the top of the canvas guidelines[0] = 0; for (i=0,l=doc.guides.length; i<l; i++) { g = doc.guides[i]; if (g.direction === Direction.HORIZONTAL) { guidelines.push(parseFloat(g.coordinate)+0); // +0 trick makes sure the variable acts as a float } } //add the last line to crop - the bottom of the canvas guidelines.push(h); guidelines.sort(SortLowToHigh); return guidelines; } function getVerticalGuides(doc) { var i, l; var g, d; var guidelines = []; //add the first line to crop - the top of the canvas guidelines[0] = 0; for (i=0,l=doc.guides.length; i<l; i++) { g = doc.guides[i]; if (g.direction === Direction.VERTICAL) { guidelines.push(parseFloat(g.coordinate)+0); // +0 trick makes sure the variable acts as a float } } //add the last line to crop - the bottom of the canvas guidelines.push(w); guidelines.sort(SortLowToHigh); return guidelines; } //////////////////////////////////////////////////////////////////////////////////////////////// function savePNG(index, doc, savePath, hires) { var opts, file, resSuffix; opts = new ExportOptionsSaveForWeb(); opts.format = SaveDocumentType.PNG; opts.PNG8 = false; opts.quality = 100; pngFile = new File(savePath + "/" + "image" + index + ".png"); app.activeDocument.exportDocument(pngFile, ExportType.SAVEFORWEB, opts); } //////////////////////////////////////////////////////////////////////////////////////////////// function SortLowToHigh(a, b) { var c = a-b; return c; } //////////////////////////////////////////////////////////////////////////////////////////////// guidelinesX = getVerticalGuides(doc); guidelinesY = getHorizontalGuides(doc); alert(guidelinesX); alert(guidelinesY); // CODE FOR PUBLISHING USING DUPLICATE IMAGE // for each row, run the loop to cut each column for (i=0; i for (j=0; j1) { newDoc.mergeVisibleLayers(); } // crop the document to the bounds defined by the guidelines newDoc.crop(new Array(guidelinesX[j],guidelinesY[i],guidelinesX[j+1],guidelinesY[i+1])); //crop(bounds = array: left top right bottom) // save the file // this is where you change the naming if you wish, instead of 'i+1' you could use anything you want savePNG(i+1, newDoc, doc.path, true); newDoc.close(SaveOptions.DONOTSAVECHANGES); } } app.preferences.rulerUnits = savedRuler; |
[/expand]
![]() |
GenerateAppStoreScreenshots.jsx |
This script helps generate all the required sizes that Apple needs for the Appstore submission of any app. The code duplicates the document, flattens it, crops it to the right size (with the anchor in the center of the image) and then saves the file. Repeat for all screenshots. This script requires a certain specific size of the original document, so that enough information is available and no actual resampling takes place.
[expand title=”Click here to see the actual code”]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
// Generate Appstore Screenshot sizes // from a 1280 x 720 px starting image // Save the current preferences var startRulerUnits = app.preferences.rulerUnits var startTypeUnits = app.preferences.typeUnits var startDisplayDialogs = app.displayDialogs // Set Adobe Photoshop CC 2014 to use pixels and display no dialogs app.preferences.rulerUnits = Units.PIXELS app.preferences.typeUnits = TypeUnits.PIXELS app.displayDialogs = DialogModes.NO var doc = app.activeDocument; var docName = doc.name; var launchName = ["iPhone-960x640", "iPhone-1136x640", "iPhone-1334x750", "iPhone-2208x1242", "iPad-2048x1536", "iPad-1024x768"]; var launchWidth = [960, 1136, 1334, 2208, 2048, 1024]; var launchHeight = [640, 640, 750, 1242, 1536, 768]; // var launchRotation = [0, 180, 180, 180, 180, 0, 0, 0, 0, 90, 90, 90, 90, 90, 90]; var w = doc.width; var h = doc.height; var docPath = decodeURI(doc.path); var PNGOptions = new PNGSaveOptions; //strip the extension var finalDotPosition = docName.lastIndexOf( "." ) ; if ( finalDotPosition > -1 ) { docName = docName.substr(0, finalDotPosition); } if ((w == 1280 && h == 720) || (w == 2560 && h == 1440)) { for(var i=0; i<launchName.length; i++) { doc.duplicate(); //resizeImage(width, height, rezolution) app.activeDocument.resizeImage(null, launchHeight[i], null, ResampleMethod.BILINEAR); app.activeDocument.resizeCanvas(launchWidth[i], null, AnchorPosition.MIDDLECENTER); // app.activeDocument.rotateCanvas(launchRotation[i]); var saveName = new File(docPath + '/' + docName + "_" + launchName[i] + '.png'); //alert(docPath); app.activeDocument.saveAs(saveName, PNGOptions, 10); app.activeDocument.close(SaveOptions.DONOTSAVECHANGES); } } else { alert("Image must be 1280x720 or 2560x1440 px! Please resize and run the script again."); } // app.activeDocument.resizeCanvas (w, h+1, AnchorPosition.TOPCENTER); // Reset the application preferences app.preferences.rulerUnits = startRulerUnits app.preferences.typeUnits = startTypeUnits app.displayDialogs = startDisplayDialogs |
[/expand]
![]() |
GenerateiOSLaunchImage.jsx |
Pretty much the same as above, only this time the script generates all the launch images for an app (all aspect ratios and sizes that Apple requires) and it also rotates the images to make sure the correct orientation is achieved.
[expand title=”Click here to see the actual code”]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
// Generate iOS launch images // from a 2208 x 2208 px starting image // Save the current preferences var startRulerUnits = app.preferences.rulerUnits var startTypeUnits = app.preferences.typeUnits var startDisplayDialogs = app.displayDialogs // Set Adobe Photoshop CC 2014 to use pixels and display no dialogs app.preferences.rulerUnits = Units.PIXELS app.preferences.typeUnits = TypeUnits.PIXELS app.displayDialogs = DialogModes.NO var doc = app.activeDocument; var docName = doc.name; var launchName = ["Default-568h@2x(640x1136)", "Default-LandscapeLeft@2x~iPad(2048x1496)", "Default-LandscapeLeft@2x~iPad(2048x1536)", "Default-LandscapeLeft~iPad(1024x748)", "Default-LandscapeLeft~iPad(1024x768)", "Default-LandscapeRight@2x~iPad(2048x1496)", "Default-LandscapeRight@2x~iPad(2048x1536)", "Default-LandscapeRight~iPad(1024x748)", "Default-LandscapeRight~iPad(1024x768)", "Default-Portrait@2x~iPad(1536x2008)", "Default-Portrait@2x~iPad(1536x2048)", "Default-Portrait~iPad(768x1004)", "Default-Portrait~iPad(768x1024)", "Default(320x480)", "Default@2x(640x960)"]; var launchWidth = [1136, 2048, 2048, 1024, 1024, 2048, 2048, 1024, 1024, 2008, 2048, 1004, 1024, 480, 960]; var launchHeight = [640, 1496, 1536, 748, 768, 1496, 1536, 748, 768, 1536, 1536, 768, 768, 320, 640]; var launchRotation = [90, 180, 180, 180, 180, 0, 0, 0, 0, 90, 90, 90, 90, 90, 90]; var w = doc.width; var h = doc.height; var docPath = decodeURI(doc.path); var PNGOptions = new PNGSaveOptions; if (w == 2208 && h == 2208) { for(var i=0; i<15; i++){ doc.duplicate(); //resizeImage(width, height, rezolution) app.activeDocument.resizeImage(launchWidth[i], null, null, ResampleMethod.BILINEAR); app.activeDocument.resizeCanvas(null, launchHeight[i], AnchorPosition.MIDDLECENTER); app.activeDocument.rotateCanvas(launchRotation[i]); var saveName = new File(docPath + '/' + launchName[i] + '.png'); //alert(docPath); app.activeDocument.saveAs(saveName, PNGOptions, 10); app.activeDocument.close(SaveOptions.DONOTSAVECHANGES); } } else { alert("Both width and height must be 2208px! Please resize and run the script again."); } // app.activeDocument.resizeCanvas (w, h+1, AnchorPosition.TOPCENTER); // Reset the application preferences app.preferences.rulerUnits = startRulerUnits app.preferences.typeUnits = startTypeUnits app.displayDialogs = startDisplayDialogs |
[/expand]
![]() |
InsertHorizontalGuide.jsx |
At some point I had to work on several documents that required me to add a huge number of guides in specific places. Unfortunately, there’s no command in PS to add a guide where the mouse is, so I couldn’t create an action. Even worse, there no way to expose the mouse position and actually insert a guide when a key is pressed via script. So my workaround was to insert horizontal guides at the top and bottom coordinates of a selection. This turned out to be even better, as I can adjust the selection while I’m making it and then, at the press of a button, I can create 2 guides at once.
[expand title=”Click here to see the actual code”]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// InsertHorizontalGuide // Insert a horizontal guide at the top and bottom of the selection var savedRuler = app.preferences.rulerUnits; app.preferences.rulerUnits = Units.PIXELS; var guides = app.activeDocument.guides; var s = app.activeDocument.selection.bounds //////////////////////////////////////////////////////////////////////////////////////////////// guides.add(Direction.HORIZONTAL, s[1]); guides.add(Direction.HORIZONTAL, s[3]); app.preferences.rulerUnits = savedRuler; |
[/expand]
![]() |
InsertVerticalGuide.jsx |
Same as above, only this time the script generates vertical guides at the left and right edges of the selection.
[expand title=”Click here to see the actual code”]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// InsertHorizontalGuide // Insert a horizontal guide at the top and bottom of the selection var savedRuler = app.preferences.rulerUnits; app.preferences.rulerUnits = Units.PIXELS; var guides = app.activeDocument.guides; var s = app.activeDocument.selection.bounds //////////////////////////////////////////////////////////////////////////////////////////////// guides.add(Direction.VERTICAL, s[0]); guides.add(Direction.VERTICAL, s[2]); app.preferences.rulerUnits = savedRuler; |
[/expand]
![]() |
ResizeEven.jsx |
When creating images for iOS apps, you need to make sure you create both retina (@2x) assets (even @3x recently) and normal sized ones for non-retina devices. Obviously this means creating the assets @2x to start with and resizing down. However, not all assets have an even number of pixels as their height, so this script checks that and adds a 1px row if the height is odd-numbered. Then the script is used as part of an batch of actions (cut, resize, save as etc). I’ve used add 1 row since my assets had a transparent background. However, if yours have a full background, I recommend using -1 pixels at the bottom instead of +1.
[expand title=”Click here to see the actual code”]
1 2 3 4 5 6 7 8 9 10 11 |
// Resize Even // checks the canvas and adds 1px to the height is the file isn't even in height. // used for making sure the images @2x are even so that the low res obtained by halving them is perfect // var savedRuler = app.preferences.rulerUnits; app.preferences.rulerUnits = Units.PIXELS; var w = app.activeDocument.width; var h = app.activeDocument.height; if(h % 2 != 0) app.activeDocument.resizeCanvas (w, h+1, AnchorPosition.TOPCENTER); app.preferences.rulerUnits = savedRuler; |
[/expand]
![]() |
ToggleVisibilityInGroup.jsx |
I made this script while working with multiple groups containing animation frames inside. Often I would need to have just one of the frames visible (and the PS way of ALT+click on the eye of the layer doesn’t work, because it renders all the other groups and layers in the document invisible, which is not what I wanted). So this script lets you make all the layers inside a group invisible, except the selected one. After that, since it’s a toggle script, just select one of the invisible layers inside the group and run the script again to turn them all on again.
[expand title=”Click here to see the actual code”]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
// ToggleVisibilityInGroup // If the selected layer is visible, it makes it the only one visible in the group and hides the rest // If the selected layer is invisible, it makes everything inside the group visible // var doc = app.activeDocument; // the current selected layer var theLayer = activeDocument.activeLayer; // the group inside which the selected layer resides var theParent = theLayer.parent; var savedRuler = app.preferences.rulerUnits; app.preferences.rulerUnits = Units.PIXELS; // var w = doc.width; // var h = doc.height; //////////////////////////////////////////////////////////////////////////////////////////////// // run the code only if the parent layer is a group if (theParent.typename == 'LayerSet') { if (theLayer.visible == 1) { for (var i=0; i<theParent.layers.length; i++) { theParent.layers[i].visible = 0; } theLayer.visible = 1; } else { for (var i=0; i<theParent.layers.length; i++) { theParent.layers[i].visible = 1; } } } app.preferences.rulerUnits = savedRuler; |