13 Replies Latest reply on Apr 14, 2011 5:58 AM by cweger79

    geometricBounds not defined for placed image

    cweger79 Level 1

      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

        • 1. Re: geometricBounds not defined for placed image
          Peter Kahrel Adobe Community Professional & MVP

          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

          • 2. Re: geometricBounds not defined for placed image
            Peter Kahrel Adobe Community Professional & MVP

            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

            1 person found this helpful
            • 3. Re: geometricBounds not defined for placed image
              cweger79 Level 1

              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

              • 4. Re: geometricBounds not defined for placed image
                Peter Kahrel Adobe Community Professional & MVP

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

                • 5. Re: geometricBounds not defined for placed image
                  cweger79 Level 1

                  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

                  • 6. Re: geometricBounds not defined for placed image
                    Dirk Becker  Level 4

                    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

                    • 7. Re: geometricBounds not defined for placed image
                      cweger79 Level 1

                      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

                      • 8. Re: geometricBounds not defined for placed image
                        Harbs. Level 6

                        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

                        • 9. Re: geometricBounds not defined for placed image
                          Dirk Becker  Level 4

                          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

                          1 person found this helpful
                          • 10. Re: geometricBounds not defined for placed image
                            Harbs. Level 6

                            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

                            • 11. Re: geometricBounds not defined for placed image
                              cweger79 Level 1

                              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

                              • 12. Re: geometricBounds not defined for placed image
                                Laubender Adobe Community Professional & MVP

                                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

                                • 13. Re: geometricBounds not defined for placed image
                                  cweger79 Level 1

                                  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