• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Draw a pen path, then a script to select/copy and close activeDocument

Enthusiast ,
Aug 29, 2011 Aug 29, 2011

Copy link to clipboard

Copied

Is this possible?

I do this step 90 times every day:

Select a image area drawing a pen path zone, and copying it to the clipboard.

Then close without save.

Then I use the selection on clipboard to paste it on the previous opened image.

P.S. I use paths because I need to have a more accurate and precise curves.

TOPICS
Actions and scripting

Views

2.1K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Community Expert ,
Aug 29, 2011 Aug 29, 2011

Copy link to clipboard

Copied

I don’t quite understand why you need to create the Path on a separate document – are those two completely different images?

Copy/Pasting seems to provide a problem if the documents are different sizes … maybe one should instead collect the pathPoint-info and create the path anew in the other document.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 30, 2011 Aug 30, 2011

Copy link to clipboard

Copied

Does this help?

// get active path, close document without saving, create path;

// 2011, use it at your own risk;

#target photoshop

if (app.documents.length > 1) {

// identify path;

var thePath = selectedPath();

if (thePath != undefined) {

var myDocument = app.activeDocument;

// set to pixels;

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS;

// collect info;

var thePathInfo = collectPathInfoFromDesc(myDocument, thePath);

// close withpout saving;

myDocument.close(SaveOptions.DONOTSAVECHANGES);

// create path;

createPath(thePathInfo, dateString());

// reset;

app.preferences.rulerUnits = originalRulerUnits;

}

else {alert ("no path selected")}

};

////// determine selected path //////

function selectedPath () {

try {

var ref = new ActionReference();

ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

var desc = executeActionGet(ref);

var theName = desc.getString(charIDToTypeID("PthN"));

return app.activeDocument.pathItems.getByName(theName)

}

catch (e) {

return undefined

}

};

////// collect path infor from actiondescriptor //////

function collectPathInfoFromDesc (myDocument, thePath) {

//var myDocument = app.activeDocument;

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.POINTS;

// based of functions from xbytor’s stdlib;

var ref = new ActionReference();

for (var l = 0; l < myDocument.pathItems.length; l++) {

     var thisPath = myDocument.pathItems;

     if (thisPath == thePath && thisPath.name == "Work Path") {

          ref.putProperty(cTID("Path"), cTID("WrPt"));

          };

     if (thisPath == thePath && thisPath.name != "Work Path" && thisPath.kind != PathKind.VECTORMASK) {

          ref.putIndex(cTID("Path"), l + 1);

          };

     if (thisPath == thePath && thisPath.kind == PathKind.VECTORMASK) {

        var idPath = charIDToTypeID( "Path" );

        var idPath = charIDToTypeID( "Path" );

        var idvectorMask = stringIDToTypeID( "vectorMask" );

        ref.putEnumerated( idPath, idPath, idvectorMask );

          };

     };

var desc = app.executeActionGet(ref);

var pname = desc.getString(cTID('PthN'));

// create new array;

var theArray = new Array;

var pathComponents = desc.getObjectValue(cTID("PthC")).getList(sTID('pathComponents'));

// for subpathitems;

for (var m = 0; m < pathComponents.count; m++) {

     var listKey = pathComponents.getObjectValue(m).getList(sTID("subpathListKey"));

     var operation = thePath.subPathItems.operation;

// for subpathitem’s count;

     for (var n = 0; n < listKey.count; n++) {

          theArray.push(new Array);

          var points = listKey.getObjectValue(n).getList(sTID('points'));

          try {var closed = listKey.getObjectValue(n).getBoolean(sTID("closedSubpath"))}

          catch (e) {var closed = false};

// for subpathitem’s segment’s number of points;

          for (var o = 0; o < points.count; o++) {

               var anchorObj = points.getObjectValue(o).getObjectValue(sTID("anchor"));

               var anchor = [anchorObj.getUnitDoubleValue(sTID('horizontal')), anchorObj.getUnitDoubleValue(sTID('vertical'))];

               var thisPoint = [anchor];

               try {

                    var left = points.getObjectValue(o).getObjectValue(cTID("Fwd "));

                    var leftDirection = [left.getUnitDoubleValue(sTID('horizontal')), left.getUnitDoubleValue(sTID('vertical'))];

                    thisPoint.push(leftDirection)

                    }

               catch (e) {

                    thisPoint.push(anchor)

                    };

               try {

                    var right = points.getObjectValue(o).getObjectValue(cTID("Bwd "));

                    var rightDirection = [right.getUnitDoubleValue(sTID('horizontal')), right.getUnitDoubleValue(sTID('vertical'))]

                    thisPoint.push(rightDirection)

                    }

               catch (e) {

                    thisPoint.push(anchor)

                    };

               theArray[theArray.length - 1].push(thisPoint);

               };

          theArray[theArray.length - 1].push(closed);

          theArray[theArray.length - 1].push(operation);

          };

     };

// by xbytor, thanks to him;

function cTID (s) { return cTID || cTID = app.charIDToTypeID(s); };

function sTID (s) { return sTID || sTID = app.stringIDToTypeID(s); };

// reset;

app.preferences.rulerUnits = originalRulerUnits;

return theArray;

};

