Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

geometricBounds not defined for placed image

Explorer ,
Apr 11, 2011 Apr 11, 2011

Hi all,

I'm trying to place inline graphics into a textFrame, and size them so they're exactly the same width as the textFrame. I'm doing essentially this:

var reportFrame =app.selection[0]; // presumes that a text frame is selected

var graphic= new File("foo.png");

var insPoint = reportFrame.insertionPoints.lastItem();
var inline = insPoint.place(graphic)[0];

if (inline.isValid) {

     var inlineBounds = inline.geometricBounds;

}

The last line fails, even though the inline graphic is valid, because the graphic is larger than the text frame (so the text frame overflows). Apparently in this case, InDesign doesn't keep track of object bounds, since part of the object is outside the frame (makes sense, I guess).

I need to know the size of the graphic so I can correctly scale its parent frame to be the same width as the enclosing textFrame.

I've come up with a workaround which seems to me to be a terrible hack: scale the graphic down to some ridiculously small value (say 5%), at which point it's wholly within the textFrame. At this point I can get the bounds, post-multiply by the scale factor to get the true bounds, compute a true scale factor, and then set the bounds correctly.


Any suggestions about the correct way to deal with this problem? I can use my hack, but then I have to surrender my membership card in the Cool Programmer's Club.

Thanks in advance for any and all advice.

Regards,

Chuck

TOPICS
Scripting
4.5K
Translate
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

LEGEND , Apr 11, 2011 Apr 11, 2011

Hi Chuck!

You can try using pageItem.resolve() and pageItem.reframe() or resize(). I'm pretty sure that works even if it's not composed.

This is one of those things that I've been meaning to try for a long time already, but work keeps getting in the way...

Harbs

Translate
Community Expert ,
Apr 11, 2011 Apr 11, 2011

Maybe you could try this approach:

- take the width of reportFrame

- place the inline

- make the inline's parent (i.e. the rectangle) as wide as reportFrame

- fit the rectangle by using one of the fit options.

Peter

Translate
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 ,
Apr 11, 2011 Apr 11, 2011

You need in fact to use fit() twice:

if (inline.isValid) {
    var gb = inline.geometricBounds;
    gb[3] = reportFrame.geometricBounds[3];
    inline.parent.geometricBounds = gb;
    inline.parent.fit (FitOptions.proportionally);
    inline.parent.fit (FitOptions.frameToContent);
}

Peter

Translate
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
Explorer ,
Apr 11, 2011 Apr 11, 2011

Hi Peter,

Thanks for your suggestions. However, they don't work (for me, anyway) because, even though inline.isValid=true, inline apparently has no geometricBounds. The script fails on this line:

    var gb = inline.geometricBounds;

If I look in the Data Browser, next to "geometricBounds" for the "inline" object, it says "Invalid object for this request."

This is the case, even though the graphic HAS been placed, and if I stop the script I can resize and fit it in the parent textFrame using the UI.

This is on CS5 Windows 7.0.3.535. I haven't tried it yet on Mac.

Regards,

Chuck

Translate
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 ,
Apr 11, 2011 Apr 11, 2011

Strange. It works ok for me. Don't know what to suggest now. . .

Translate
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
Explorer ,
Apr 11, 2011 Apr 11, 2011

Peter,

It fails for me when the placed graphic is too large to fit within the bounds of the textFrame. If the graphic is small enough to fit, it works fine.

Unfortunately, most of the graphics I am working with are larger than the textFrames in which I am placing them, so the script mostly fails.

Have you tried it with a graphic larger than the frame? And are you using Mac or Windows?

Thanks for exploring this.

Regards,

Chuck

Translate
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
Advocate ,
Apr 11, 2011 Apr 11, 2011

If you need the geometric bounds of a newly placed inline item, make sure the parent frame is composed - I've occasionally had that fail at least on InDesign Server CS4.

Of course Chuck is also right with the size of the inline vs. parent frame.

Before resizing, I'd also try to clear that text frame option that limits the inlined object into the frame.

Dirk

Translate
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
Explorer ,
Apr 11, 2011 Apr 11, 2011

Hi Dirk,

Thanks for chiming in. Unfortunately, you also have failed to provide a correct answer, so IBM's Watson remains in the lead.

Here's what I've done to disprove your theory:

A. Manually, in the UI

  1. Created a new empty InDesign document

  2. On page 1 of that document, drew a text frame about 5x5 inches

  3. Chose Object->Text Frame Options, and made sure the "Ignore Text Wrap" checkbox was checked

  4. In that same text frame, typed "Hello, world" followed by a carriage return

  5. With the text cursor still active, chose File->Place, and placed a large (9.6" wide x 7.5" high) PNG image.

The image does not appear in the frame (naturally), and the overflow mark showed up in the lower right corner of the frame. As expected.

Now, in ExtendScript, I ran the following script:

var myFrame = app.activeDocument.textFrames.item(0); // there's only one frame in the document

myFrame.recompose(); // just in case that makes a difference

var inlineImage= myFrame.allPageItems[0];
var g = inlineImage.geometricBounds;

This script fails on the last line with the message "Invalid object for this request." It has the right pageItem, but the pageItem does not report its bounds.

HOWEVER, and here's the interesting part:

