CS6: create a two segment open line path with a 1px stroke

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

Jeremy Knudsen

CS6: create a two segment open line path with a 1px stroke

Post by Jeremy Knudsen »

Hi there,

The Goal:
I am trying to script Photoshop CS6 to create a simple vector line that has 2 segments (3 corner points with the middle point used to create an "elbow" bend). I want the path to remain open so that it doesn't auto-complete and create an enclosed shape (i.e. I want it to appear as a line with an elbow bend; not as a triangle shape). I want this line to use the new Shape layer features in CS6, which allows you to create a dashed line. If you select the pen tool and the "Shape" tool preset for the pen, and then click three times on the canvas you will see what I want to create via script.

The Problem:
I can't seem to create a shape layer via script that keeps the path open. And I do not want to use the stroke layer FX or create a raster art layer and stroke the path with the brush/pencil tool.

Here is an image example of what I'm trying to do via script: http://sdrv.ms/1hlR5jW


Please let me know if you need any clarification of what I'm trying to do. Any help would be GREATLY appreciated. I've been trying to figure this one out on my own for quite a while without any luck (albeit I am not a developer by trade).

Thanks in advance!
Jeremy

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

pfaffenbichler

CS6: create a two segment open line path with a 1px stroke

Post by pfaffenbichler »

Does this help?
Code: Select all// create three point path shape layer with dashed stroke;
// 2014, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
var myDocument = app.activeDocument;
app.activeDocument.suspendHistory ("stuff", "main ()")
};
function main () {
var theArray = [[[[0,0], [0,0], [0,0],false],[[100,100], [100,100], [100,100],false],[[200,0], [200,0], [200,0],false],false,1097098272]];
var thePath = createPath2012(theArray, Math.random());
var theLayer = makeSolidColorLayer("shape", 0, 0, 0);
thePath.remove();
noFillAndDashedStroke ()
};
////// 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
};

