I have a doc with about 400 layers in it, and another layer that is a modified flattened version of those layers on top (so that only that is visible). My goal is to simplify saving the pieces of the flattened version in the same shape/size as the original pieces.
I’m doing it manually by ctrl-clicking the layer I want, copying its layer name to the clipboard, cropping the image to the selection, exporting as png, pasting the layer name into the dialogue and saving, and then undoing my crop in the history before moving on to the next layer.
I’m not very familiar with scripting languages, but I’ve managed to smoosh together three scripts that i found with some digging (see below).
So far, what it seems to do is load the selection, open the cropped version as a new document, copy the layer name to the clipboard, and then open the export as png dialogue, wait for input, and close the new doc after saving.
Where I’ve hit a snag is that the layer name should be from the original document, and the process of opening the crop as a new document overwrites the clipboard if I put it before that point – and then I haven’t figured out how to paste what’s in the clipboard anyway.
Is there…
- an easier way to script my above workflow?
- a way to just crop the file instead of pasting the crop in a new doc?
- a way to carry over the layer name to the cropped doc, if not?
- a quick and easy paste-the-clipboard thing I can add to the end of what I have?
app.displayDialogs = DialogModes.NO;
var id1268 = charIDToTypeID( "setd" );
var desc307 = new ActionDescriptor();
var id1269 = charIDToTypeID( "null" );
var ref257 = new ActionReference();
var id1270 = charIDToTypeID( "Chnl" );
var id1271 = charIDToTypeID( "fsel" );
ref257.putProperty( id1270, id1271 );
desc307.putReference( id1269, ref257 );
var id1272 = charIDToTypeID( "T " );
var ref258 = new ActionReference();
var id1273 = charIDToTypeID( "Chnl" );
var id1274 = charIDToTypeID( "Chnl" );
var id1275 = charIDToTypeID( "Trsp" );
ref258.putEnumerated( id1273, id1274, id1275 );
desc307.putReference( id1272, ref258 );
executeAction( id1268, desc307, DialogModes.NO )
var pngSaveOptions = new PNGSaveOptions();
pngSaveOptions.compression = 9;
pngSaveOptions.interlaced = false;
var hasSelection;
var docRef;
var artLayer;
var width = app.activeDocument.width;
var height = app.activeDocument.height;
try {
hasSelection = !!app.activeDocument.selection.bounds;
} catch (err) {
hasSelection = false;
}
if (hasSelection) {
//copy merged
app.activeDocument.selection.copy(true);
//create new RGB document with transperant background
docRef = app.documents.add(width, height, 72, null, NewDocumentMode.RGB, DocumentFill.TRANSPARENT)
artLayer = docRef.paste();
//crop the image to pasted bounds
docRef.crop(artLayer.bounds);
} else {
docRef = app.activeDocument;
}
// Copy Active Layer Name to Clipboard.jsx
#target photoshop
var doc = activeDocument;
var aLayer = doc.activeLayer.name;
var d = new ActionDescriptor();
d.putString(stringIDToTypeID("textData"), aLayer);
executeAction(stringIDToTypeID("textToClipboard"), d, DialogModes.NO);
var file = File.saveDialog("Export as PNG to...");
if (file && ((file.exists && confirm("Overwrite " + file +"?")) || !file.exists)) {
docRef.saveAs(file, pngSaveOptions, !hasSelection, Extension.LOWERCASE);
if (hasSelection) {
docRef.close(SaveOptions.DONOTSAVECHANGES);
}
}
2
Answers
Here are a couple of code snippets that might help you. I’m not certain, but I think you might have two documents open to start with.
As for the clipboard – not sure what you’re trying to do.
The method used by the OP for saving,
File.saveDialog
, has a big brother known as saveDlg:The latter is used with a
File
instance, and will prefill the save field with any filepath you wish, foregoing any copy/paste clipboard voodoo. The method returns a newFile
object you can use to do the actual save when the save dialog returns, or null if canceled by the user, and handles the "overwrite file" prompt for you.If you save a reference to your initial document (or layer) before leaving that document, just use that to get the layer name when ready to save (
var layer
just above). Or, just name your new document the same as the layer it’s saving, and use the document name. Flip a coin.Here’s a modified version of your script that walks through all top-level layers (it doesn’t recurse into layersets), skipping the first layer. Save dialog is only shown if the file already exists; otherwise, it saves the cropped image as the layer name before closing the new doc and moving on to the next layer.