IF I manually make the textFrame tall enough so that it's at least as tall as the image, THEN the image appears in the frame (extending beyond the right edge, because I haven't made the frame any wider, only taller).

And THEN the script runs fine.

I'm sure someone somewhere had a good reason for this behavior, but I can't work out the logic behind it. In any event, there seems to be no way to obtain the bounds of an inline pageItem that's taller than the frame. Wider is OK, but taller causes the failure described above.

I don't know if this behavior is historic or new in CS5. For now, I'm just going to use my extremely kludgy workaround (see original post in this thread).

Thanks again, Peter and Dirk. As always, your help is appreciated.

Regards,

Chuck

Translate
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
Advocate ,
Apr 11, 2011 Apr 11, 2011

Chuck,

as you found, isValid is not sufficient for inlines in overset. It just says whether your object specifier points to an existing object.

To check for overset at a particular position, we examine the parentTextContainers of the image's storyOffset (that would be your insertionPoint).

Another approach could temporarily resize the enclosing text frame. Note that with severe overflow if the parent text frame exceeds the pasteboard size, you'd then find your inlines assembled at the bottom there, with wrong bounds.

Finally, you could place the image as regular page item and only move it inline when you're done with scaling ...

Dirk

Translate
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
LEGEND ,
Apr 11, 2011 Apr 11, 2011

Hi Chuck!

You can try using pageItem.resolve() and pageItem.reframe() or resize(). I'm pretty sure that works even if it's not composed.

This is one of those things that I've been meaning to try for a long time already, but work keeps getting in the way...

Harbs

Translate
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
LEGEND ,
Apr 11, 2011 Apr 11, 2011

I just quickly tried playing with resolve, reframe and resize, and I quickly remembered why I put this off to a quiet day (which doesn't seem to come).

The API makes my head hurt trying to figure out the correct parameters to plug in...

If you get it working, let me know!

Harbs

Translate
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
Explorer ,
Apr 11, 2011 Apr 11, 2011

Thanks to all for your help. Here's the solution at which I finally arrived (I'm sure this can be improved upon, feel free to comment):

var reportFile = new File("foo.png");


// the parent textFrame:
var parentFrame = app.activeDocument.textFrames.item(0); // there's only one frame in this test document
parentFrame.recompose(); // just in case it makes a difference
var parentBounds = parentFrame.geometricBounds;

// place the file inline, at the end of the text in the parentFrame:
var insPoint = parentFrame.insertionPoints.lastItem();
var inlineFrame = insPoint.place(reportFile)[0].parent; // need "parent" because otherwise we'd get the placed image; we need its parent rectangle

// in case the placed frame is too tall for the parentFrame, we need to reframe it:
if (parentFrame.overflows) {
    var opposingCorners = [[parentBounds[0],parentBounds[1]], [parentBounds[2], parentBounds[3]]];

        // the parent frame's bounds as an array of two [y,x] arrays
    inlineFrame.reframe(CoordinateSpaces.INNER_COORDINATES, opposingCorners);
}

// now make sure the inlineFrame fits exactly into the parentFrame horizontally,  fit the image so it fits into the inlineFrame, and finally shrink the inline Frame to match the image:
var inlineBounds = inlineFrame.geometricBounds;
inlineFrame.geometricBounds = [inlineBounds[0], inlineBounds[1], parentBounds[2], parentBounds[3]]; // same bounds, but set the inline frame in so it matches the parent frame's bottom right
inlineFrame.fit(FitOptions.PROPORTIONALLY);
inlineFrame.fit(FitOptions.FRAME_TO_CONTENT);

It was Harbs' suggestion regarding pageItem.reframe() that put me on the right track. The "gotcha" here is that reframe REQUIRES that you work in points; I haven't shown the requisite "set the units to points" code, but it needs to be there for this to work right.

Thanks again to all.

-Chuck

Translate
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 ,
Apr 13, 2011 Apr 13, 2011

Chuck,

I wonder If your script will work in every case. I had occasional issues and "interesting" results in testing it with InDesign CS4 6.0.6 (German).
It seems to me that a special relationship between text frame size and picture size is necessary. Somehow unpredictable…

See screen grabs from two working examples and two not working example (resulting in text overflow; in my German version tagged as "Übersatz" in the story panel, thus the "UE" in the links panel instead of a page number).

Working example 1 BEFORE script execution (notice the ratio of the text frame):

Before_WorkingExample_1.png

Working example 1 AFTER script execution:

After_WorkingExample_1.png

Working example 2 AFTER script execution (this time a more extreme ratio of width x height):

After_WorkingExample_2.png

And here an example for a not working situation resulting in text overflow:

After_NotWorkingExample_1.png

First I thought it would be wise to end the text with end paragraph, but the following example shows, that there could be text overflow as well:

After_NotWorkingExample_2.png

It seems to me there must be a minimum height or width of the text frame depending of size and/or ratio of the picture you want to place.
Btw, there's no difference if you use points or millimeter. Tested both.

Uwe

Translate
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
Explorer ,
Apr 14, 2011 Apr 14, 2011
LATEST

Hi Uwe,

Hmmm, I think you are correct. I'll have to return to my secret laboratory to see if I can come up with a more robust version.

Thanks,

Chuck

Translate
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