Skip to main content
bala281972
Known Participant
November 24, 2011
Answered

How to measure the distance using script

  • November 24, 2011
  • 2 replies
  • 5445 views

Hi

Is there any way to measure the distance of any photoshop document using the measure tool, by using the script. Given below the steps required by me. Hope i'm clear in my communications.

I searched the forums but couldnt find any suitable answers.

1.Open Photoshop document

2. Allow the user to draw the line using measure tool

3. alert the distance

Rgs

Anish

This topic has been closed for replies.
Correct answer Michael_L_Hale

I understand what you are saying and I agree that to match the measure tool the function would need to be changed. What I was trying to say was that it was originally written to work with left to right paths. The angle of a path made from left to right( that is pathPoint[0].anchor[0] is less than of pathPoint[3].anchor[0] when using a line tool path ) can only have an angle of +/- 90.

A path made from right to left needs to use different pathpoints and requries different math. Another factor for the mismatch is the measure tool rounds to the nearest whole pixel. Paths can use fractions of a pixel. The angle may not match exactly because of that rounding.

It's true all of those issues could be fixed and you are free to make any modifications you like.


This only works with CS5 as it now uses the ruler tool instead of a path. But it fixes all the issues talked about in this thread and well as some other differences between the original funciton and the data in the info panel.

It returns a custom object with angle and length properties if there is a ruler tool line in the active document and undefined it not. I was unsure if the length should be a unitValue or a number in the ruler units settings. I went with number because the info panel has different number of decimal places for the different units. And like the info panel if the ruler setting are set to percent the length value is blank

function getRulerToolLengthAndAngle(){

    var points = [];

    points.start = [];

    points.end = [];

    var desc = new ActionDescriptor();

    var ref = new ActionReference();

    ref.putProperty( charIDToTypeID('Prpr'), charIDToTypeID('RrPt') );

    ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );

    desc.putReference( charIDToTypeID('null'), ref );

    var desc = executeAction( charIDToTypeID('getd'), desc, DialogModes.NO );

    if( desc.hasKey( charIDToTypeID('Pts ') ) ){

        var pointList = desc.getList( charIDToTypeID('Pts ') );

        var startPointDesc = pointList.getObjectValue(0);

       

        points.start.push( startPointDesc.getUnitDoubleValue( charIDToTypeID( 'X   ' ) ) );

        points.start.push( startPointDesc.getUnitDoubleValue( charIDToTypeID( 'Y   ' ) ) );

        var endPointDesc = pointList.getObjectValue(2);

        points.end.push( endPointDesc.getUnitDoubleValue( charIDToTypeID( 'X   ' ) ) );

        points.end.push( endPointDesc.getUnitDoubleValue( charIDToTypeID( 'Y   ' ) ) );

       

        var res = {};

        res.toString = function(){ return 'RulerTool Info';};

        var pointA = points.start;

        var pointB = points.end;

        if( pointA[0]<pointB[0] ){

            var a = Math.max(pointA[0],pointB[0])-Math.min(pointA[0],pointB[0]);

            var o = Math.max(pointA[1],pointB[1])-Math.min(pointA[1],pointB[1]);

            var ang = (180/Math.PI) * Math.atan2(o,a);

            if(pointA[1] < pointB[1]){//negative angle

                ang = -ang;

            };

            res.angle = ang.toFixed(1);

        }else{

            var a = Math.max(pointA[1],pointB[1])-Math.min(pointA[1],pointB[1]);

            var o = Math.max(pointA[0],pointB[0])-Math.min(pointA[0],pointB[0]);

            var ang = 180-((180/Math.PI) * Math.atan2(a,o));

            if(pointA[1] < pointB[1]){//negative angle

                ang = -ang;

            };

            res.angle = ang.toFixed(1);

        }

            if( app.preferences.rulerUnits == Units.PERCENT ){

                res.length = "";

            }else{

                var c = Math.sqrt((a*a)+(o*o));

                var length = new UnitValue( c, 'px');

                length.baseUnit = new UnitValue((1/app.activeDocument.resolution),'in');

                switch( app.preferences.rulerUnits ){

                    case Units.PIXELS: res.length = length.as('px').toFixed(2); break;

                    case Units.INCHES : res.length = length.as('in').toFixed(3); break;

                    case Units.CM: res.length = length.as('cm').toFixed(2); break;

                    case Units.MM: res.length = length.as('mm').toFixed(1); break;

                    case Units.POINTS: res.length = length.as('pt').toFixed(1); break;

                    case Units.PICAS: res.length = length.as('pc').toFixed(2); break;

                }

            }

        return res;

    }

}

var info = getRulerToolLengthAndAngle();

if(info != undefined ) alert('The ruler tool angle is: '+info.angle+'\nThe length is: '+info.length);

2 replies

Inspiring
November 24, 2011

You can have the user mark the part of the image to be measured with the pen or line shape tool. But if all the script is going to do is alert the user the distance, they could get that from using the measure tool and the info panel without a script.

At any rate here is a function to find the distance and angle of a line path made with either the pen or line tool.

//the code below is for the pen tool. If the path was made with the line tool replace pathPoints[1] with pathPoints[3]

  function measureLine(path){

   var res = new Array;

   var lineStart = path.subPathItems[0].pathPoints[0].anchor;

   var lineEnd = path.subPathItems[0].pathPoints[1].anchor;

   var a = Math.max(lineStart[0],lineEnd[0])-Math.min(lineStart[0],lineEnd[0]);

   var o = Math.max(lineStart[1],lineEnd[1])-Math.min(lineStart[1],lineEnd[1]);

   var c = Math.round(Math.sqrt((a*a)+(o*o)));

   res.push(c);

   var ang = (180/Math.PI) * Math.atan2(o,a);

   if(lineStart[1] < lineEnd[1]){//negative angle

      ang = -ang;

   };

   res.push(ang);

   return res;

   }

JJMack
Community Expert
November 24, 2011

I would think that if the measure tool were recordable which it is not you would need to set the two end points.  If you have the two end points you do not need the measure tool for its then simple math the length is the square root of the sum of the width length squared and the height length squared.

With the line tool set to create a path you could daw a line path and have  a script to get the bounds of the path or path turned into a selection and do the above math. To automate the process you could record an interactine action to create the line path then have the action use the script that calulayes the line length after the interactive path step..

JJMack
Inspiring
November 24, 2011

JJMack,

I have never been able to find a way that allows the user to make the path using the line tool while the script is running. I will admit I never thought of actions but I can't get it it work with actions either. Can you post the steps to create an interactive action using the line tool?

JJMack
Community Expert
November 25, 2011

Your most likely will not like my reply for its not fully automated. Many things in Photoshop can not be recorded or scripted. These thing need to be done manually by a user. All an Action of script can do in these cases is help with the manual process.  This normally means selecting the tools and set it to the properties you want the user to use. Then inserting a stop with a message instructing the user what to do and that after they do it to click Play to continue the action.  In the cast of the line tool you need to install or have the user define a line tool preset with a specific name like "Line Tool 1".  The action would have a recorded step where the preset manager was used to select tool preset "Line Tool 1".  That step would set the current tool to be the line tool with no arrow heads and be 1 pixel wide path. The stop would tell the user to draw out a line then click play.  IMO the pen tool could be used but the Pen tool can also draw curved lines that twist back over the path and the bounds of a selection made from the work path might not be what one wants. Also the pen tool wants to continue drawing after you draw out the first line.

And thank you for the function.....

JJMack