Skip to main content
X-Raym
Participating Frequently
February 21, 2018
解決済み

Get Layer Transform X Y Top Left Coordinate Position

  • February 21, 2018
  • 返信数 3.
  • 15041 ビュー

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 !

このトピックへの返信は締め切られました。
解決に役立った回答 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

X-Raym
X-Raym作成者
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-Raym作成者
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-Raym作成者
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).

X-Raym
X-Raym作成者
Participating Frequently
February 21, 2018

If you exclude Transform Warp and I think  you should all the other Transform have the same user interface only their operation differs. How dragging with the mouse function differ.  All record in the history palette as free transform even Transform Warp.  Transform Warp though has a different UI interface and the same interface in the tools options bar there is a little icon that you can to toggle between the two transform UI.  You can use both transforming a layer.  So a transformed smart object transform can have setting for both interfaces.  I would think all smart object layers will have standard free transform settings and  some Smart object layers associated transform may have additional  transform warp settings.  The script seems the get the Free Transform four corners in a sequence that a selection using them will show when extreme distortion was used causing sides to crossover an other,


JJMack

These are definitely complex cases, where the definition of Top Left XY may no be the same for everyone one

I consider this should be part of a wider feature request for getting XY of all Smart Layers corners.

I mark r-bin​ solution as a good one for now (as it does what I was looking for in my case), and I'll update if he or someone else come with a solution which could handle these cases.

Thanks for having taken the time to digg these possible issues !