Copy link to clipboard
Copied
Hello, not sure if it's correct group but maybe someone know how exactly Photoshop 4-chars commands work.
I'm trying to find correct script to create new document from specific layer by id. But it always uses active layer. Is there any way to change the script to fit my requirements?
var mkId = charIDToTypeID("Mk "),
action = new ActionDescriptor(),
nullId = charIDToTypeID("null"),
actionRef = new ActionReference(),
docId = charIDToTypeID("Dcmn");
actionRef.putClass(docId),
action.putReference(nullId, actionRef);
var nmId = charIDToTypeID("Nm ");
action.putString(nmId, "My new document");
var usingId = charIDToTypeID("Usng"),
// trying to set target layer, but it doesn't work
c = new ActionReference();
c.putIndex( charIDToTypeID( "Lyr " ), 2);
action.putReference(usingId, c);
var versionId = charIDToTypeID("Vrsn");
action.putInteger(versionId, 5),
executeAction(mkId, action, DialogModes.NO);
Copy link to clipboard
Copied
Duplicate layer duplicate the Active layer set the layer you want to create a new document with as the Active layer before using the code.
function NewDocFromActiveLayer(LayerName,DocName) {
var idMk = charIDToTypeID( "Mk " );
var desc54 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref9 = new ActionReference();
var idDcmn = charIDToTypeID( "Dcmn" );
ref9.putClass( idDcmn );
desc54.putReference( idnull, ref9 );
var idNm = charIDToTypeID( "Nm " );
desc54.putString( idNm, DocName );
var idUsng = charIDToTypeID( "Usng" );
var ref10 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref10.putEnumerated( idLyr, idOrdn, idTrgt );
desc54.putReference( idUsng, ref10 );
var idLyrN = charIDToTypeID( "LyrN" );
desc54.putString( idLyrN, LayerName );
var idVrsn = charIDToTypeID( "Vrsn" );
desc54.putInteger( idVrsn, 5 );
executeAction( idMk, desc54, DialogModes.NO );
}
NewDocFromActiveLayer("llll","xxx");
Copy link to clipboard
Copied
Thanks for reply! Really the point is to NOT use active layer but use layer reference instead.
Create new doc using active layer is exactly how the code I shared works
Copy link to clipboard
Copied
I do not understand what is a layer reference. If it is a layer in the document save the active layers in a variable set the docment's active layer the layer reference duplicate the active layer into a new document then restore the document active layer to the one you saved before. If you want to us a layer you normally need to target the layer first. Many Photoshop tools and commands work on or with the active layer. If you look at the duplicate layer dialog the source layer can not be set it is the current targeted active layer. You have to target the correct document not the new document you opened that became the Acrive document set a varable Doc to the original source document first. Set Doc.acticeLayer = the old saved active layer.
Copy link to clipboard
Copied
If I use active layer it's not just changing layer currently selected by but also changing source document by expanding layers tree.
Let me provide an example regarding layer reference. There are a lot of sample scripts how to define if layer is artboard by getting property of that layer. This script can be executed using active layer but also there is an option to set specific layer using following command:
ref.putIndex( charIDToTypeID( "Lyr " ), current.itemIndex );
Here I'm trying to do pretty the same but I can't find what exactly should be set for "Using" command.
I suppose if script looks like this
var idUsng = charIDToTypeID( "Usng" );
var ref10 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref10.putEnumerated( idLyr, idOrdn, idTrgt );
desc54.putReference( idUsng, ref10 );
then I can use some other parameters to use not active but specific layer by id, index or name.
Copy link to clipboard
Copied
I do not understand what you mean by expanding the layer tree. Is that the Layers palette? If you do not want to activate the reference layer. You could get the documents layers to get all the layers and then find the reference layer. Open a new document the with the same size and resolution as the current document. Add a new artlayer. Set the new layer to be the same as reference layer. Then delete the new document's bottom layer. Could be done using DOM code action manager code would not be needed.
Copy link to clipboard
Copied
Sorry, could you please provide some details how can I create new layer and make it the same as reference layer (or layers section). I wrote small script but it doesn't work:
function main() {
var doc = app.activeDocument;
var lr = doc.activeLayer; // replace it with getTargetLayer(doc, id);
var newDoc = app.documents.add(doc.width, doc.height);
var newLr = newDoc.artLayers.add();
newDoc.activeLayer = lr; // this code causes exception
}
Copy link to clipboard
Copied
Sorry I only hack at Photoshop scripting and do not know javascript.. It seemed logical that you would be able to open a new document the correct size and resolution. Add a new layer and set it with an artlayer from the original document. However it look like Adobe does not allow that. I get a error or the new layer added does not get set with an assignment statement using the atrlayer object from the original and remains empty.
function main() {
var doc = app.activeDocument;
var lr = doc.activeLayer; // replace it with getTargetLayer(doc, id);
var newDoc = app.documents.add(doc.width, doc.height, doc.resolution);
var newLr = newDoc.artLayers.add();
// newDoc.activeLayer = lr;
// newLr = lr; // nothing get set no error message
newLr.kind = LayerKind.TEXT;
textColor = new SolidColor;
textColor.rgb.red = 255;
textColor.rgb.green = 0;
textColor.rgb.blue = 0;
newLr.textItem.color = textColor;
newLr.textItem.font = "ArialMT";
newLr.blendMode = BlendMode.NORMAL;
newLr.textItem.fauxBold = false;
newLr.textItem.fauxItalic = false;
newLr.textItem.underline = UnderlineType.UNDERLINEOFF;
newLr.textItem.capitalization = TextCase.NORMAL;
newLr.textItem.antiAliasMethod = AntiAlias.SHARP;
newLr.textItem.size = 20;
newLr.textItem.position = Array(40, 40 );
newLr.textItem.contents = "text";
newLr = lr; // nothing get set no error message
}
main();
Copy link to clipboard
Copied
Thanks for details but it seems to be pretty not trivial solution as we should know all possible properties for all kinds of layers. E.g. what if we need to create new document from layers section with smart objects, masks and fx layers?
I still believe that solution should be related to passing correct set of parameters for "Usng" action. As this action applies second parameter as target for Using then should exist another valid value which will reference to the specific layer.
Copy link to clipboard
Copied
You will not get what you want!
The nearest you will get is something like...
dupLayerToNewFile(27,"My new document");
function dupLayerToNewFile(ID,filename) {
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), ID);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
desc = new ActionDescriptor();
ref = new ActionReference();
ref.putClass( charIDToTypeID("Dcmn") );
desc.putReference( charIDToTypeID("null"), ref );
desc.putString( charIDToTypeID("Nm "), filename );
var ref2 = new ActionReference();
//This line does not work!!!!!!!!!!!
//It still wants the selected layer(s)
ref2.putIdentifier(charIDToTypeID("Lyr "), ID);
desc.putReference( charIDToTypeID("Usng"), ref2 );
desc.putInteger( charIDToTypeID("Vrsn"), 5 );
executeAction( charIDToTypeID("Mk "), desc, DialogModes.NO );
};
This selects the layer then duplicates it.
By the way you said in your fist statement you wanted to use the layer ID this is what this function uses, but you were using the layers Index. there is a big difference.
The layer ID is unique the Index can and will change if you delete/move/add layer(s)
Copy link to clipboard
Copied
I'm trying not to use active layer (or select layer) is it changes source document by expanding layers tree in Layers pane.
But if it's technically impossible then I should find some workarounds. Thanks for help!