• 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?

New Here ,
Oct 14, 2022 Oct 14, 2022

Copy link to clipboard

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

Translate

Translate

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 guidelines

correct answers 1 Correct answer

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;

//alert the current selection’s bounds
var b = app.selection[0].geometricBounds;
alert("Selection’s Bounds: " + b);

//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 the new bounds
alert("Selection’s New Bo
...

Likes

Translate

Translate
Community Expert ,
Oct 14, 2022 Oct 14, 2022

Copy link to clipboard

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
( Adobe Community Expert )

Likes

Translate

Translate

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 guidelines
New Here ,
Oct 16, 2022 Oct 16, 2022

Copy link to clipboard

Copied

Hi Uwe Laubender,

Thank you so much for your helpfull suggestion,

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:

<ad>
<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"/>

</ad>

 

pos =Rect A

clip= Rect B

 

Thank You in Advance

 

Likes

Translate

Translate

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 guidelines
New Here ,
Oct 17, 2022 Oct 17, 2022

Copy link to clipboard

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

Translate

Translate

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 guidelines
Community Expert ,
Oct 17, 2022 Oct 17, 2022

Copy link to clipboard

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];
}

p.rectangles.add ({ geometricBounds: [y1,x1,y2,x2], fillColor:"Paper"});

 

 

Screen Shot 2.pngScreen Shot 3.png

Likes

Translate

Translate

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 guidelines
New Here ,
Oct 17, 2022 Oct 17, 2022

Copy link to clipboard

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

Translate

Translate

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 guidelines
Community Expert ,
Oct 17, 2022 Oct 17, 2022

Copy link to clipboard

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

 

Screen Shot 4.png

Likes

Translate

Translate

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 guidelines
New Here ,
Oct 17, 2022 Oct 17, 2022

Copy link to clipboard

Copied

hi rob day,

It would be great if you check your inbox .

Likes

Translate

Translate

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 guidelines
Community Expert ,
Oct 17, 2022 Oct 17, 2022

Copy link to clipboard

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;

//alert the current selection’s bounds
var b = app.selection[0].geometricBounds;
alert("Selection’s Bounds: " + b);

//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 the new bounds
alert("Selection’s New Bounds: " + app.selection[0].geometricBounds);

 

 

 

Screen Shot 9.png

 

 

Screen Shot 10.png

 

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

Likes

Translate

Translate

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 guidelines
New Here ,
Oct 17, 2022 Oct 17, 2022

Copy link to clipboard

Copied

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

Likes

Translate

Translate

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 guidelines
Community Expert ,
Oct 17, 2022 Oct 17, 2022

Copy link to clipboard

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

Translate

Translate

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 guidelines
New Here ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

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

Translate

Translate

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 guidelines
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

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

Translate

Translate

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 guidelines
New Here ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

Copied

@rob day  yes it is input from xml 

<ad>
<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>

</ad>

 

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

sukriti29_0-1666097240469.png

please see this image for better understanding

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

<ad>

    <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]

                … …

</ad>

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

Translate

Translate

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 guidelines
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

Copied

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

Likes

Translate

Translate

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 guidelines
New Here ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

Copied

@rob day 

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

Translate

Translate

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 guidelines
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

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:

 

Screen Shot 23.pngScreen Shot 24.png

Likes

Translate

Translate

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 guidelines
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

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

Translate

Translate

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 guidelines
New Here ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

Copied

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

Likes

Translate

Translate

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 guidelines
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

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"});

 

Screen Shot 25.png

Likes

Translate

Translate

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 guidelines
New Here ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

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

Translate

Translate

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 guidelines
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

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

Screen Shot 27.png

Likes

Translate

Translate

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 guidelines
New Here ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

Copied

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

Likes

Translate

Translate

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 guidelines
New Here ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

Copied

@rob day 

 

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

Likes

Translate

Translate

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 guidelines
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

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

Translate

Translate

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 guidelines