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
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
...
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 )
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
Copy link to clipboard
Copied
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"});
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 !!
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
Copy link to clipboard
Copied
hi rob day,
It would be great if you check your inbox .
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);
The width of the frame would be b[3]-b[1], and the height would be b[2]-b[0]
Copy link to clipboard
Copied
Hi @rob day Thank you so much for your valuable suggestion!!!!
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
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"
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
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.
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)
Copy link to clipboard
Copied
How are you getting the bounds out of your XML tag?
Copy link to clipboard
Copied
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];
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:
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];
}
Copy link to clipboard
Copied
@rob day yes you are right it has ,it just copy paste issue..:-)
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"});
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."
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
Copy link to clipboard
Copied
@rob day if we are placing .pdf as image is that valid as well
Copy link to clipboard
Copied
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 ]);