Skip to main content
Known Participant
April 27, 2024
Answered

Photoshop ExtendScript Frame Bounds

  • April 27, 2024
  • 3 replies
  • 850 views

Hello,

I'm encountering an issue in ExtendScript where accessing the 'bounds' property of a frame incorrectly returns the dimensions of the image contained within it, rather than those of the frame itself.

This occurs when I select a frame and attempt to retrieve its bounds, expecting to see the frame's actual size.

Could someone please advise on how to accurately obtain the frame's bounds or if there is a workaround for this issue?

Thanks!

Correct answer Stephen Marsh
quote

I don't use Frames, but as far as I know, a Frame physically consists of at least two "layers".

This is a folder and a layer within that folder.

The result may depend on whether the "folder" or layer within it is currently active.

 


By @r-bin

 

 

Good point, my code above only works if the frame is selected, not the content of the frame (if it exists).

 

EDIT: This revision will hopefully work better:

 

/* 
Active Frame Dimensions.jsx
v1.1 - 28th April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-extendscript-frame-bounds/td-p/14583991
*/

#target photoshop

// Frame content active
if (app.activeDocument.activeLayer.parent.name != app.activeDocument.name) {
    app.activeDocument.activeLayer = app.activeDocument.activeLayer.parent;
    var ref = new ActionReference();
    ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
    var frameRect = executeActionGet(ref).getObjectValue(stringIDToTypeID("framedGroup")).getObjectValue(stringIDToTypeID("framedGroupRect"));
    var frameRectWidth = new UnitValue(frameRect.getDouble(stringIDToTypeID("right")) - frameRect.getDouble(stringIDToTypeID("left")), "px");
    var frameRectHeight = new UnitValue(frameRect.getDouble(stringIDToTypeID("bottom")) - frameRect.getDouble(stringIDToTypeID("top")), "px");
    app.activeDocument.activeLayer = app.activeDocument.activeLayer.layers[0];
    alert("Frame dimensions - W: " + frameRectWidth.value + "px X H: " + frameRectHeight.value + "px");
// Frame active
} else {
    var ref = new ActionReference();
    ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
    var frameRect = executeActionGet(ref).getObjectValue(stringIDToTypeID("framedGroup")).getObjectValue(stringIDToTypeID("framedGroupRect"));
    var frameRectWidth = new UnitValue(frameRect.getDouble(stringIDToTypeID("right")) - frameRect.getDouble(stringIDToTypeID("left")), "px");
    var frameRectHeight = new UnitValue(frameRect.getDouble(stringIDToTypeID("bottom")) - frameRect.getDouble(stringIDToTypeID("top")), "px");
    alert("Frame dimensions - W: " + frameRectWidth.value + "px X H: " + frameRectHeight.value + "px");
}

 

 

3 replies

Legend
April 28, 2024

I don't use Frames, but as far as I know, a Frame physically consists of at least two "layers".

This is a folder and a layer within that folder.

The result may depend on whether the "folder" or layer within it is currently active.

 

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
April 28, 2024
quote

I don't use Frames, but as far as I know, a Frame physically consists of at least two "layers".

This is a folder and a layer within that folder.

The result may depend on whether the "folder" or layer within it is currently active.

 


By @r-bin

 

 

Good point, my code above only works if the frame is selected, not the content of the frame (if it exists).

 

EDIT: This revision will hopefully work better:

 

/* 
Active Frame Dimensions.jsx
v1.1 - 28th April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-extendscript-frame-bounds/td-p/14583991
*/

#target photoshop

// Frame content active
if (app.activeDocument.activeLayer.parent.name != app.activeDocument.name) {
    app.activeDocument.activeLayer = app.activeDocument.activeLayer.parent;
    var ref = new ActionReference();
    ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
    var frameRect = executeActionGet(ref).getObjectValue(stringIDToTypeID("framedGroup")).getObjectValue(stringIDToTypeID("framedGroupRect"));
    var frameRectWidth = new UnitValue(frameRect.getDouble(stringIDToTypeID("right")) - frameRect.getDouble(stringIDToTypeID("left")), "px");
    var frameRectHeight = new UnitValue(frameRect.getDouble(stringIDToTypeID("bottom")) - frameRect.getDouble(stringIDToTypeID("top")), "px");
    app.activeDocument.activeLayer = app.activeDocument.activeLayer.layers[0];
    alert("Frame dimensions - W: " + frameRectWidth.value + "px X H: " + frameRectHeight.value + "px");
// Frame active
} else {
    var ref = new ActionReference();
    ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
    var frameRect = executeActionGet(ref).getObjectValue(stringIDToTypeID("framedGroup")).getObjectValue(stringIDToTypeID("framedGroupRect"));
    var frameRectWidth = new UnitValue(frameRect.getDouble(stringIDToTypeID("right")) - frameRect.getDouble(stringIDToTypeID("left")), "px");
    var frameRectHeight = new UnitValue(frameRect.getDouble(stringIDToTypeID("bottom")) - frameRect.getDouble(stringIDToTypeID("top")), "px");
    alert("Frame dimensions - W: " + frameRectWidth.value + "px X H: " + frameRectHeight.value + "px");
}

 

 

Stephen Marsh
Community Expert
Community Expert
April 28, 2024

How does the following code work for you?

 

/* 
Active Frame Dimensions.jsx
v1.0 - 28th April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-extendscript-frame-bounds/td-p/14583991
*/

#target photoshop

var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var frameRect = executeActionGet(ref).getObjectValue(stringIDToTypeID("framedGroup")).getObjectValue(stringIDToTypeID("framedGroupRect"));
var frameRectWidth = new UnitValue(frameRect.getDouble(stringIDToTypeID("right")) - frameRect.getDouble(stringIDToTypeID("left")), "px");
var frameRectHeight = new UnitValue(frameRect.getDouble(stringIDToTypeID("bottom")) - frameRect.getDouble(stringIDToTypeID("top")), "px");
alert("Frame dimensions - W: " + frameRectWidth.value + "px X H: " + frameRectHeight.value + "px");

 

 

Known Participant
April 28, 2024

It worked! The solution you provided was spot-on and precisely what I needed.

Initially, I took a different approach to determine the frame size, but it only yielded the dimensions of the image content rather than the frame itself, the code that didn't work:

var layer = doc.layers.getByName(layerName);
var frameBounds = layer. Bounds;
var frameX = frameBounds[0].as('px');
var frameY = frameBounds[1].as('px');
var frameWidth = frameBounds[2].as('px') - frameX;
var frameHeight = frameBounds[3].as('px') - frameY;
$.writeln("frameWidth: ", frameWidth);
$.writeln("frameHeight: ", frameHeight);

 

Could you explain how you developed the code you provided?
I'd love to understand your thought process and how you approach such challenges.

Once again, thank you for your swift and effective assistance. Your expertise is deeply valued.

Stephen Marsh
Community Expert
Community Expert
April 28, 2024
quote

Could you explain how you developed the code you provided?
I'd love to understand your thought process and how you approach such challenges.

Once again, thank you for your swift and effective assistance. Your expertise is deeply valued.


By @Adi1231234

 

My thought process was knowing that artboards and frames are "almost the same thing" in this respect, I modified existing code by a user named @Rune LH to get the artboard bounds and modified it to specifically work with frames:

 

 
I can't write such advanced AM code, however, I can sometimes adapt it. It took a little bit of trial and error to get the stringIDToTypeID("framedGroup") and stringIDToTypeID("framedGroupRect") correct by looking at code recorded by ScriptingListener and other scripts that deal with frames.
 
P.S. Another option could have been to load the frame as a selection, and then get the bounds of the selection, similar to this:
 
// Load frame as selection
var s2t = function (s) {
	return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
reference.putProperty( s2t( "channel" ), s2t( "selection" ));
descriptor.putReference( s2t( "null" ), reference );
reference2.putEnumerated( s2t( "path" ), s2t( "path" ), s2t( "vectorMask" ));
reference2.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "to" ), reference2 );
descriptor.putInteger( s2t( "version" ), 1 );
descriptor.putBoolean( s2t( "vectorMaskParams" ), true );
executeAction(s2t("set"), descriptor, DialogModes.NO);
// Selection bounds
var origRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var selectionBounds = activeDocument.selection.bounds;
var selectionLeft = selectionBounds[0].value;
var selectionTop = selectionBounds[1].value;
var selectionRight = selectionBounds[2].value;
var selectionBottom = selectionBounds[3].value;
var selectionWidth = selectionBounds[2].value - selectionBounds[0].value;
var selectionHeight = selectionBounds[3].value - selectionBounds[1].value;
var selectionXCenter = (selectionLeft) + (selectionWidth / 2);
var selectionYCenter = (selectionTop) + (selectionHeight / 2);
alert("Frame dimensions - W: " + selectionWidth + "px X H: " + selectionHeight + "px");
app.activeDocument.selection.deselect();
app.preferences.rulerUnits = origRulerUnits;
Stephen Marsh
Community Expert
Community Expert
April 27, 2024

@Adi1231234 – So what's the code that you are currently using to get the frame bounds?