10 Replies Latest reply on Aug 29, 2017 1:25 PM by G_Drey_V

    New document from layer

    G_Drey_V Level 1

      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);

        • 1. Re: New document from layer
          JJMack Most Valuable Participant

          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");

          • 2. Re: New document from layer
            G_Drey_V Level 1

            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

            • 3. Re: New document from layer
              JJMack Most Valuable Participant

              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.

              Capture.jpg

              • 4. Re: New document from layer
                G_Drey_V Level 1

                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.

                • 5. Re: New document from layer
                  JJMack Most Valuable Participant

                  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.

                  • 6. Re: New document from layer
                    G_Drey_V Level 1

                    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 

                    }

                    • 7. Re: New document from layer
                      JJMack Most Valuable Participant

                      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.

                       

                      Capture.jpg

                      Capture.jpg

                       

                       

                      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();

                      • 8. Re: New document from layer
                        G_Drey_V Level 1

                        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.

                        • 9. Re: New document from layer
                          SuperMerlin Level 5

                          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)

                          • 10. Re: New document from layer
                            G_Drey_V Level 1

                            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!