Skip to main content
X-Raym
Participating Frequently
February 21, 2018
Answered

Get Layer Transform X Y Top Left Coordinate Position

  • February 21, 2018
  • 3 replies
  • 15061 views

Hi !

I try to look for this but in fact it seems more complicated than expected, and I didn't find a working up to date solution.

So we have layer bound property, which can return top left value of a layer.

But if the layer is smart layer (or a text) this may not work as I would have expect: indeed, it will return the value of the position of the first pixel, and not the actual smart layer position (determined by it's original boundaries).

Here is a screen capture to show the difference between the layer top left coordinate and the transform X Y position (which match the original file placement):

How do you get these X Y positions from a Photoshop script ?

Thanks !

This topic has been closed for replies.
Correct answer r-bin

Try this function

function get_layer_bounds(layer)

    {

    try

        {

        if (layer.kind == LayerKind.SMARTOBJECT)

            {

            var layer0 = activeDocument.activeLayer;

            activeDocument.activeLayer = layer;

            var r = new ActionReference();

            r.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );

            var d = executeActionGet(r).getObjectValue(stringIDToTypeID("smartObjectMore")).getList(stringIDToTypeID("transform"));

            var x = [d.getDouble(0), d.getDouble(2), d.getDouble(4), d.getDouble(6)];

            var y = [d.getDouble(1), d.getDouble(3), d.getDouble(5), d.getDouble(7)];

          

            var l = [Math.min(x[0], Math.min(x[1], Math.min(x[2], x[3]))) ];

            var r = [Math.max(x[0], Math.max(x[1], Math.max(x[2], x[3]))) ];

            var t = [Math.min(y[0], Math.min(y[1], Math.min(y[2], y[3]))) ];

            var b = [Math.max(y[0], Math.max(y[1], Math.max(y[2], y[3]))) ];

            activeDocument.activeLayer = layer0;

            return [ UnitValue(l,"px"), UnitValue(t,"px"), UnitValue(r,"px"), UnitValue(b,"px") ];

            }

        else

            return layer.boundsNoEffects;

        }

    catch (e) { alert(e); }

    }

3 replies

X-Raym
X-RaymAuthor
Participating Frequently
March 17, 2018

r-bin​, the question is for anyone who want to answer 🙂
Thank you again for your time and expertise !!

 

I'll see how this function can be integrated in my current script.

 

Cheers !

X-Raym
X-RaymAuthor
Participating Frequently
March 15, 2018

I just got a very particular cases,

How would you get X and Y position relative to the Artboard position ? Seems to be a quite complex API case.

I had a layer on a artboard which was offset by 961px, and all Y were offset by 961px. Idealy, I would prefer to have it not offset.

Thanks for your help

Legend
March 16, 2018

If the question is to me, then I have never worked with ArtBoards (in CS6 there are none).

But if I understand correctly what you need, then here is a new function which, depending on the parameter "in_artboard" returns the absolute or relative coordinates of the layer (or smart object).

 

To work, you also need the function get_prop_value().

Its code can be found in this thread: Modifying Levels Adjustment Layer?

 

alert(get_layer_bounds(activeDocument.activeLayer, false))

alert(get_layer_bounds(activeDocument.activeLayer, true))

 

