How to each point of a path

Anyone, especially newbies, asking for help with Photoshop Scripting and Photoshop Automation - as opposed to those contributing to discussion about an aspect of Photoshop Scripting

Moderators: Tom, Kukurykus

rashed.mamoon

How to each point of a path

Post by rashed.mamoon »

Hi,

I need a loop/script which can read each point of a path and show it on alert box

Please help!

Professional AI Audio Generation within Adobe Premiere Pro - Download Free Plugin here

pfaffenbichler

How to each point of a path

Post by pfaffenbichler »

I’m not sure I understand what you want fully, but give this a try.
Code: Select all// alert paths’s points’ coordinates;
// 2013, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
var myDocument = app.activeDocument;
if (myDocument.pathItems.length > 0) {
var thePathStuff = collectPathInfoFromDesc2012 (myDocument, selectedPath());
for (var m = 0; m < thePathStuff.length; m++) {
var thisSubPath = thePathStuff[m];
for (var n = 0; n < thisSubPath.length - 2; n++) {
alert ("subPathItem "+m+"\npoint "+n+"\n"+thisSubPath[n].join("\n"))
}
}
};
};
////// collect path info from actiondescriptor, smooth added //////
function collectPathInfoFromDesc2012 (myDocument, thePath) {
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[l];
   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 operation1 = pathComponents.getObjectValue(m).getEnumerationValue(sTID("shapeOperation"));
   switch (operation1) {
      case 1097098272:
      var operation = 1097098272 //cTID('Add ');
      break;
      case 1398961266:
      var operation = 1398961266 //cTID('Sbtr');
      break;
      case 1231975538:
      var operation = 1231975538 //cTID('Intr');
      break;
      default:
//      case 1102:
      var operation = sTID('xor') //ShapeOperation.SHAPEXOR;
      break;
      };
// 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)
            };
         try {
            var smoothOr = points.getObjectValue(o).getBoolean(cTID("Smoo"));
            thisPoint.push(smoothOr)
            }
         catch (e) {thisPoint.push(false)};
         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[s] || cTID[s] = app.charIDToTypeID(s); };
function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };
// reset;
app.preferences.rulerUnits = originalRulerUnits;
return theArray;
};
////// determine selected path, updated 08.2011 //////
function selectedPath () {
try {
// save work path;
if (app.activeDocument.pathItems[app.activeDocument.pathItems.length - 1].kind == PathKind.WORKPATH) {
app.activeDocument.pathItems[app.activeDocument.pathItems.length - 1].name = Math.random()
};
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref);
var theName = desc.getString(charIDToTypeID("PthN"));
//
if (theName == "Work Path") {
   return app.activeDocument.pathItems[app.activeDocument.pathItems.length - 1]
   }
else {
   return app.activeDocument.pathItems.getByName(theName)
   }
}
catch (e) {
   return undefined
   }
};
rashed.mamoon

How to each point of a path

Post by rashed.mamoon »

HI,

Thank you so much, yes i wanted that.

But my ultimate goal to archive the following:

Please see the attached error.psd
In the PSD file there are 2 path layer: path 4 and Path 1

There is a path in path 4, where its have only 1 anchor point, I need to find this type of path(s) from a file.
- It would be wonderful if it could be marked with a red circle.

the script should not detect normal path like "Path 1"

Also script need to run on CS3

Thank you in advance!
pfaffenbichler

How to each point of a path

Post by pfaffenbichler »

I could not find an attached file.

Wouldn’t it be easier to simply have the 1-point-paths removed, so to speak?
rashed.mamoon

How to each point of a path

Post by rashed.mamoon »

I have attached now!

Yes, that would the best solution.

If you could also add a alert to show how many path removed.
rashed.mamoon

How to each point of a path

Post by rashed.mamoon »

Hello pfaffenbichler

Please have a look, need your help
pfaffenbichler

How to each point of a path

Post by pfaffenbichler »

I have not forgotten the issue but I am currently busy at work, so I can’t say when exactly I’ll have the time to look into it.

Edit: But maybe someone else wants to give it a try.
rashed.mamoon

How to each point of a path

Post by rashed.mamoon »

thank you for response! I will wait
pfaffenbichler

How to each point of a path

Post by pfaffenbichler »