function noFillAndDashedStroke () {
// =======================================================
var idsetd = charIDToTypeID( "setd" );
    var desc27 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref8 = new ActionReference();
        var idcontentLayer = stringIDToTypeID( "contentLayer" );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idTrgt = charIDToTypeID( "Trgt" );
        ref8.putEnumerated( idcontentLayer, idOrdn, idTrgt );
    desc27.putReference( idnull, ref8 );
    var idT = charIDToTypeID( "T   " );
        var desc28 = new ActionDescriptor();
        var idstrokeStyle = stringIDToTypeID( "strokeStyle" );
            var desc29 = new ActionDescriptor();
            var idstrokeStyleVersion = stringIDToTypeID( "strokeStyleVersion" );
            desc29.putInteger( idstrokeStyleVersion, 2 );
            var idfillEnabled = stringIDToTypeID( "fillEnabled" );
            desc29.putBoolean( idfillEnabled, false );
        var idstrokeStyle = stringIDToTypeID( "strokeStyle" );
        desc28.putObject( idstrokeStyle, idstrokeStyle, desc29 );
    var idshapeStyle = stringIDToTypeID( "shapeStyle" );
    desc27.putObject( idT, idshapeStyle, desc28 );
executeAction( idsetd, desc27, DialogModes.NO );

// =======================================================
var idsetd = charIDToTypeID( "setd" );
    var desc30 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref9 = new ActionReference();
        var idcontentLayer = stringIDToTypeID( "contentLayer" );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idTrgt = charIDToTypeID( "Trgt" );
        ref9.putEnumerated( idcontentLayer, idOrdn, idTrgt );
    desc30.putReference( idnull, ref9 );
    var idT = charIDToTypeID( "T   " );
        var desc31 = new ActionDescriptor();
        var idstrokeStyle = stringIDToTypeID( "strokeStyle" );
            var desc32 = new ActionDescriptor();
            var idstrokeStyleContent = stringIDToTypeID( "strokeStyleContent" );
                var desc33 = new ActionDescriptor();
                var idClr = charIDToTypeID( "Clr " );
                    var desc34 = new ActionDescriptor();
                    var idRd = charIDToTypeID( "Rd  " );
                    desc34.putDouble( idRd, 41.417409 );
                    var idGrn = charIDToTypeID( "Grn " );
                    desc34.putDouble( idGrn, 41.417409 );
                    var idBl = charIDToTypeID( "Bl  " );
                    desc34.putDouble( idBl, 41.417409 );
                var idRGBC = charIDToTypeID( "RGBC" );
                desc33.putObject( idClr, idRGBC, desc34 );
            var idsolidColorLayer = stringIDToTypeID( "solidColorLayer" );
            desc32.putObject( idstrokeStyleContent, idsolidColorLayer, desc33 );
            var idstrokeStyleVersion = stringIDToTypeID( "strokeStyleVersion" );
            desc32.putInteger( idstrokeStyleVersion, 2 );
            var idstrokeEnabled = stringIDToTypeID( "strokeEnabled" );
            desc32.putBoolean( idstrokeEnabled, true );
        var idstrokeStyle = stringIDToTypeID( "strokeStyle" );
        desc31.putObject( idstrokeStyle, idstrokeStyle, desc32 );
    var idshapeStyle = stringIDToTypeID( "shapeStyle" );
    desc30.putObject( idT, idshapeStyle, desc31 );
executeAction( idsetd, desc30, DialogModes.NO );

// =======================================================
var idsetd = charIDToTypeID( "setd" );
    var desc35 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref10 = new ActionReference();
        var idcontentLayer = stringIDToTypeID( "contentLayer" );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idTrgt = charIDToTypeID( "Trgt" );
        ref10.putEnumerated( idcontentLayer, idOrdn, idTrgt );
    desc35.putReference( idnull, ref10 );
    var idT = charIDToTypeID( "T   " );
        var desc36 = new ActionDescriptor();
        var idstrokeStyle = stringIDToTypeID( "strokeStyle" );
            var desc37 = new ActionDescriptor();
            var idstrokeStyleLineAlignment = stringIDToTypeID( "strokeStyleLineAlignment" );
            var idstrokeStyleLineAlignment = stringIDToTypeID( "strokeStyleLineAlignment" );
            var idstrokeStyleAlignCenter = stringIDToTypeID( "strokeStyleAlignCenter" );
            desc37.putEnumerated( idstrokeStyleLineAlignment, idstrokeStyleLineAlignment, idstrokeStyleAlignCenter );
            var idstrokeStyleLineDashSet = stringIDToTypeID( "strokeStyleLineDashSet" );
                var list2 = new ActionList();
                var idNne = charIDToTypeID( "#Nne" );
                list2.putUnitDouble( idNne, 4.000000 );
                var idNne = charIDToTypeID( "#Nne" );
                list2.putUnitDouble( idNne, 2.000000 );
            desc37.putList( idstrokeStyleLineDashSet, list2 );
            var idstrokeStyleVersion = stringIDToTypeID( "strokeStyleVersion" );
            desc37.putInteger( idstrokeStyleVersion, 2 );
            var idstrokeEnabled = stringIDToTypeID( "strokeEnabled" );
            desc37.putBoolean( idstrokeEnabled, true );
        var idstrokeStyle = stringIDToTypeID( "strokeStyle" );
        desc36.putObject( idstrokeStyle, idstrokeStyle, desc37 );
    var idshapeStyle = stringIDToTypeID( "shapeStyle" );
    desc35.putObject( idT, idshapeStyle, desc36 );
executeAction( idsetd, desc35, DialogModes.NO );
};
////// the fill-layer-function //////
function makeSolidColorLayer (theName, theR, theG, theB) {
// =======================================================
var idMk = charIDToTypeID( "Mk  " );
    var desc3 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref1 = new ActionReference();
        var idcontentLayer = stringIDToTypeID( "contentLayer" );
        ref1.putClass( idcontentLayer );
    desc3.putReference( idnull, ref1 );
    var idUsng = charIDToTypeID( "Usng" );
        var desc4 = new ActionDescriptor();
        var idType = charIDToTypeID( "Type" );
            var desc5 = new ActionDescriptor();
            var idClr = charIDToTypeID( "Clr " );
                var desc6 = new ActionDescriptor();
                var idRd = charIDToTypeID( "Rd  " );
                desc6.putDouble( idRd, theR );
                var idGrn = charIDToTypeID( "Grn " );
                desc6.putDouble( idGrn, theG );
                var idBl = charIDToTypeID( "Bl  " );
                desc6.putDouble( idBl, theB );
            var idRGBC = charIDToTypeID( "RGBC" );
            desc5.putObject( idClr, idRGBC, desc6 );
        var idsolidColorLayer = stringIDToTypeID( "solidColorLayer" );
        desc4.putObject( idType, idsolidColorLayer, desc5 );
    var idcontentLayer = stringIDToTypeID( "contentLayer" );
    desc3.putObject( idUsng, idcontentLayer, desc4 );
executeAction( idMk, desc3, DialogModes.NO );
return app.activeDocument.activeLayer
};
// 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;
};
Jeremy Knudsen

CS6: create a two segment open line path with a 1px stroke

Post by Jeremy Knudsen »

WOW!

Does it help?! You nailed it! You bet it helps! THANK YOU!!! You've made a new follower.
pfaffenbichler

CS6: create a two segment open line path with a 1px stroke

Post by pfaffenbichler »

You’re welcome.

You will have to figure out where to amend the values in the function »noFillAndDashedStroke« to meet your needs.
But worst case you can record the operations as you need them with ScriptingListener.plugin and replace the corresponding code.
Jeremy Knudsen

CS6: create a two segment open line path with a 1px stroke

Post by Jeremy Knudsen »

Thanks for the tip on how to modify the stroke and fill--script listener did the trick! You've saved me countless hours of me trying to continue figuring this out on my own.