Skip to main content
Known Participant
June 10, 2020
Answered

[Script] How can I get the width and height?

  • June 10, 2020
  • 2 replies
  • 7783 views

How can you measure the width and height of an item?

 

I tryed code:

 

document = app.activeDocument;

layer = document.layers.getByName('Test');

item = layer.pageItem.getByName('A');

 

alert("WIDTH: "+item.width+", HEIGHT: "+item.height);

 

But the data was strangely printed.

 

width: 31mm

height: 4mm

 

Result data:

width: 101mm

height= 24mm

This topic has been closed for replies.
Correct answer m1b

Hi SonDaehyeon,

 

That is strange. The values are not even the right proportions. Is there a chance that the script is selecting an item that is different to the selection in your screen shot?

 

Could you try:

item = app.activeDocument.selection[0];

and see if it matches the width and height you see in the UI? (Note that the value from extendscript will be in points, so you will need to divide by 72 and multiple by 25.4 to get mm I think.)

2 replies

Disposition_Dev
Legend
June 12, 2020

As m1b says, extendscript works in points, not mm. 

According to google, 1pt = 0.352778mm

 

It should also be noted that the "width" and "height" properties can be deceiving. For example if you're trying to measure the width of a clipping mask, all artwork inside the clipping mask will also be counted. See the following screenshots:

 

In the first image, there are 3 shapes.

  • the top shape is a simple rectangle 250pt wide. If you measure a shape like this, you can be confident in the result from extendscript. In other words, the width property in extendscript will match the width property in the UI transform panel.
  • the middle shape is a clipping mask where the clipping path is a rectangle 250pt wide. In this case, the UI will show the width as 250pt... However, if you ask extendscript for the width of that object, it will return 353.4545 pt.. what?!
  • the bottom shape is the exact same clip group displayed in "outline mode".  Here you can see the entire star, even though half of it is clipped and thus invisible. Unfortunately, when you use extendscript to get the width of an object, this is what extendscript sees. Even though the clipped artwork is normally invisible, it still gets included in the "width" (or height).

In the second image, I showed the difference between the width property as shown in the UI (top shape) and the width property in extendscript (bottom shape). 

 

If you're checking the width/height of an object and the resulting numbers don't match what you think they should be, check to see if there's any clipped artwork that is adulterating the result. If there is indeed a clipping mask, then you can get around this oddity by simply getting the width/height of the clipping path (usually the topmost path item in a clip group.. see the 3rd screenshot). 

 

Hope this helps.

 

 

m1b
Community Expert
Community Expert
June 12, 2020

Goods point! I hadn't thought of that possibility.

 

Also, SonDaehyeon, it might be good to look into visibleBounds versus geometricBounds if you are interested in getting an item's size. VisibleBounds includes strokes (and maybe effects?) whereas I believe geometricBounds is just measuring the underlying geometry, eg. the path(s).

m1b
Community Expert
Community Expert
June 12, 2020

Unfortunately, m1b... Visible bounds gives the same result. as "width".

 

You are correct that visibleBounds includes the stroke whereas geometric bounds only includes the actual path points. However.. visibleBounds still measures the invisible stuff...

 

because.... logic, i guess?

 

check out this screenshot of a clipping mask. I queried the width (w), visibleBounds (vb), and geometricBounds (gb).

There are no strokes here, so all the measurements are the same. No distinction between visible bounds and width. =(


Yes that is unfortunate that none of the dimension getters take into account clipping groups. I hadn't realised.

 

For anyone else reading, here's a function that illustrates the way clipping groups are structured. It gets the visibleBounds of a normal item, or of the clipping mask item of a clipping group. I wrote it for my own education—haven't rigorously tested! 🙂

 

 

function getVisibleBounds(item, geometric) {
    var bounds;

    // `clipped` is the property given to the clipping *group*
    if (item.typename == "GroupItem" && item.clipped) {
        var clippingItem;

        // look at all the items in the group to find the clipping item
        for (var i = 0; i < item.pageItems.length; i++) {

            // `clipping` is the property given to the item doing the clipping
            if (item.pageItems[i].clipping) {

                // found the clipping item!
                clippingItem = item.pageItems[i];
                break;

                // this part just does the same thing for CompoundPathItems
            } else if (item.pageItems[i].typename == "CompoundPathItem") {
                if (item.pageItems[i].pathItems[0].clipping) {
                    clippingItem = item.pageItems[i];
                    break;
                }
            }
        }
        bounds = geometric ? clippingItem.geometricBounds : clippingItem.visibleBounds;
    } else {

        // this is any item except a clipping group
        bounds = geometric ? item.geometricBounds : item.visibleBounds;
    }
    return bounds;
}

 

 

 

 

Thanks, William for showing me this problem.

 

Regards,

Mark

m1b
Community Expert
m1bCommunity ExpertCorrect answer
Community Expert
June 10, 2020

Hi SonDaehyeon,

 

That is strange. The values are not even the right proportions. Is there a chance that the script is selecting an item that is different to the selection in your screen shot?

 

Could you try:

item = app.activeDocument.selection[0];

and see if it matches the width and height you see in the UI? (Note that the value from extendscript will be in points, so you will need to divide by 72 and multiple by 25.4 to get mm I think.)

Known Participant
June 10, 2020