////// function to create path from array with one array per point that holds anchor, leftdirection, etc, 2010 //////

function createPath (theArray, thePathsName) {

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.POINTS;

lineSubPathArray = new Array ();

if (theArray[theArray.length - 1].constructor != Array) {var numberOfSubPathItems = theArray.length - 1}

else {var numberOfSubPathItems = theArray.length};

for (var b = 0; b < numberOfSubPathItems; b++) {

     var lineArray = new Array ();

     for (c = 0; c < (theArray.length - 2); c++) {

          lineArray = new PathPointInfo;

          if (!theArray[3]) {lineArray.kind = PointKind.CORNERPOINT}

          else {lineArray.kind = theArray[3]};

          lineArray.anchor = theArray[0];

          if (!theArray[1]) {lineArray.leftDirection = theArray[0]}

          else {lineArray.leftDirection = theArray[1]};

          if (!theArray[2]) {lineArray.rightDirection = theArray[0]}

          else {lineArray.rightDirection = theArray[2]};     

          };

     lineSubPathArray = new SubPathInfo();

     lineSubPathArray.closed = theArray[theArray.length - 2];

     lineSubPathArray.operation = theArray[theArray.length - 1];

     lineSubPathArray.entireSubPath = lineArray;

     };

var myPathItem = app.activeDocument.pathItems.add(thePathsName, lineSubPathArray);

app.preferences.rulerUnits = originalRulerUnits;

return myPathItem

};

////// function to get the date //////

function dateString () {

     var now = new Date();

     var day = now.getDate();

     day = bufferNumberWithZeros(day, 2);

     var month = now.getMonth();

     month++;

     month = bufferNumberWithZeros(month, 2);

     var year = now.getFullYear();

     var hour = now.getHours();

     hour = bufferNumberWithZeros(hour, 2);

     var minutes = now.getMinutes();

     minutes = bufferNumberWithZeros(minutes, 2);

     var seconds = now.getSeconds();

     seconds = bufferNumberWithZeros(seconds, 2);

     var myDateText = year+"-"+month+"-"+day+"_"+hour+"-"+minutes+"-"+seconds;

     return myDateText

     };

////// buffer number with zeros //////

function bufferNumberWithZeros (number, places) {

     var theNumberString = String(number);

     for (var o = 0; o < (places - String(number).length); o++) {

          theNumberString = String("0" + theNumberString)

          };

     return theNumberString

     };

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 30, 2011 Aug 30, 2011

Copy link to clipboard

Copied

I have to compose 2 images in one (two different photo studio raw pictures)

I will try your code. Tks

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 30, 2011 Aug 30, 2011

Copy link to clipboard

Copied

You could also use the path as a Vector Mask and drag it over with the Layer, I guess.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 30, 2011 Aug 30, 2011

Copy link to clipboard

Copied

Well I have just use d the code and now I understand your question.

It worked to copy/paste the path itself.

Sorry, I didn't explained myself clear.