Could you give this a try?
But some warnings:
• there can be paths that will produce wrong results
• paths elements cannot be edited properly with Scripts, one can create a new Path altogether and remove the old one to produce the appearance but it is not the same
Code: Select all// address one point subpathitems;
// 2013, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
var myDocument = app.activeDocument;
if (myDocument.pathItems.length > 0) {
// check for selected path;
var theSelectedPath = selectedPath();
if (theSelectedPath != undefined) {
var thePathName = theSelectedPath.name;
var thePathStuff = collectPathInfoFromDesc2012 (myDocument, selectedPath());
// collect only the subpathitems with more than one point;
var theNewPathStuff = new Array;
//theSelectePath.remove();
var theCounter = 0;
for (var m = 0; m < thePathStuff.length; m++) {
var thisSubPath = thePathStuff[m];
if (thisSubPath.length > 3) {theNewPathStuff.push(thisSubPath)}
else {theCounter++}
};
// check for vector mask;
if (hasVectorMask() == true && myDocument.pathItems[myDocument.pathItems.length -1] == theSelectedPath) {
// delete vector mask
// =======================================================
var idDlt = charIDToTypeID( "Dlt " );
    var desc2 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref1 = new ActionReference();
        var idPath = charIDToTypeID( "Path" );
        var idPath = charIDToTypeID( "Path" );
        var idvectorMask = stringIDToTypeID( "vectorMask" );
        ref1.putEnumerated( idPath, idPath, idvectorMask );
        var idLyr = charIDToTypeID( "Lyr " );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idTrgt = charIDToTypeID( "Trgt" );
        ref1.putEnumerated( idLyr, idOrdn, idTrgt );
    desc2.putReference( idnull, ref1 );
executeAction( idDlt, desc2, DialogModes.NO );
// create path;
var tempPath = createPath2012(theNewPathStuff, Math.random());
// add vector mask;
// =======================================================
var idMk = charIDToTypeID( "Mk  " );
    var desc4 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref3 = new ActionReference();
        var idPath = charIDToTypeID( "Path" );
        ref3.putClass( idPath );
    desc4.putReference( idnull, ref3 );
    var idAt = charIDToTypeID( "At  " );
        var ref4 = new ActionReference();
        var idPath = charIDToTypeID( "Path" );
        var idPath = charIDToTypeID( "Path" );
        var idvectorMask = stringIDToTypeID( "vectorMask" );
        ref4.putEnumerated( idPath, idPath, idvectorMask );
    desc4.putReference( idAt, ref4 );
    var idUsng = charIDToTypeID( "Usng" );
        var ref5 = new ActionReference();
        var idPath = charIDToTypeID( "Path" );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idTrgt = charIDToTypeID( "Trgt" );
        ref5.putEnumerated( idPath, idOrdn, idTrgt );
    desc4.putReference( idUsng, ref5 );
executeAction( idMk, desc4, DialogModes.NO );
// remove temporary path;
tempPath.remove();
}
else {
theSelectedPath.remove();
// create path;
createPath2012(theNewPathStuff, thePathName);
};
alert (thePathName+":\n"+theCounter+" of "+thePathStuff.length+" paths were single point and have not been recreated");
};
}
};
////// collect path info from actiondescriptor, smooth added //////
function collectPathInfoFromDesc2012 (myDocument, thePath) {
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[l];
   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 operation1 = pathComponents.getObjectValue(m).getEnumerationValue(sTID("shapeOperation"));
   switch (operation1) {
      case 1097098272:
      var operation = 1097098272 //cTID('Add ');
      break;
      case 1398961266:
      var operation = 1398961266 //cTID('Sbtr');
      break;
      case 1231975538:
      var operation = 1231975538 //cTID('Intr');
      break;
      default:
//      case 1102:
      var operation = sTID('xor') //ShapeOperation.SHAPEXOR;
      break;
      };
// 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)
            };
         try {
            var smoothOr = points.getObjectValue(o).getBoolean(cTID("Smoo"));
            thisPoint.push(smoothOr)
            }
         catch (e) {thisPoint.push(false)};
         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[s] || cTID[s] = app.charIDToTypeID(s); };
function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };
// reset;
app.preferences.rulerUnits = originalRulerUnits;
return theArray;
};
////// determine selected path, updated 08.2011 //////
function selectedPath () {
try {
// save work path;
if (app.activeDocument.pathItems[app.activeDocument.pathItems.length - 1].kind == PathKind.WORKPATH) {
app.activeDocument.pathItems[app.activeDocument.pathItems.length - 1].name = Math.random()
};
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref);
var theName = desc.getString(charIDToTypeID("PthN"));
//
if (theName == "Work Path") {
   return app.activeDocument.pathItems[app.activeDocument.pathItems.length - 1]
   }
else {
   return app.activeDocument.pathItems.getByName(theName)
   }
}
catch (e) {
   return undefined
   }
};
////// create a path from collectPathInfoFromDesc2012-array //////
function createPath2012(theArray, thePathsName) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.POINTS;
// thanks to xbytor;
cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };

    var desc1 = new ActionDescriptor();
    var ref1 = new ActionReference();
    ref1.putProperty(cTID('Path'), cTID('WrPt'));
    desc1.putReference(sTID('null'), ref1);
    var list1 = new ActionList();
   
