Copy link to clipboard
Copied
I'm trying to write a script that needs to get what I would think of as the visible bounds object, or bounding box when placing an AI file, but the bounding box includes extra space around the art when it is placed with PDF place option, Crop to Bounding Box (visible layers only), (see the attached screenshot), which makes it impossible to get the bounds of the art excluding handles that extend past the art (or in some cases, art hidden by a clipping mask). (re)Placing the art with the PDF place option to Crop to Art makes the art shift, which is not what I want. Is there an object or property that better represents the bounds of art that doesn't give you space around the visible art when art is placed to bounding box? Geometric bounds doesn't work either. I'd like to be able to relink art to from Crop to Bounding Box to Crop to Media without it shifting, which only seems to work if the visible bounds have no space between the bound and the art. There doesn't seem to be a way to do this without a script, or possibly even with a script. It's driving me nuts.
set {y1, x1, y2, x2} to get visible bounds of graphic 1 of selection
[ attachments inserted as inline image by moderator ]
Copy link to clipboard
Copied
Hi Foboid,
I don't think you can do this with InDesign alone. Hm. One workaround could be:
Open the placed PDF in PhotoShop and render it to a highres image, perhaps 1200 ppi, get the area of drawing pixels with a selection there, calculate position and size of the selection and use the calculated values to crop the placed PDF in InDesign. That could be done by scripting, but requires knowledge in PhotoShop scripting and cross-scripting between InDesign and PhotoShop using bridgeTalk.
All that with ExtendScript (JavaScript); cannot tell if there is a bridgeTalk module available for AppleScript.
Regards,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
Hi Uwe, AppleScript doesn’t need Bridgetalk, communicating between apps is simply a matter of telling Photoshop to activate and open the file. The simplicity of communicating between apps is probably the only advantage AS has over JS.
Copy link to clipboard
Copied
> The simplicity of communicating between apps is probably the only advantage AS has over JS
Another related advantage (don't know if it's changed) is controlling several apps and the OS in the same script.
Copy link to clipboard
Copied
After seeing into your provided screenshots:
There you show very basic drawings. For graphics like that it should be easier. But as soon as your graphics get more complex, applied effects like drop shadows etc.pp. the cross-scripting way between InDesign and PhotoShop is required.
And the result, a script that can do all this, is way out of focus of this forum.
This requires hard work and a lot of testing.
Regards,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
Are you saving the Illustrator file as a PDF or an AI file? With .AI you get the Art Crop To option, which seems to be what you are looking for:
Copy link to clipboard
Copied
Uwe’s idea of getting the bounds from Photoshop seems to work. If I open the PDF in PS using Bounding Box as the crop, I can get the dimensions of the left, top, right and bottom transparent pixels by selecting the object and then selecting all.
Direct Select the PDF and try this :
tell application id "com.adobe.indesign"
set vp to properties of view preferences of active document
set properties of view preferences to {horizontal measurement units:inches, vertical measurement units:inches}
set tp to file path of item link of selection
set hs to (horizontal scale of selection) / 100
set vs to (vertical scale of selection) / 100
parent of selection fit given frame to content
set {a, b, c, d} to geometric bounds of selection
set {lt, tp, rt, bm} to my getTrim(tp)
set geometric bounds of parent of selection to {a - (tp * vs), b - (lt * hs), c - (bm * vs), d - (rt * hs)}
set properties of view preferences of active document to vp
end tell
--returns an array with left, top, right, and bottom amounts to trim
on getTrim(p)
tell application id "com.adobe.photoshop"
set ruler units of settings to inch units
set openOptions to {class:PDF open options, constrain proportions:true, mode:grayscale, resolution:1200, crop page:bounding box}
open file p with options openOptions
tell current document
load selection from channel 1 with inverting
set {a, b, c, d} to bounds of selection
select all
set {e, f, g, h} to bounds of selection
set trm to {e - a, f - b, g - c, h - d}
close saving no
end tell
end tell
return trm
end getTrim
Placed with Crop To as Bounding Box Visible:
The script sets the parent frame to the art.
Copy link to clipboard
Copied
Rob,
Thank you (and everyone else) for your quick reply. Your answer gave me an idea.
I decided to come at it from the other way and set the artboard to the visible bounds in Illustrator, which makes it easier to work with, especially in the case where the art is all white, or it needs to align exactly with other links (think spot UV).
I worry that even at 1200dpi, there is still some rounding of numbers happening. I think someone could probably replace a channel selection with transparency selection to make your script more versitile, but I didn't dig around to find out the object for that. I may come back to your method if my method doesn't work for raster effects or the like.
Anyway, the object of the day is... control bounds
This script will set the (first) artboard to the visible bounds and leave you with a guide where the artboard used to be (just incase you need to revert). Sorry if it's a little clunky.
tell application id "com.adobe.Illustrator"
activate
tell current document
set myObjCount to count of page item
set myLayerCount to count of layer
set myLockedObject to {}
set myLockedLayer to {}
set myControlBounds to {}
repeat with l from 1 to myLayerCount
if locked of layer l is true then
set end of myLockedLayer to l
set locked of layer l to false
end if
end repeat
repeat with i from 1 to myObjCount
if locked of page item i is true then
set end of myLockedObject to i
set locked of page item i to false
end if
set selected of page item i to true
set end of myControlBounds to control bounds of page item i
set selected of page item i to false
end repeat
make new layer with properties {name:"TEMP_BOUNDS"}
repeat with p in myControlBounds
make new rectangle with properties {bounds:p}
end repeat
set artDim to visible bounds
set theAB to artboard rectangle of artboard 1
make new layer with properties {name:"Original Artboard_guides"}
set oldArtBoard to make new rectangle with properties {bounds:theAB}
set guides of oldArtBoard to true
set xx1 to (item 1 of artDim) + 0.5
set yy1 to (item 2 of artDim) - 0.5
set xx2 to (item 3 of artDim) - 0.5
set yy2 to (item 4 of artDim) + 0.5
make new layer with properties {name:"*ID FRAME*"}
make new rectangle with properties {bounds:{xx1, yy1, xx2, yy2}}
set selection to page item 1 of layer "*ID FRAME*"
set selBounds to the visible bounds of selection
set artboard rectangle of artboard 1 to selBounds
delete layer "*ID FRAME*"
delete layer "TEMP_BOUNDS"
repeat with m in myLockedObject
set locked of page item m to true
end repeat
repeat with n in myLockedLayer
set locked of layer n to true
end repeat
end tell
end tell
Copy link to clipboard
Copied
sorry 🙂
set artDim to geometric bounds
Copy link to clipboard
Copied
I think someone could probably replace a channel selection with transparency selection to make your script more versitile
You can’t load a Layer’s transparency natively via Applescript, but you can with a do javascript. Use this handler:
tell application id "com.adobe.photoshop"
tell current document
my loadTransparency()
end tell
end tell
--Loads the active layer’s transparency as a selection
on loadTransparency()
tell application id "com.adobe.photoshop"
do javascript "
var d = new ActionDescriptor();
var r1 = new ActionReference();
var r2 = new ActionReference();
r1.putProperty( stringIDToTypeID( 'channel' ), stringIDToTypeID( 'selection' ) );
d.putReference( stringIDToTypeID( 'null' ), r1 );
r2.putEnumerated( stringIDToTypeID( 'channel' ), stringIDToTypeID( 'channel' ), stringIDToTypeID( 'transparencyEnum' ) );
d.putReference( stringIDToTypeID( 'to' ), r2 );
executeAction( stringIDToTypeID( 'set' ), d, DialogModes.NO );
" show debugger on runtime error
end tell
end loadTransparency
Copy link to clipboard
Copied
This is what I ended up using. I didn't need to select each object to get the control bounds—which takes a while... I could probably widdle it down further, but for the sake of anyone who is looking for solutions, this works for me. It sets the artboard to the visible bounds (doesn't work for objects in clipping masks or live type, but seems to work for effects like drop shadow) to match how InDesign sees a link placed to visible bounds.
tell application id "com.adobe.Illustrator"
activate
ignoring application responses
display dialog "This may take a while, please wait." buttons {"OK"} default button 1 giving up after 3
end ignoring
delay 1
tell current document
set myObjCount to count of page item
set myLayerCount to count of layer
set myLockedObject to {}
set myLockedLayer to {}
set myControlBounds to {}
repeat with l from 1 to myLayerCount
if locked of layer l is true then
set end of myLockedLayer to l
set locked of layer l to false
end if
end repeat
repeat with i from 1 to myObjCount
if locked of page item i is true then
set end of myLockedObject to i
set locked of page item i to false
end if
set end of myControlBounds to control bounds of page item i
end repeat
make new layer with properties {name:"TEMP_BOUNDS"}
repeat with p in myControlBounds
make new rectangle with properties {bounds:p}
end repeat
set artDim to geometric bounds
set theAB to artboard rectangle of artboard 1
make new layer with properties {name:"Original Artboard_guides"}
set oldArtBoard to make new rectangle with properties {bounds:theAB}
set guides of oldArtBoard to true
set xx1 to (item 1 of artDim)
set yy1 to (item 2 of artDim)
set xx2 to (item 3 of artDim)
set yy2 to (item 4 of artDim)
make new layer with properties {name:"*ID FRAME*"}
make new rectangle with properties {bounds:{xx1, yy1, xx2, yy2}}
set selection to page item 1 of layer "*ID FRAME*"
set selBounds to the geometric bounds of selection
set artboard rectangle of artboard 1 to selBounds
delete layer "*ID FRAME*"
delete layer "TEMP_BOUNDS"
repeat with m in myLockedObject
set locked of page item m to true
end repeat
repeat with n in myLockedLayer
set locked of layer n to true
end repeat
end tell
end tell
Copy link to clipboard
Copied
The simple script:
tell application id "com.adobe.Illustrator"
activate
tell current document
set myObjCount to count of page item
set myControlBounds to {}
repeat with i from 1 to myObjCount
set end of myControlBounds to control bounds of page item i
end repeat
make new layer with properties {name:"TEMP_BOUNDS"}
repeat with p in myControlBounds
make new rectangle with properties {bounds:p}
end repeat
set artDim to geometric bounds
set theAB to artboard rectangle of artboard 1
make new layer with properties {name:"Original Artboard_guides"}
set oldArtBoard to make new rectangle with properties {bounds:theAB}
set guides of oldArtBoard to true
set xx1 to (item 1 of artDim)
set yy1 to (item 2 of artDim)
set xx2 to (item 3 of artDim)
set yy2 to (item 4 of artDim)
make new layer with properties {name:"*ID FRAME*"}
make new rectangle with properties {bounds:{xx1, yy1, xx2, yy2}}
set selection to page item 1 of layer "*ID FRAME*"
set selBounds to the geometric bounds of selection
set artboard rectangle of artboard 1 to selBounds
delete layer "*ID FRAME*"
delete layer "TEMP_BOUNDS"
end tell
end tell
Copy link to clipboard
Copied
I'm clearly a beginner, keep changing my answer (this excudes hidden items).
tell application id "com.adobe.Illustrator"
activate
tell current document
set myObjCount to count of page item
set myControlBounds to {}
repeat with i from 1 to myObjCount
if hidden of page item i is false then
set end of myControlBounds to control bounds of page item i
end if
end repeat
make new layer with properties {name:"TEMP_BOUNDS"}
repeat with p in myControlBounds
make new rectangle with properties {bounds:p}
end repeat
set artDim to geometric bounds
set theAB to artboard rectangle of artboard 1
make new layer with properties {name:"Original Artboard_guides"}
set oldArtBoard to make new rectangle with properties {bounds:theAB}
set guides of oldArtBoard to true
set xx1 to (item 1 of artDim)
set yy1 to (item 2 of artDim)
set xx2 to (item 3 of artDim)
set yy2 to (item 4 of artDim)
make new layer with properties {name:"*ID FRAME*"}
make new rectangle with properties {bounds:{xx1, yy1, xx2, yy2}}
set selection to page item 1 of layer "*ID FRAME*"
set selBounds to the geometric bounds of selection
set artboard rectangle of artboard 1 to selBounds
delete layer "*ID FRAME*"
delete layer "TEMP_BOUNDS"
end tell
end tell
Copy link to clipboard
Copied
Hi Rob,
I think, we need a sample AI file and a sample InDesign document from our OP Fabioid.
Hm. Maybe there is a stray single path point, a remnant of a frame that was not fully deleted?
Regards,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
I’ve never noticed this before, but with .AI files the Crop To Art option is always available, which is what I think @Fobioid wants—there’s no extra white space. With PDF’s the Art option is often grayed out, but not all of the time and I’m not sure why.