I need to copy the pixels selection created by the path (this path can be erased and I don't need it).

Thanks a lot anyway.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 30, 2011 Aug 30, 2011

Copy link to clipboard

Copied

In your desrciption I see you did a copy then closed to document no save.  Therefore I take it the image you do the copy from may be a file to begin with. Often it is a bit tricky to create Scripts or Action that work when there are more then one document in Photshop open document ring where the action or script needs to do things between documents or open new documents and work between documents.

I thought I would put together a little action for you that would work a bit differently then what you described.  In the document you want to add the layer to with paste. Play this action instead. It will put you into a Photoshop Place file selection Dialog select the file you want to make the selection from and place it into the active document.  The Action will move the places smart object layer to the top of the layer stack and rastersize it.  The Action will then display a stop message for you to create your selection Pen Workpath. Once you create the pen work path (Make sure you createing a add to path Path) in the Action Palette click on play button to have the Action to continue.  It will load the Path as a selection Invert the selection delete the work path and clear the area in the top layer so all that remains is the area you drew the path around. http://www.mouseprints.net/old/dpr/LayerfromPath.atn

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 31, 2011 Aug 31, 2011

Copy link to clipboard

Copied

I haven’t actually tested JJMack’s Action, but his outline describes a sensible solution without having to use Scripts.

But I personally doubt the benefits of the Selection and Deleting compared to using the Path as a Vector Mask on a complete Layer.

Size restrictions and having to pass the files on to other people may naturally be factors here.

// make selection from active path, copy, close document without saving, paste;

// 2011, use it at your own risk;

#target photoshop

if (app.documents.length > 1) {

var thePath = selectedPath();

if (thePath != undefined) {

thePath.makeSelection(0, true, SelectionType.REPLACE);

thePath.remove();

// merge just to make sure to get the image;

app.activeDocument.mergeVisibleLayers();

// =======================================================

var idcut = charIDToTypeID( "copy" );

executeAction( idcut, undefined, DialogModes.NO );

// close;

app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

// =======================================================

var idpast = charIDToTypeID( "past" );

executeAction( idpast, undefined, DialogModes.NO );

}

else {alert ("no path selected")}

};

////// determine selected path //////

function selectedPath () {

try {

var ref = new ActionReference();

ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

var desc = executeActionGet(ref);

var theName = desc.getString(charIDToTypeID("PthN"));

return app.activeDocument.pathItems.getByName(theName)

}

catch (e) {

return undefined

}

};

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 31, 2011 Aug 31, 2011

Copy link to clipboard

Copied

I do not see any difference with the layers added between my way or youtr way. Your script will fail if the document with the path is flat; you need to catch the merge visible layers error.

// make selection from active path, copy, close document without saving, paste;

// 2011, use it at your own risk;

#target photoshop

if (app.documents.length > 1) {

   var thePath = selectedPath();

   if (thePath != undefined) {

      thePath.makeSelection(0, true, SelectionType.REPLACE);

      thePath.remove();

      // merge just to make sure to get the image;

      try { app.activeDocument.mergeVisibleLayers();}

      catch (e) {};

      // =======================================================

      var idcut = charIDToTypeID( "copy" );

      executeAction( idcut, undefined, DialogModes.NO );

      // close;

      app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

      // =======================================================

      var idpast = charIDToTypeID( "past" );

      executeAction( idpast, undefined, DialogModes.NO );

      }

      else {alert ("no path selected")}

   };

////// determine selected path //////

function selectedPath () {

   try {

      var ref = new ActionReference();

      ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

      var desc = executeActionGet(ref);

      var theName = desc.getString(charIDToTypeID("PthN"));

      return app.activeDocument.pathItems.getByName(theName)

      }

      catch (e) { return undefined }

   };

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 31, 2011 Aug 31, 2011

Copy link to clipboard

Copied

Good catch; I should have included a check for the presence of more than one layer.

Edit: And copy/pasting with a Script is not a good idea, anyway, I guess.

Your method incurs the risk of having the placed file scaled if it is of a different resolution than the receiving document.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 31, 2011 Aug 31, 2011

Copy link to clipboard

Copied

c.pfaffenbichler wrote:

Your method incurs the risk of having the placed file scaled if it is of a different resolution than the receiving document.

It is an interactive place so the user had the option to scale the image being placed to suit the scale of the image its being added to as a smart object layer. The interactive transforn will always match the place layer to the active document resolution. The place operation may also resize the image being placed even if their resolution matched. If the image being placed is larger then then document its being placed into and Photoshop preferences resized during place is checked. The user is in control during the Place Transform...

The problem with the Paste thing is if you start the operation using an action or script from an active document that has an active path copy it to the clibboard and close that active document nosave which document becomes the active document depend on how documents were added to the open document ring.  If the user had five open document the one prior to the active document might not be the document they want the layer added to.  That is the reason I started with the document the layer is going to be added to and did not record things like next document and count on the prior document.

JJMack

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 31, 2011 Aug 31, 2011

Copy link to clipboard

Copied

LATEST

»It is an interactive place so the user had the option to scale the image being placed to suit the scale of the image its being added to as a smart object layer.«

Right you are.

Edit:

That is the reason I started with the document the layer is going to be added to and did not record things like next document and count on the prior document.

Good reasoning.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines