• Global community
• Language:
• Deutsch
• English
• Español
• Français
• Português
• 日本語コミュニティ
Dedicated community for Japanese speakers
• 한국 커뮤니티
Dedicated community for Korean speakers
• Clipping a Rectangle using Extendscript?

# Clipping a Rectangle using Extendscript?

New Here ,
Oct 14, 2022 Oct 14, 2022

Copied

I'm trying to write a function that takes two possibly overlapping rectangles and returns an array of rectangles that cover the area of rectangle A, but exclude area of rectangle B.

rect A= x1="800.7" x2="1000.35" y1="11.37" y2="90.17"

rect B= x1="833.967 " x2="1000.697" y1="11.37" y2="90.17"T

i want to place my image in the resulting rectangle

result rect= rect A- rect B

i am available to get the bounds for both the reactangles but not sure how to get the result reactangle and also how to place image in the resultanted rectangle please the attachment for proper understanding

TOPICS
Scripting

Views

309

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

Community Expert , Oct 17, 2022 Oct 17, 2022

Hi @codevita , I saw your note. The container frames’s geometricBounds are relative to the page not the image—[Y1, X1, Y2, X2]:

``````//the amount to clip
var clipX = 85;

var b = app.selection[0].geometricBounds;

//add the clip amount to the x1 value  (b[1]+clipX) moves the left edge of the frame to the right
app.selection[0].geometricBounds = [b[0], b[1]+clipX, b[2], b[3]]

...

Likes

30 Replies 30
Community Expert ,
Oct 14, 2022 Oct 14, 2022

Copied

Hi @codevita ,

ask yourself how you would do this in the GUI.

You'd align both rectangles vertically and then use one of the pathfinder tools to create A minus B.

This is scriptable.

Also possible:

create a new rectangle out of your values.

Note, that geometricBounds are defined with an array of values:

[

y1, x1,

y2, x2

]

In ExtendScript code, not optimized or generalized at all:

``````// Rectangle A selected using the GUI
var rectA = app.selection[0];

// Rectangle B selected using the Shift key after rectangle A was selected:
var rectA = app.selection[1];

// For now I do not use rectangle B, just rectangle A to define the spread where the new rectangle should be added:

// Create a new rectangle without fill and stroke on the spread:
var newRect = rectA.parent.rectangles.add({ fillColor : "None" , strokeColor : "None" , strokeWeight : 0 });

// Assign new values for property geometricBounds in Points:
// First use your concrete values without any variables to get a quick result:
newRect.geometricBounds = [11.37, 800.7 , 90.17 , 800.7 + 833.967 - 800.7 ] ;

// You'd need a valid file object to do this:
// newRect.place( imageFile );``````

This just as a start to write a more general script.

Look up object File and its constructor in the ExtendScript DOM documentation:

https://www.indesignjs.de/extendscriptAPI/indesign-latest/#File.html

Also object Rectangle and its properties and methods:
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#Rectangle.html#d1e217417__d1e220961

https://www.indesignjs.de/extendscriptAPI/indesign-latest/#Rectangles.html

Regards,
Uwe Laubender

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
New Here ,
Oct 16, 2022 Oct 16, 2022

Copied

Hi Uwe Laubender,

`newRect.geometricBounds = [11.37, 800.7 , 90.17 , 800.7 + 833.967 - 800.7 ] ;`

newRect geometricBounds has some hard coded value can we somehow make it generic so that we can use it for other Bounds value as well....with same intention of getting the clip rectangle(rect A-rect B).

because we are trying to access data from xml and every Ad has thier different bounds.

xml formate:

<pos x1="800.7" x2="1000.35" y1="11.37" y2="90.17"/>

<clip x1="833.967 " x2="1000.697" y1="11.37" y2="90.17"/>

pos =Rect A

clip= Rect B

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
New Here ,
Oct 17, 2022 Oct 17, 2022

Copied

hi Uwe Laubender

Adding to this if we want to crop an image with this bounds

`newRect.geometricBounds = [11.37, 800.7 , 90.17 , 800.7 + 833.967 - 800.7 ]`

.

Please see the image below , i want to clip this image with newRect.geometricBounds

Any suggetsion is highly appreicated.

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Community Expert ,
Oct 17, 2022 Oct 17, 2022

Copied

Hi @codevita , With the 2 frames selected try this:

``````var s = app.activeDocument.selection;
var p=app.activeWindow.activePage;

var a = s[0].geometricBounds;
var b = s[1].geometricBounds;
var y1,x1,y2,x2;

if (a[1]<= b[1]) {
x1 = b[1];
x2 = a[3]
} else {
x1 = a[1]
x2 = b[3]
}

if (a[0]<= b[0]) {
y1 = b[0];
y2 = a[2];
} else {
y1 = a[0];
y2 = b[2];
}

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
New Here ,
Oct 17, 2022 Oct 17, 2022

Copied

hi rob day

Thank you so much for your suggestion ,

basically we are placing image in frame having bound

<pos x1="800.7" x2="1000.35" y1="11.37" y2="90.17"/> ....

now i want to crop this image with bound

<clip x1="833.967 " x2="1000.697" y1="11.37" y2="90.17"/>

and the resultant image is crop one with bounds

x1=33.967 ,x2=1000.697 ,y1=11.37 ,y2=90.17

Please check attachment for better understang .

Appreciated !!

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Community Expert ,
Oct 17, 2022 Oct 17, 2022

Copied

The geometricBounds array is [y1,x1,y2,x2]—not [x1,x2,y1,y2]

``alert("Bounds: " + app.selection[0].geometricBounds)``

This 200 x 100 point rectangle’s bounds are 72, 172, 72, 272

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
New Here ,
Oct 17, 2022 Oct 17, 2022

Copied

hi rob day,

It would be great if you check your inbox .

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Community Expert ,
Oct 17, 2022 Oct 17, 2022

Copied

Hi @codevita , I saw your note. The container frames’s geometricBounds are relative to the page not the image—[Y1, X1, Y2, X2]:

``````//the amount to clip
var clipX = 85;

var b = app.selection[0].geometricBounds;

//add the clip amount to the x1 value  (b[1]+clipX) moves the left edge of the frame to the right
app.selection[0].geometricBounds = [b[0], b[1]+clipX, b[2], b[3]]

alert("Selection’s New Bounds: " + app.selection[0].geometricBounds);``````

The width of the frame would be b[3]-b[1], and the height would be b[2]-b[0]

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
New Here ,
Oct 17, 2022 Oct 17, 2022

Copied

Hi @rob day  Thank you so much for your valuable suggestion!!!!

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Community Expert ,
Oct 17, 2022 Oct 17, 2022

Copied

Can you please let us know which answer is correct - if you can mark it a correct answer or let us know and we can do it for you.

Thanks

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
New Here ,
Oct 18, 2022 Oct 18, 2022

Copied

Hi @rob day

Can we crop image according to the clip bound  x1="800.7 " x2="833.697" y1="11.37" y2="90.17"

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copied

It would be:

``````var x1="800.7";
var x2="833.697";
var y1="11.37";
var y2="90.17";

theImage.parent.geometricBounds[y1,x1,y2,x2]``````

I couldn’t read the screen capture in your message, but it looks like you are trying to convert coordinates from an XML tag into x,y variables. How are you doing that? If you are new to scripting that would be fairly advanced.

Also, you have to set ruler units and ruler origins—looks like you are expecting the document units to be points and the ruler origin to be spread, but the document might be set to something different

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
New Here ,
Oct 18, 2022 Oct 18, 2022

Copied

@rob day  yes it is input from xml

<pos x1="800.7" x2="1000.35" y1="11.37" y2="90.17"/>

<clip x1="800.7 " x2="833.697" y1="11.37" y2="90.17"/>
<orderids>
<orderid name="222.22"/>
<orderid name="222.22"/>
</orderids>

Intially we created a frame with pos bounds and insert ads on it ...now i want to clip this ad with clip bounds.

please see this image for better understanding

PDL file structure would define ad like this for each page pair:

<pos x1="12.7" x2="134.62" y1="281.87" y2="396.17"/>  [existing prop]

<clip x1="12.7" x2="100.62" y1="281.87" y2="396.17"/> [new prop to be added]

… …

where, ‘pos’ defines the boundary of the entire unclipped ad frame and the ‘clip’ coordinates would give the cropped ad boundary seen on each page (pos x1 part can go negative but the clip coordinates will always be positive)

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copied

How are you getting the bounds out of your XML tag?

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
New Here ,
Oct 18, 2022 Oct 18, 2022

Copied

function GetPosition(page, pageNumber, posXMLElement) {
var x1 = Number(posXMLElement.xmlAttributes.itemByName("x1").value);
var x2 = Number(posXMLElement.xmlAttributes.itemByName("x2").value);
var y1 = Number(posXMLElement.xmlAttributes.itemByName("y1").value);
var y2 = Number(posXMLElement.xmlAttributes.itemByName("y2").value);

// this hack shifts the x position over to the right for odd pages except page 1
if ((page.bounds[1] > 0) && (pageNumber != 1)) {
var bounds = page.bounds;
var width = bounds[3] - bounds[1];
x1 = x1 + width;
x2 = x2 + width;
}
return [y1, x1, y2, x2];

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copied

Both the image and its parent frame have bounds, so keep in mind if you move a container frame with a placed image, the frame bounds will move, but the image bounds will remain the same.

Assuming you have the image positioned in its container frame with the "pos" bounds then:

``````//clip coordinates
var x1="12.7";
var x2="100.62";
var y1="281.87";
var y2="396.17";

//the first image on page 1
var img = app.activeDocument.pages[0].allGraphics[0];
//the image’s parent frame
img.parent.geometricBounds = [y1,x1,y2,x2];``````

Page 1 with a single placed image with its parent frame set to the "pos" bounds.

Before and after:

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copied

Also, you have the function’s returned array value outsind of the function, it needs to be inside the last curly brace:

``````var adBounds = GetPosition(page, pageNumber, adXMLElement.xmlElements.item("pos"));

function GetPosition(page, pageNumber, posXMLElement) {
var x1 = Number(posXMLElement.xmlAttributes.itemByName("x1").value);
var x2 = Number(posXMLElement.xmlAttributes.itemByName("x2").value);
var y1 = Number(posXMLElement.xmlAttributes.itemByName("y1").value);
var y2 = Number(posXMLElement.xmlAttributes.itemByName("y2").value);

// this hack shifts the x position over to the right for odd pages except page 1
if ((page.bounds[1] > 0) && (pageNumber != 1)) {
var bounds = page.bounds;
var width = bounds[3] - bounds[1];
x1 = x1 + width;
x2 = x2 + width;
return [y1, x1, y2, x2];
}``````

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
New Here ,
Oct 18, 2022 Oct 18, 2022

Copied

@rob day  yes you are right it has ,it just copy paste issue..:-)

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copied

Also you don’t need the page number test, you can set the ruler orign to page instead.

This should work in case the document’s ruler origin is set to spreads:

``````var adBounds = GetPosition(adXMLElement.xmlElements.item("pos"));

function GetPosition(posXMLElement) {
app.activeDocument.viewPreferences.rulerOrigin = RulerOrigin.PAGE_ORIGIN;
var x1 = Number(posXMLElement.xmlAttributes.itemByName("x1").value);
var x2 = Number(posXMLElement.xmlAttributes.itemByName("x2").value);
var y1 = Number(posXMLElement.xmlAttributes.itemByName("y1").value);
var y2 = Number(posXMLElement.xmlAttributes.itemByName("y2").value);
return [y1, x1, y2, x2];
}``````

This puts the rectangle on page 3 without adding the page width:

``````var doc = app.activeDocument;
//page 3 right hand page
var p = doc.pages[2];
//sets the rulerOrigin to Page
doc.viewPreferences.rulerOrigin = RulerOrigin.PAGE_ORIGIN;
var pos = [10, 10, 100, 100];
var recA = p.rectangles.add ({ geometricBounds: pos, fillColor:"None", strokeColor:"Black"});``````

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
New Here ,
Oct 18, 2022 Oct 18, 2022

Copied

@rob day Thank you ,this something i am not aware of

rob , how can we get the moved  image bounds

which you have mentiioned

"Both the image and its parent frame have bounds, so keep in mind if you move a container frame with a placed image, the frame bounds will move, but the image bounds will remain the same."

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copied

If page 1 has 1 image:

``````var img = app.activeDocument.pages[0].allGraphics[0];

var imgB = img.geometricBounds;
var parB = img.parent.geometricBounds

alert("\rImage Bounds:\r" + imgB + "\r\r Image Container Bounds:\r" + parB)``````

The parent frame crops the image

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
New Here ,
Oct 18, 2022 Oct 18, 2022

Copied

@rob day if we are placing .pdf as image is that valid as well

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
New Here ,
Oct 18, 2022 Oct 18, 2022

Copied

Ok so to be more precise i need to crop my .pdf according to clip bounds

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copied

There’s also the move() method which lets you move the parent frame and its contents. This creates a frame, places a chosen file into the frame, fits the image to the frame proportionally, and then moves the frame and contents to the upper left corner.

``````var doc = app.activeDocument;
var image = File.openDialog("Please try to select the icons folder");
var x1="12.7";
var x2="100.62";
var y1="281.87";
var y2="396.17";
var rect1 = doc.pages[0].rectangles.add({geometricBounds:  [y1, x1, y2, x2], fillColor:"None", strokeColor:"Black"});
rect1.place(image);

//fits the image to the frame
rect1.fit(FitOptions.PROPORTIONALLY);

//move the parent frame and image to x,y
rect1.move([ 0 , 0 ]);``````

Likes

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Resources
Learn and Support
Resources
Crash and Slow Performance