for (var m = 0; m < theArray.length; m++) {
   var thisSubPath = theArray[m];
   
    var desc2 = new ActionDescriptor();
    desc2.putEnumerated(sTID('shapeOperation'), sTID('shapeOperation'), thisSubPath[thisSubPath.length - 1]);
    var list2 = new ActionList();
    var desc3 = new ActionDescriptor();
    desc3.putBoolean(cTID('Clsp'), thisSubPath[thisSubPath.length - 2]);
    var list3 = new ActionList();
   
for (var n = 0; n < thisSubPath.length - 2; n++) {
   var thisPoint = thisSubPath[n];
   
    var desc4 = new ActionDescriptor();
    var desc5 = new ActionDescriptor();
    desc5.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[0][0]);
    desc5.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[0][1]);
    desc4.putObject(cTID('Anch'), cTID('Pnt '), desc5);
    var desc6 = new ActionDescriptor();
    desc6.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[1][0]);
    desc6.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[1][1]);
    desc4.putObject(cTID('Fwd '), cTID('Pnt '), desc6);
    var desc7 = new ActionDescriptor();
    desc7.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[2][0]);
    desc7.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[2][1]);
    desc4.putObject(cTID('Bwd '), cTID('Pnt '), desc7);
    desc4.putBoolean(cTID('Smoo'), thisPoint[3]);
    list3.putObject(cTID('Pthp'), desc4);
   
   };
   
    desc3.putList(cTID('Pts '), list3);
    list2.putObject(cTID('Sbpl'), desc3);
    desc2.putList(cTID('SbpL'), list2);
    list1.putObject(cTID('PaCm'), desc2);
   };
   
    desc1.putList(cTID('T   '), list1);
    executeAction(cTID('setd'), desc1, DialogModes.NO);

if (hasVectorMask() == false) {
if (thePathsName != undefined) {app.activeDocument.pathItems[app.activeDocument.pathItems.length - 1].name = thePathsName};
var myPathItem = app.activeDocument.pathItems[app.activeDocument.pathItems.length - 1];
}
else {
if (thePathsName != undefined) {app.activeDocument.pathItems[app.activeDocument.pathItems.length - 2].name = thePathsName};
var myPathItem = app.activeDocument.pathItems[app.activeDocument.pathItems.length - 2];
};
app.preferences.rulerUnits = originalRulerUnits;
return myPathItem
};
// from »Flatten All Masks.jsx« by jeffrey tranberry;
///////////////////////////////////////////////////////////////////////////////
// Function: hasVectorMask
// Usage: see if there is a vector layer mask
// Input: <none> Must have an open document
// Return: true if there is a vector mask
///////////////////////////////////////////////////////////////////////////////
function hasVectorMask() {
   var hasVectorMask = false;
   try {
      var ref = new ActionReference();
      var keyVectorMaskEnabled = app.stringIDToTypeID( 'vectorMask' );
      var keyKind = app.charIDToTypeID( 'Knd ' );
      ref.putEnumerated( app.charIDToTypeID( 'Path' ), app.charIDToTypeID( 'Ordn' ), keyVectorMaskEnabled );
      var desc = executeActionGet( ref );
      if ( desc.hasKey( keyKind ) ) {
         var kindValue = desc.getEnumerationValue( keyKind );
         if (kindValue == keyVectorMaskEnabled) {
            hasVectorMask = true;
         }
      }
   }catch(e) {
      hasVectorMask = false;
   }
   return hasVectorMask;
};
rashed.mamoon

How to each point of a path

Post by rashed.mamoon »

Hi,

Thank you so much, that was too quick.

I tested the script on the files I sent and worked but the file I have attached didn't work but it have 12 of them. Also, it works on only the selected path layer, it need to scan all the path layers.

And for warning point 2, If so, then can you please don't delete it, just create a circle on it.

But some warnings:
• there can be paths that will produce wrong results
• paths elements cannot be edited properly with Scripts, one can create a new Path altogether and remove the old one to produce the appearance but it is not the same