function get_layer_bounds(layer, in_artboard) 

    { 

    try 

        { 

        var ret;

 

        var layer0 = activeDocument.activeLayer; 

        activeDocument.activeLayer = layer; 

 

        var id = get_prop_value("layer", null, "layerID");

 

        if (layer.kind == LayerKind.SMARTOBJECT) 

            { 

            var d = get_prop_value("layer", null, "smartObjectMore", "transform");

 

            var x = [d.getDouble(0), d.getDouble(2), d.getDouble(4), d.getDouble(6)]; 

            var y = [d.getDouble(1), d.getDouble(3), d.getDouble(5), d.getDouble(7)]; 

            

            var l = [Math.min(x[0], Math.min(x[1], Math.min(x[2], x[3]))) ]; 

            var r = [Math.max(x[0], Math.max(x[1], Math.max(x[2], x[3]))) ]; 

 

            var t = [Math.min(y[0], Math.min(y[1], Math.min(y[2], y[3]))) ]; 

            var b = [Math.max(y[0], Math.max(y[1], Math.max(y[2], y[3]))) ]; 

 

            ret = [ UnitValue(l,"px"), UnitValue(t,"px"), UnitValue(r,"px"), UnitValue(b,"px") ]; 

            } 

        else 

            {

            var old_units = app.preferences.rulerUnits;

            app.preferences.rulerUnits = Units.PIXELS;

 

            ret = layer.boundsNoEffects; 

            app.preferences.rulerUnits = old_units;

            }

 

        if (in_artboard)

            {

            var art_rect = get_layer_atrboard_rect(id)

   

            ret[0] -= art_rect.left;

            ret[2] -= art_rect.left;

 

            ret[1] -= art_rect.top;

            ret[3] -= art_rect.top;

            }

 

        activeDocument.activeLayer = layer0; 

 

        return ret;

        } 

    catch (e) { alert(e); } 

    }  

 

function get_layer_atrboard_rect(id)

    {

    try {

        var not_artboard_rect = {top:0, left:0, bottom:0, right:0};

 

        eval("var json = " + get_prop_value("layer", null, "json"));

 

        if (json == undefined) return not_artboard_rect;

 

        function test_id(layer, id, n)

            {

            if (layer.id == id) return n;

 

            if (layer.layers)

                {

                for (var i = 0; i < layer.layers.length; i++)

                    {

                    var ret = test_id(layer.layers, id, n+1);

                    if (ret != null) return ret;

                    }               

                return null;

                }

            else

                {

                return null;

                }           

            }

 

        for (var i = 0; i < json.layers.length; i++)

            {

            var ret = test_id(json.layers, id, 0);

 

            if (ret)

                {

                if (json.layers.artboard) return json.layers.artboard.artboardRect;

                else return not_artboard_rect;

                break;       

                }

            }

       

        return not_artboard_rect;       

        }

    catch (e) { alert(e); }

    }

Legend
February 21, 2018
X-Raym
X-RaymAuthor
Participating Frequently
February 21, 2018

r-bin

Hi, thanks for your very quick assistance (and your initial code snippet) !

This get_smart_object_corners() function doesn't take any parameter, how come ?

How to pass a Layer as parameter to it ?

My ultimate goal is to merge this code snippet to

Adobe-Export-Scripts/Export Layer Coordinates Photoshop.jsx at master · bronzehedwick/Adobe-Export-Scripts · GitHub

As you can see L44, the function need to take a Layer as parameter.

Many thanks again!

(let me know if you prefer me to answer in the original thread).

r-binCorrect answer
Legend
February 21, 2018

Try this function

function get_layer_bounds(layer)

    {

    try

        {

        if (layer.kind == LayerKind.SMARTOBJECT)

            {

            var layer0 = activeDocument.activeLayer;

            activeDocument.activeLayer = layer;

            var r = new ActionReference();

            r.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );

            var d = executeActionGet(r).getObjectValue(stringIDToTypeID("smartObjectMore")).getList(stringIDToTypeID("transform"));

            var x = [d.getDouble(0), d.getDouble(2), d.getDouble(4), d.getDouble(6)];

            var y = [d.getDouble(1), d.getDouble(3), d.getDouble(5), d.getDouble(7)];

          

            var l = [Math.min(x[0], Math.min(x[1], Math.min(x[2], x[3]))) ];

            var r = [Math.max(x[0], Math.max(x[1], Math.max(x[2], x[3]))) ];

            var t = [Math.min(y[0], Math.min(y[1], Math.min(y[2], y[3]))) ];

            var b = [Math.max(y[0], Math.max(y[1], Math.max(y[2], y[3]))) ];

            activeDocument.activeLayer = layer0;

            return [ UnitValue(l,"px"), UnitValue(t,"px"), UnitValue(r,"px"), UnitValue(b,"px") ];

            }

        else

            return layer.boundsNoEffects;

        }

    catch (e) { alert(e); }

    }