skip to Main Content

TL;DR – I want to use code to define a custom pattern from selection in Photoshop using scripting (Extendscript).

Here is the code I have so far:

    (function () {
      var doc = app.activeDocument;
      // I put 2 guides in the doc to easily get coords for this test
      var guides = doc.guides;
      var hGuide = guides[0].coordinate.value;
      var vGuide = guides[1].coordinate.value;
      // Select whole doc
      doc.selection.selectAll();
      var sel = doc.selection.bounds;
      // Get percentages so we can resize the selection
      var xVal = (hGuide / sel[2].value) * 100;
      var yVal = (vGuide / sel[3].value) * 100;
      doc.selection.resizeBoundary(xVal, yVal, AnchorPosition.TOPLEFT);
  
      cTID = function (s) { return app.charIDToTypeID(s); };
      sTID = function (s) { return app.stringIDToTypeID(s); };
      
      // This part is recorded from an ActionListener
      var desc1 = new ActionDescriptor();
      var ref1 = new ActionReference();
      ref1.putClass(cTID('Ptrn'));
      desc1.putReference(cTID('null'), ref1);
      var ref2 = new ActionReference();
      ref2.putProperty(cTID('Prpr'), sTID("selection"));
      ref2.putEnumerated(cTID('Dcmn'), cTID('Ordn'), cTID('Trgt'));
      desc1.putReference(cTID('Usng'), ref2);
      desc1.putString(cTID('Nm  '), "Leaves");
      app.executeAction(cTID('Mk  '), desc1, DialogModes.NO);
    })();

This is done manually, in the UI, by using a marquee tool to make a selection, then going to Edit > Define Pattern…, entering the name, then clicking ok.

I have recorded myself doing just that and have gotten an action script in Javascript from it, but when I run it, Extendscript tells me: "General Photoshop error occured. This functionality may not be available in this version of Photoshop."

I am not so skilled when it comes to using the ActionDescriptors and ActionReferences, so I would love some help in getting this to define a custom pattern.

Thank you in advance!

**EDIT:**The ActionScript code works when I manually make the selection, but when I use the above code to make the selection, it doesn’t work. Why would there be a difference, I wonder?

2

Answers


  1. Chosen as BEST ANSWER

    I am not sure what was going on with my setup, but when I used the Ps Javascript API to make a selection, the code broke. But when I used ActionScript to make the selection, it worked. Here are the two functions I have made to select and then make a pattern from the selection:

        function setSelection(top, left, bottom, right) {
          var desc1 = new ActionDescriptor();
          var ref1 = new ActionReference();
          ref1.putProperty(app.charIDToTypeID('Chnl'), app.stringIDToTypeID("selection"));
          desc1.putReference(app.charIDToTypeID('null'), ref1);
          var desc2 = new ActionDescriptor();
          desc2.putUnitDouble(app.charIDToTypeID('Top '), app.charIDToTypeID('#Pxl'), top);
          desc2.putUnitDouble(app.charIDToTypeID('Left'), app.charIDToTypeID('#Pxl'), left);
          desc2.putUnitDouble(app.charIDToTypeID('Btom'), app.charIDToTypeID('#Pxl'), bottom);
          desc2.putUnitDouble(app.charIDToTypeID('Rght'), app.charIDToTypeID('#Pxl'), right);
          desc1.putObject(app.charIDToTypeID('T   '), app.charIDToTypeID('Rctn'), desc2);
          executeAction(app.charIDToTypeID('setd'), desc1, DialogModes.NO);
        }
    
        function makePatternFromSelection(name) {
          var desc1 = new ActionDescriptor();
          var ref1 = new ActionReference();
          ref1.putClass(app.charIDToTypeID('Ptrn'));
          desc1.putReference(app.charIDToTypeID('null'), ref1);
          var ref2 = new ActionReference();
          ref2.putProperty(app.charIDToTypeID('Prpr'), app.stringIDToTypeID("selection"));
          ref2.putEnumerated(app.charIDToTypeID('Dcmn'), app.charIDToTypeID('Ordn'), app.charIDToTypeID('Trgt'));
          desc1.putReference(app.charIDToTypeID('Usng'), ref2);
          desc1.putString(app.charIDToTypeID('Nm  '), name);
          executeAction(app.charIDToTypeID('Mk  '), desc1, DialogModes.NO);
        }
    

  2. The code worked fine for me. However, things like this tend to crop up with new versions of Photoshop.

    This is a long shot, and not really an answer, but try replacing your ScriptListener code with the following:

    // =======================================================
    var idMk = charIDToTypeID( "Mk  " );
    var desc26 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
    var ref10 = new ActionReference();
    var idPtrn = charIDToTypeID( "Ptrn" );
    ref10.putClass( idPtrn );
    desc26.putReference( idnull, ref10 );
    var idUsng = charIDToTypeID( "Usng" );
    var ref11 = new ActionReference();
    var idPrpr = charIDToTypeID( "Prpr" );
    var idfsel = charIDToTypeID( "fsel" );
    ref11.putProperty( idPrpr, idfsel );
    var idDcmn = charIDToTypeID( "Dcmn" );
    var idOrdn = charIDToTypeID( "Ordn" );
    var idTrgt = charIDToTypeID( "Trgt" );
    ref11.putEnumerated( idDcmn, idOrdn, idTrgt );
    desc26.putReference( idUsng, ref11 );
    var idNm = charIDToTypeID( "Nm  " );
    desc26.putString( idNm, "Leaves" );
    executeAction( idMk, desc26, DialogModes.NO );
    

    Also, you might want to pass a string as a parameter to your function as all the patterns created are going to be called "leaves"

    var myPatternName = "geometric pattern 4"
    desc26.putString( idNm, myPatternName ); // was "Leaves"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search