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

Scale all images at once in InDesign

Explorer ,
Jun 15, 2018 Jun 15, 2018

Copy link to clipboard

Copied

Hi,

I am working on a document with 500 images and all of them run beyond the text frame size (W: 5 in, H: 7.7 in). Hence, to fit them to the frame, I tried to use Transform->Scale and set the percentage value to less than 100% and the image got fit into the text frame. However, the problem is with a single selection. Selecting an image every time and setting the scale for 500 objects is a time consuming task. I tried using Object style but it does not incorporate "Scale" option in its palette. I tried using Find/Change option but it does not take anything other than an Object style, hence bringing me back to square one.

Then I started a discussion on InDesign for the problem: https://forums.adobe.com/thread/2502461

vinny38​ was a kind enough soul to provide two solutions:

Solution A

  1. //FitAnchorToColumn v2 
  2. //Transform anchored objects in order to rescale them to make them fit column width, keeping proportions. 
  3. //by Vinny 
  4.  
  5.  
  6. if (parseFloat(app.version) < 6
  7.     main(); 
  8. else 
  9.     app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "FitAnchorToColumn"); 
  10.  
  11.  
  12. function main() { 
  13.  
  14.  
  15.     if (app.documents.length > 0) { 
  16.         var 
  17.         myDoc = app.activeDocument, 
  18.         docUnits = myDoc.viewPreferences.horizontalMeasurementUnits; 
  19.  
  20.  
  21.         app.findGrepPreferences = app.changeGrepPreferences = null
  22.         app.findGrepPreferences.findWhat = "~a" 
  23.         var myFound = myDoc.findGrep(); 
  24.  
  25.  
  26.         for (i = 0; i < myFound.length; i++) { 
  27.             if (typeof myFound.parentTextFrames[0] != "undefined") { 
  28.                 var columnWidth = myFound.parentTextFrames[0].textFramePreferences.textColumnFixedWidth, 
  29.                 myObjectWidth = myFound.pageItems[0].geometricBounds[3]-myFound.pageItems[0].geometricBounds[1], 
  30.                 myScaleFactor = columnWidth/myObjectWidth, 
  31.                 myScaleMatrix = app.transformationMatrices.add({horizontalScaleFactor:myScaleFactor,verticalScaleFactor:myScaleFactor}); 
  32.                   
  33.                 myFound.pageItems[0].transform( 
  34.                     CoordinateSpaces.INNER_COORDINATES, 
  35.                     AnchorPoint.TOP_LEFT_ANCHOR, 
  36.                     myScaleMatrix  
  37.                 ); 
  38.             } 
  39.         } 
  40.  
  41.  
  42.         app.findGrepPreferences = app.changeGrepPreferences = null
  43.  
  44.  
  45.     } else
  46.         alert("Open a document"); 
  47.     } 

It worked wonders for the images with respect to the width. It rescaled (and not trimmed) the width of the over bound images to the width of the text frame however, it could not adjust the height of too large images.

Thus, Vinny took out the time from his busy schedule and provided the following solution.

Solution B

  1. //FitAnchorToColumn v3 
  2. //Transform anchored objects in order to rescale them to make them fit column width, keeping proportions. 
  3. //by Vinny 
  4.  
  5.  
  6. if (parseFloat(app.version) < 6
  7.     main(); 
  8. else 
  9.     app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "FitAnchorToColumn"); 
  10.  
  11.  
  12. function main() { 
  13.  
  14.  
  15.     if (app.documents.length > 0) { 
  16.         var 
  17.             myDoc = app.activeDocument, 
  18.             docUnits = myDoc.viewPreferences.horizontalMeasurementUnits, 
  19.             myFound; 
  20.  
  21.  
  22.         app.findGrepPreferences = app.changeGrepPreferences = null
  23.         app.findGrepPreferences.findWhat = "~a"
  24.         myFound = myDoc.findGrep(); 
  25.  
  26.  
  27.         for (i = 0; i < myFound.length; i++) { 
  28.             if (typeof myFound.parentTextFrames[0] != "undefined") { 
  29.                 var 
  30.                     columnWidth = myFound.parentTextFrames[0].textFramePreferences.textColumnFixedWidth, 
  31.                     columnHeight = myFound.parentTextFrames[0].geometricBounds[2] - myFound.parentTextFrames[0].geometricBounds[0], 
  32.                     myObjectWidth = myFound.pageItems[0].geometricBounds[3] - myFound.pageItems[0].geometricBounds[1], 
  33.                     myObjectHeight = myFound.pageItems[0].geometricBounds[2] - myFound.pageItems[0].geometricBounds[0], 
  34.                     myScaleFactor = columnWidth / myObjectWidth, 
  35.                     myScaleMatrix = app.transformationMatrices.add({ 
  36.                         horizontalScaleFactor: myScaleFactor, 
  37.                         verticalScaleFactor: myScaleFactor 
  38.                     }) 
  39.  
  40.  
  41.                 if (myObjectHeight * myScaleFactor == columnHeight) { 
  42.                     return null
  43.                 } else if (myObjectHeight * myScaleFactor < columnHeight) { 
  44.  
  45.  
  46.                     myFound.pageItems[0].transform( 
  47.                         CoordinateSpaces.INNER_COORDINATES, 
  48.                         AnchorPoint.TOP_LEFT_ANCHOR, 
  49.                         myScaleMatrix); 
  50.                 } else
  51.                     myFound.pageItems[0].transform( 
  52.                         CoordinateSpaces.INNER_COORDINATES, 
  53.                         AnchorPoint.TOP_LEFT_ANCHOR, 
  54.                         myScaleMatrix 
  55.                     ); 
  56.                     myFound.pageItems[0].resize( 
  57.                         CoordinateSpaces.INNER_COORDINATES, 
  58.                         AnchorPoint.CENTER_ANCHOR, 
  59.                         ResizeMethods.REPLACING_CURRENT_DIMENSIONS_WITH, [ResizeConstraints.KEEP_CURRENT_VALUE, 
  60.                             UnitValue(columnHeight + String(docUnits)).as('pt'
  61.                         ] 
  62.                     ); 
  63.                 } 
  64.             } 
  65.         } 
  66.  
  67.  
  68.         app.findGrepPreferences = app.changeGrepPreferences = null
  69.  
  70.  
  71.     } else
  72.         alert("Open a document"); 
  73.     } 

The solution worked for both width and height this time however, it trimmed down the top and bottom part of the over bound images (width got rescaled), instead of rescaling them to fit to the text frame size.

Vinny has been of great help but he would not be able to provide more time to the puzzle and I am already grateful to him for providing all the help.

I am searching for a solution which could search for all the over bound images and rescale (not trim down) them to fit to the size of the text frame. I urge all the scripting experts to provide guidance in the right direction.

Regards,

Aman Mittal

  1. //FitAnchorToColumn v3 
  2. //Transform anchored objects in order to rescale them to make them fit column width, keeping proportions. 
  3. //by Vinny 
  4.  
  5.  
  6. if (parseFloat(app.version) < 6
  7.     main(); 
  8. else 
  9.     app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "FitAnchorToColumn"); 
  10.  
  11.  
  12. function main() { 
  13.  
  14.  
  15.     if (app.documents.length > 0) { 
  16.         var 
  17.             myDoc = app.activeDocument, 
  18.             docUnits = myDoc.viewPreferences.horizontalMeasurementUnits, 
  19.             myFound; 
  20.  
  21.  
  22.         app.findGrepPreferences = app.changeGrepPreferences = null
  23.         app.findGrepPreferences.findWhat = "~a"
  24.         myFound = myDoc.findGrep(); 
  25.  
  26.  
  27.         for (i = 0; i < myFound.length; i++) { 
  28.             if (typeof myFound.parentTextFrames[0] != "undefined") { 
  29.                 var 
  30.                     columnWidth = myFound.parentTextFrames[0].textFramePreferences.textColumnFixedWidth, 
  31.                     columnHeight = myFound.parentTextFrames[0].geometricBounds[2] - myFound.parentTextFrames[0].geometricBounds[0], 
  32.                     myObjectWidth = myFound.pageItems[0].geometricBounds[3] - myFound.pageItems[0].geometricBounds[1], 
  33.                     myObjectHeight = myFound.pageItems[0].geometricBounds[2] - myFound.pageItems[0].geometricBounds[0], 
  34.                     myScaleFactor = columnWidth / myObjectWidth, 
  35.                     myScaleMatrix = app.transformationMatrices.add({ 
  36.                         horizontalScaleFactor: myScaleFactor, 
  37.                         verticalScaleFactor: myScaleFactor 
  38.                     }) 
  39.  
  40.  
  41.                 if (myObjectHeight * myScaleFactor == columnHeight) { 
  42.                     return null
  43.                 } else if (myObjectHeight * myScaleFactor < columnHeight) { 
  44.  
  45.  
  46.                     myFound.pageItems[0].transform( 
  47.                         CoordinateSpaces.INNER_COORDINATES, 
  48.                         AnchorPoint.TOP_LEFT_ANCHOR, 
  49.                         myScaleMatrix); 
  50.                 } else
  51.                     myFound.pageItems[0].transform( 
  52.                         CoordinateSpaces.INNER_COORDINATES, 
  53.                         AnchorPoint.TOP_LEFT_ANCHOR, 
  54.                         myScaleMatrix 
  55.                     ); 
  56.                     myFound.pageItems[0].resize( 
  57.                         CoordinateSpaces.INNER_COORDINATES, 
  58.                         AnchorPoint.CENTER_ANCHOR, 
  59.                         ResizeMethods.REPLACING_CURRENT_DIMENSIONS_WITH, [ResizeConstraints.KEEP_CURRENT_VALUE, 
  60.                             UnitValue(columnHeight + String(docUnits)).as('pt'
  61.                         ] 
  62.                     ); 
  63.                 } 
  64.             } 
  65.         } 
  66.  
  67.  
  68.         app.findGrepPreferences = app.changeGrepPreferences = null
  69.  
  70.  
  71.     } else
  72.         alert("Open a document"); 
  73.     } 
TOPICS
Scripting

Views

8.7K

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

Guide , Jun 20, 2018 Jun 20, 2018

Hi Aman,

1. The sample document contains aboveLine anchors (not only pure inline.) I found that in such case rescaling to the height of the text frame is not sufficient to wake up the ghost object. An advanced product could surely work around this using smart calculations and so. But here I will consider the inline mode as a requirement, so the version below just converts any aboveLine anchor into inline. (Recall that custom anchored objects are ignored.)

2. Smart text reflow is not properly confi

...

Votes

Translate

Translate
Community Expert ,
Jun 15, 2018 Jun 15, 2018

Copy link to clipboard

Copied

You should let InDesign do all the work:

links = app.documents[0].links.everyItem().getElements();

for (i = 0; i < links.length; i++) {

  links.parent.parent.fit (FitOptions.CONTENT_TO_FRAME);

}

P.

Votes

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
Explorer ,
Jun 15, 2018 Jun 15, 2018

Copy link to clipboard

Copied

Hello Mr. Kahrel,

Thank you for taking out time from your busy schedule and replying to the thread. I saved the script and tried to run it in InDesign, however, I regret (because your reputation in InDesign community precedes you) to tell you that it did not affect a single image. All the out of bound images remained of the same size and did not fit to the text frame size.

I know your schedule remains too busy but I would really appreciate if you could help me out regarding the request. Hope to receive a positive reply.

Regards,

Aman Mittal

Votes

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
Guide ,
Jun 17, 2018 Jun 17, 2018

Copy link to clipboard

Copied

Hi Aman,

If your goal is to proportionnally re-scale inline containers with respect to the width of the text frame they belong to, here is a possible approach:

function rescaleInlines(  q,t,wso,items,chars,z,c,o,aos,k,w,x)

//----------------------------------

// This function proportionnaly re-scales every *inline* or

// *aboveLine* anchored item found in the document so that

// it fits the parent frame width.

{

    // Cache and constants.

    // ---

    q = (callee.Q||callee.Q={});

    const EPSILON = 1e-3,

          ANCH = +AnchorPosition.ANCHORED,

          // ---

          CPAR = +CoordinateSpaces.parentCoordinates,

          CINN = +CoordinateSpaces.innerCoordinates,

          BVSB = +BoundingBoxLimits.outerStrokeBounds,

          // ---

          PAR0 = [+AnchorPoint.topLeftAnchor, BVSB],

          PAR1 = [+AnchorPoint.bottomRightAnchor, BVSB],

          INN0 = PAR0.concat(CPAR),

          INN1 = PAR1.concat(CPAR),

          MATX = [1,0,0,1, 0,0];

   

    // Get anchored items from all stories, and the respective parent char.

    // ---

    if( !(t=app.properties.activeDocument) ){ alert("No document!"); return; }

    t = t.stories.everyItem().texts.everyItem().pageItems;

    if( !t.length ){ alert("No anchored item."); return; }

    items = (t=t.everyItem()).getElements(); // array of anchored items

    chars = t.parent;                        // array of anchor characters

    // Safer scaling options.

    // ---

    t = +WhenScalingOptions.ADJUST_SCALING_PERCENTAGE;

    wso = +app.transformPreferences.whenScaling;

    wso==t ? (wso=0) : (app.transformPreferences.whenScaling=t);

    // Scan each anchor character and its respective parent frame (if any!)

    // (Loop from the end to get as many parent frames as possible while rescaling.)

    // ---

    for( z=0 ; (c=chars.pop()) && (o=items.pop()) ; )

    {

        // c in overset text -> no parent available.

        // ---

        if( !(t=(c.parentTextFrames||0)[0]) ) continue;

        // Filtering conditions on `o` (you may add your own.)

        // ---

        aos = o.properties.anchoredObjectSettings||0;

        if( (!aos) || ANCH==+aos.anchoredPosition ) continue;

       

        // If needed, do fitting jobs now.

        o.fit(FitOptions.FRAME_TO_CONTENT);

       

        // Use box coordinates to determine the scaling factor.

        // ---

        w = q[k=t.id]||(q=t.resolve(PAR1,CINN)[0][0]-t.resolve(PAR0,CINN)[0][0]);

        x = w/(o.resolve(INN1,CPAR)[0][0]-o.resolve(INN0,CPAR)[0][0]);

        if( Math.abs(x-1) < EPSILON ) continue; // matches already.

       

        // Rescale.

        // ---

        MATX[0] = MATX[3] = x;

        o.transform(CPAR,INN0,MATX);

        ++z;

    }

   

    wso && (app.transformPreferences.whenScaling=wso);

    alert( "Processed items: " + z);

};

app.doScript(rescaleInlines, void 0, void 0, UndoModes.entireScript, "RescaleInlines");

@+

Marc

Votes

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
Explorer ,
Jun 18, 2018 Jun 18, 2018

Copy link to clipboard

Copied

Hey Marc,

Thank you for taking out time from your busy schedule and replying to the query. I am grateful to you for going to the extent of developing a script to solve the problem. I tried the script however, the overset text remained the same and the file didn't flow till the time, I didn't change the Anchored Positioning to "Custom" from "Inline or Above Line" and the size of the the over-bound images with respect to height remained unchanged.

I am trying to look for a solution which could follow these steps:

1. Look through the entire document for over-bound images: Images that go beyond the text frame size: 5 inch x 7.7 inch (width x height) by width or height or both. Search for an image that exceeds the text frame size by width (5 inch) or exceeds the frame by height (7.7 inch) or exceed the frame through both ends.

2. Rescale and not trim down such over-bound images such that they fit to the frame size

3. Leave the already in-bound images unattended: The process may not rescale those mages which are already fit or are under the frame size by width or height or both.

I apologize for bothering you all so much but I do not have any form of learning the script language and am in need to such a thing to complete my project on time.

In case, such a thing is plausible then kindly, point in the right direction. Big thank you even considering the request.

Regards,

Aman Mittal

Votes

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
Guide ,
Jun 18, 2018 Jun 18, 2018

Copy link to clipboard

Copied

Hi Aman,

Do you mean (#7) that your document originally has mainly overset text and does not use smart reflow mechanism?

In that case it is impossible to tell which TextFrame an inline object should belong to (as there is no such TextFrame) and furthermore the inline object has no visible bounding box (it is a “ghost” object). Then it seems very complicate to compute width and or height ratio (and apply scaling) to objects that do not exist yet.

In case you'd have actual visible boxes to run on, my snippet (#3) should work. It does the job regarding the desired width. It applies rescaling to every non-matching anchor frame. If you want to exclude some stuff from the process—for example leaving unchanged frames that are under the width—it is easy to add filtering, etc.

The line

if( Math.abs(x-1) < EPSILON ) continue;

skips objects whose width ratio, x, is already 1 or very close to 1.

To only manage objects that require downscaling (x < 1) change it to:

if( x+EPSILON >= 1 ) continue;

Note. — If the size of all text frames is constant and already known, there are possible optimization but my code already uses a cache for width calculation so it should still provide fair performance while remaining more generic. (IMHO, the purpose of this Scripting Forum is about discussing and providing generic codes and techniques and not about solving for free highly specific problems that nobody will never encounter—anymore—like “Rescaling Not-Yet-Existing Inline Boxes to 5×7.7 in.”)

@+

Marc

Votes

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
Explorer ,
Jun 18, 2018 Jun 18, 2018

Copy link to clipboard

Copied

Hey Marc,

Thank you for taking out the time and replying to the thread. Regarding the concern, It follows Smart Flow mechanism but due to large-size of the images and being already in-lined in the original document, the text overflows.

With reference to the purpose of scripting forum, you are right that the the purpose is to provide generic code and not specific ones. However, if you would look at the initial part of the request:

1. The problem raised is a genuine problem faced by almost all users at some point or the other (when the size of the images are too large that it overflows the text).

2. However, the problem is so general that you need a container to look/provide for a generic code therefore, i went with the concept of text frame size. If no container is applied, then the problem becomes vast and complex leading to probable application of machine learning. That is why, I applied a container so that one could tweak the container size to find relevant results.

Additionally, I perfectly understand the amount of expertise, a professional puts in bringing out such kinds of solutions and I respect one's time for the same. Therefore, for highly specific problems (which I thought to be more complex than the one state above), whenever I turn to a professional I keep in consideration the worthiness of their effort, as well. For instance, there was a highly specific problem pertaining to a concept for which I needed a solution. Even though I didn't know Mr. Peter Kahrel but knew his reputation preceded his good name so I turned to him for professional help rather than 'free highly specific problem' help.

With all due respect, I do not mean to exploit anyone as I know that the time and effort it takes to build such an expertise can't be quantified. If I had slightest bit of an idea that was a complex problem, I would have turned to experts in a professional manner, only.

Consider my sincerest apologies for the trouble caused and thank you for putting things in perspective. I shall be be considerate of the same, in future.

Regards,

Aman Mittal

Votes

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
Guide ,
Jun 18, 2018 Jun 18, 2018

Copy link to clipboard

Copied

Hi Aman,

While remaining extremely cautious and unsteady regarding my understanding of the whole picture, I might have now a slightly clearer view of the topic. So:

— SmartTextReflow is ON but your stream still overflows because sparse inline objects are too high relative to the frame that would host them.

— Apart from that, your main goal is to downscale those inline objects when needed, so that their width doesn't exceed text frame width.

Now, I admit that's an interesting (and very technical) question! Indeed, ghost page items are often a serious problem to us. They formally exist but as long as they belong to an overset part of the stream, they don't have geometric properties. Even worse, they do not have parent text frame yet. So we can't perform calculations based on either their own size, or the size of their host!

To address this issue, I think we need a two-step process.

1. First, detect ghost items and force them to show up by changing their formal scaling properties. Using a high downscaling factor should do the job—provided we keep track of that temporary fix.

2. Then, when all actors are on stage, we can perform the desired tasks the regular way.

That's what the code below—generously commented for further customizations—is trying to do:

function fixAndDownscaleInlines(  q,t,wso,items,chars,z,c,o,aos,k,wh,xy,x,y)

//----------------------------------

// This function proportionnaly downscale every *inline* or *aboveLine*

// anchored item found in the document, so that:

// 1. Target width does not exceed parent frame width (PFW.)

// 2. Targets whose width is *under* PFW are not touched.

// 3. Targets whose height exceeds the parent frame height (causing

//    overset issues that SmartTextReflow can't fix) are temporarily

//    downscaled so that the algorithm can eat them. When available back,

//    those objects are adjusted to the frame height unless width adjustment

//    is required to prevent them from violating rule 1.

// Note: Smart Text Reflow must be turned on and properly set.

{

    // Cache and constants.

    // ---

    q = (callee.Q||callee.Q={});

    const EPSILON = 1e-3,

          DOWN = 100, // Downscaling factor

          ANCH = +AnchorPosition.ANCHORED,

          // ---

          CPAR = +CoordinateSpaces.parentCoordinates,

          CINN = +CoordinateSpaces.innerCoordinates,

          BVSB = +BoundingBoxLimits.outerStrokeBounds,

          // ---

          PAR0 = [+AnchorPoint.topLeftAnchor, BVSB],

          PAR1 = [+AnchorPoint.bottomRightAnchor, BVSB],

          INN0 = PAR0.concat(CPAR),

          INN1 = PAR1.concat(CPAR),

          MATX = [1,0,0,1, 0,0];

    // Checkpoint.

    // ---

    if( !(t=app.properties.activeDocument) )

        { alert("No document!"); return; }

    if( !t.textPreferences.properties.smartTextReflow )

        { alert("SmartTextReflow must be turned on!"); return; }

    // Get anchored items from all stories, and the respective parent char.

    // ---

    t = t.stories.everyItem().texts.everyItem().pageItems;

    if( !t.length ){ alert("No anchored item."); return; }

    items = (t=t.everyItem()).getElements(); // array of anchored items

    chars = t.parent;                        // array of anchor characters

    // Safe scaling options are definitely needed.

    // ---

    t = +WhenScalingOptions.ADJUST_SCALING_PERCENTAGE;

    wso = +app.transformPreferences.whenScaling;

    wso==t ? (wso=0) : (app.transformPreferences.whenScaling=t);

    // [180618] Patch. Looping here from top to bottom (in

    // each story stream) we try to restore missing bounding boxes

    // due to 'formal heights' being higher than the parent frame.

    // A flag is then set in q[_id] to save those special cases.

    // ---

    for( n=items.length, z=-1 ; ++z < n ; )

    {

        // `o` is a PageItem which typically contains

        // a Graphic which typically controls a Link.

        // ---

        o = items;

        if( o.properties.visibleBounds ) continue;

       

        // `o` has no parent text frame because it's too high!

        // Let's temporarily apply a hard downscaling to it.

        // ---

        if( !(x=o.properties.horizontalScale) ) continue;

        if( !(y=o.properties.verticalScale) ) continue;

        o.horizontalScale = x/DOWN; // 1%

        o.verticalScale = y/DOWN;   // 1%

        q['_'+o.id] = 1; // flag

    }

    // Scan each anchor character and its respective parent frame (if any!)

    // [REM] Original reason for looping upwards: "Get as many parent frames

    // as possible while rescaling." Sounds pointless now, but keeping the

    // logic won't hurt.

    // ---

    for( z=0 ; (c=chars.pop()) && (o=items.pop()) ; )

    {

        // c in overset text -> no parent available.

        // ---

        if( !(t=(c.parentTextFrames||0)[0]) ) continue;

        // Filtering conditions on `o` (you may add your own.)

        // Here we check that the anchor is of inline/aboveLine kind.

        // ---

        aos = o.properties.anchoredObjectSettings||0;

        if( (!aos) || ANCH==+aos.anchoredPosition ) continue;

        // Visible width and height of the text frame (if not in cache yet.)

        // ---

        if( !(wh=q[k=t.id]) )

        {

            wh = q = t.resolve(PAR1,CINN)[0];

            xy = t.resolve(PAR0,CINN)[0];

            wh[0] -= xy[0];

            wh[1] -= xy[1];

        }

        // Temporarily store the (w,h) of `o` (in parent space.)

        // ---

        t = o.resolve(INN1,CPAR)[0].concat(o.resolve(INN0,CPAR)[0]);

        t[0] -= t[2];

        t[1] -= t[3];

        t.length = 2;

        // The x factor is required in either case.

        // ---

        x = wh[0]/t[0];

       

        // If `o` has been previously downscaled to make it show up,

        // we need to find the *smallest fit factor*.

        // ---

        y = q['_'+o.id] ? wh[1]/t[1] : false;

       

        // If `o` hasn't been downscaled, prevent it from being upscaled.

        // ("Width shorter than the frame width -> do nothing.")

        // ---

        if( (!y) && 1 <= x+EPSILON ) continue;

        // Rescale.

        // ---

        y && y < x && (x=y);

        MATX[0] = MATX[3] = x;

        o.transform(CPAR,INN0,MATX);

        ++z;

    }

    wso && (app.transformPreferences.whenScaling=wso);

    alert( "Processed items: " + z);

};

app.doScript(fixAndDownscaleInlines, void 0, void 0, UndoModes.entireScript, "FixAndDownscaleInlines");

Hope that helps.

Marc

Votes

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 ,
Jun 18, 2018 Jun 18, 2018

Copy link to clipboard

Copied

https://forums.adobe.com/people/Marc+Autret  wrote

Hi Aman,

While remaining extremely cautious and unsteady regarding my understanding of the whole picture, I might have now a slightly clearer view of the topic.…

Hi Marc,

hope you noticed this other thread currently running in the InDesign forum that eventually makes clear what Aman is aiming at:

Scale all images at once in InDesign

vinny38 was suggesting something similar by trying a high downscaling factor first in reply 18 over there:

So, I modified the script in a way it first look for overset objects, reduce them to 5% (assuming this would be small enough to make them fit in the flow), then, rescale them as described earlier.

Best,
Uwe

Votes

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
Explorer ,
Jun 18, 2018 Jun 18, 2018

Copy link to clipboard

Copied

Hi Marc,

Thank you replying to thread, once again. It is delight to see such an amazing mind working on the technicality, and am glad to hear that you now have a bit clear understanding of the issue at hand.

As rightly stated, my goal line is to downscale all those inline objects which run out of the text frame either by 'width' or 'height' or both; not particularly just the width but the height, as well as this helps in getting rid of the overflow problem and makes the workflow manageable.

I went with the script and it worked on all the object in two different ways:

  • The dialog box displayed that it had processed two items. It perfectly gave the desired results for the first two objects as they were rescaled to fit to the text frame width
  • It left the already in-bound object (which fit well under the text frame size) unattended.
  • The script detected the ghost items and forced them to show up on stage, and the text flowed perfectly. However, the script highly downscaled the rest of the images and left them and din't do the adjustment, it did for the first two objects.

12.png

This definitely solved the problem of overflow text arising out of large images, at a single go and definitely brought us one step closer to a simpler workflow in terms of text flow. However, it brings us back to the task of rescaling every image, again. Though the effort is great, however, it could have been tremendous if the work had given the same output generated for the first two objects to all the other objects, as well. This tweak could definitely bring a lot of people closer to a manageable workflow. Thank you for going through all the trouble and helping out! Greatly appreciated!

Regards,

Aman

Votes

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
Guide ,
Jun 19, 2018 Jun 19, 2018

Copy link to clipboard

Copied

Hi Aman,

On downscaled images left as such, my guess is that the layout hasn't the time to update during the process—in the context of a huge document, latency issues arise.

So, after step 1, we should probably force the recomposition or something. Otherwise, Smart Text Reflow would still be under processing when step 2 starts, so most inline components remain in overset zone at this stage, which surely explains the result you observe.

Is there a sample document somewhere so we can test refreshing strategies?

@+

Marc

Votes

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 ,
Jun 19, 2018 Jun 19, 2018

Copy link to clipboard

Copied

https://forums.adobe.com/people/Marc+Autret  wrote

… Is there a sample document somewhere so we can test refreshing strategies?

Yes! This would help tremendously to tackle some issues.

Best,
Uwe

Votes

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
Explorer ,
Jun 19, 2018 Jun 19, 2018

Copy link to clipboard

Copied

Hey Marc,

I understand that a sample file would be rather help in understanding the problem. Hence, please find attached a sample INDD document with certain caveats:

https://drive.google.com/file/d/19SrwcPWRUqLMrdgHLOSpdCpNRfw11bwA/view?usp=sharing

1. I have removed the image content however, the image frames are intact and untouched which shall serve the same purpose.

2. All the images have Anchored Object Positioning: Above or Inline, as the original word document have inline images

3. You will find that the text overflows due to the varying size of images which run beyond the text frame size.

4. If you apply Anchored Object Positioning: Custom through all Find/Change to all the Objects then, the file will start to flow and you will see images frames of varying sizes.

Hope, this serves as a sample document.

Regards,

Aman

Votes

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
Guide ,
Jun 19, 2018 Jun 19, 2018

Copy link to clipboard

Copied

Hi Aman,

Here is the variant with forced recomposition:

function fixAndDownscaleInlines(  q,doc,t,wso,n,items,chars,z,c,o,aos,k,wh,xy,x,y)

//----------------------------------

// [180619] Added `document.recompose()` to force smart reflow to update.

// This function proportionnaly downscale every *inline* or

// *aboveLine* anchored item found in the document, so that:

// 1. Target width does not exceed parent frame width (PFW.)

// 2. Targets whose width is *under* PFW are not touched.

// 3. Objects whose height exceeds the parent frame height (then causing

//    overset issues that SmartTextReflow can't fix) are temporarily

//    downscaled so that the algorithm can eat them. When available back,

//    those objects are adjusted to the frame height unless width adjustment

//    is required instead (to prevent them from violating rule 1.)

// Note: Smart Text Reflow must be turned on and properly set.

{

    // Cache and constants.

    // ---

    q = (callee.Q||callee.Q={});

    const EPSILON = 1e-3,

          DOWN = 100, // Downscaling factor

          ANCH = +AnchorPosition.ANCHORED,

          // ---

          CPAR = +CoordinateSpaces.parentCoordinates,

          CINN = +CoordinateSpaces.innerCoordinates,

          BVSB = +BoundingBoxLimits.outerStrokeBounds,

          // ---

          PAR0 = [+AnchorPoint.topLeftAnchor, BVSB],

          PAR1 = [+AnchorPoint.bottomRightAnchor, BVSB],

          INN0 = PAR0.concat(CPAR),

          INN1 = PAR1.concat(CPAR),

          MATX = [1,0,0,1, 0,0];

    // Checkpoint.

    // ---

    if( !(doc=app.properties.activeDocument) )

        { alert("No document!"); return; }

    if( !doc.textPreferences.properties.smartTextReflow )

        { alert("SmartTextReflow must be turned on!"); return; }

    // Get anchored items from all stories, and the respective parent char.

    // ---

    t = doc.stories.everyItem().texts.everyItem().pageItems;

    if( !t.length ){ alert("No anchored item."); return; }

    items = (t=t.everyItem()).getElements(); // array of anchored items

    chars = t.parent;                        // array of anchor characters

    // Safe scaling options are definitely needed.

    // ---

    t = +WhenScalingOptions.ADJUST_SCALING_PERCENTAGE;

    wso = +app.transformPreferences.whenScaling;

    wso==t ? (wso=0) : (app.transformPreferences.whenScaling=t);

    // [180618] Patch. Looping here from top to bottom (in

    // each story stream) we try to restore missing bounding boxes

    // due to 'formal heights' being higher than the parent frame.

    // A flag is then set in q[_id] to save those special cases.

    // ---

    for( n=items.length, z=-1 ; ++z < n ; )

    {

        // `o` is a PageItem which typically contains

        // a Graphic which typically controls a Link.

        // ---

        o = items;

        if( o.properties.visibleBounds ) continue;

       

        // `o` has no parent text frame because it's too high!

        // Let's temporarily apply a hard downscaling to it.

        // ---

        if( !(x=o.properties.horizontalScale) ) continue;

        if( !(y=o.properties.verticalScale) ) continue;

        o.horizontalScale = x/DOWN; // 1%

        o.verticalScale = y/DOWN;   // 1%

        q['_'+o.id] = 1; // flag

    }

    // [180619] Force recomposition now.

    // ---

    doc.recompose();

    // Scan each anchor character and its respective parent frame (if any!)

    // [REM] Original reason for looping upwards: "Get as many parent frames

    // as possible while rescaling." Sounds pointless now, but keeping the

    // logic won't hurt.

    // ---

    for( z=0 ; (c=chars.pop()) && (o=items.pop()) ; )

    {

        // c in overset text -> no parent available.

        // ---

        if( !(t=(c.parentTextFrames||0)[0]) ) continue;

        // Filtering conditions on `o` (you may add your own.)

        // Here we check that the anchor is of inline/aboveLine kind.

        // ---

        aos = o.properties.anchoredObjectSettings||0;

        if( (!aos) || ANCH==+aos.anchoredPosition ) continue;

        // Visible width and height of the text frame (if not in cache yet.)

        // ---

        if( !(wh=q[k=t.id]) )

        {

            wh = q = t.resolve(PAR1,CINN)[0];

            xy = t.resolve(PAR0,CINN)[0];

            wh[0] -= xy[0];

            wh[1] -= xy[1];

        }

        // Temporarily store the (w,h) of `o` (in parent space.)

        // ---

        t = o.resolve(INN1,CPAR)[0].concat(o.resolve(INN0,CPAR)[0]);

        t[0] -= t[2];

        t[1] -= t[3];

        t.length = 2;

        // The x factor is required in either case.

        // ---

        x = wh[0]/t[0];

       

        // If `o` has been previously downscaled to make it show up,

        // we need to find the *smallest fit factor*.

        // ---

        y = q['_'+o.id] ? wh[1]/t[1] : false;

       

        // If `o` hasn't been downscaled, prevent it from being upscaled.

        // ("Width shorter than the frame width -> do nothing.")

        // ---

        if( (!y) && 1 <= x+EPSILON ) continue;

        // Rescale.

        // ---

        y && y < x && (x=y);

        MATX[0] = MATX[3] = x;

        o.transform(CPAR,INN0,MATX);

        ++z;

    }

    wso && (app.transformPreferences.whenScaling=wso);

    alert( "Processed items: " + z);

};

app.doScript(fixAndDownscaleInlines, void 0, void 0, UndoModes.entireScript, "FixAndDownscaleInlines");

@+

Marc

Votes

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 ,
Jun 19, 2018 Jun 19, 2018

Copy link to clipboard

Copied

Hi Marc,
I fear that doc.recompose() would not be enough.

I'd also test the following menu action:

app.menuActions.itemByName("$ID/Recompose all stories").invoke();

Once I had success by invoking this menu command when a simple recompose() failed.

Best,
Uwe

Votes

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
Guide ,
Jun 19, 2018 Jun 19, 2018

Copy link to clipboard

Copied

Hi Uwe,

I fear that doc.recompose() would not be enough.

You're probably right, but that's a starting point.

(I confess I'm not efficient at dealing with refreshing problems. Your help is welcome!)

Best,

Marc

Votes

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
Explorer ,
Jun 20, 2018 Jun 20, 2018

Copy link to clipboard

Copied

Hi Marc,

I tried the modified version of of the script and it gave the same results as we discussed before. for ease, I have already attached a sample document and hope that it will fulfill the purpose for testing. Hope to see this through.

Regards,

Aman

Votes

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
Guide ,
Jun 20, 2018 Jun 20, 2018

Copy link to clipboard

Copied

Hi Aman,

1. The sample document contains aboveLine anchors (not only pure inline.) I found that in such case rescaling to the height of the text frame is not sufficient to wake up the ghost object. An advanced product could surely work around this using smart calculations and so. But here I will consider the inline mode as a requirement, so the version below just converts any aboveLine anchor into inline. (Recall that custom anchored objects are ignored.)

2. Smart text reflow is not properly configured in the sample document. AFAIK, the master spread (applied to page 1) should have primary text frames, which should be chained due to facing pages, and the frame on page 1 should instantiate the master frame. The other pages can be removed by the script as a first step.

Then the code below worked for me.

Again, we may provide an automated check-and-repair mechanism regarding the issues above, but it's not technically interesting (and quite boring to implement), so better is to let the user prepare the input document as specified. (A simple document preset would solve this once for all.)

function fixAndDownscaleInlines(  q,doc,t,wso,n,items,chars,z,c,o,aos,k,wh,xy,x,y)

//----------------------------------

// [180621] Force inline anchoring when aboveLine is found.

// [180619] Added `document.recompose()` to force smart reflow to update.

// This function proportionnaly downscale every *inline* or

// *aboveLine* anchored item found in the document, so that:

// 1. Target width does not exceed parent frame width (PFW.)

// 2. Targets whose width is *under* PFW are not touched.

// 3. Objects whose height exceeds the parent frame height (then causing

//    overset issues that SmartTextReflow can't fix) are temporarily

//    downscaled so that the algorithm can eat them. When available back,

//    those objects are adjusted to the frame height unless width adjustment

//    is required instead (to prevent them from violating rule 1.)

// Note: Smart Text Reflow must be turned on and properly set.

{

    // Cache and constants.

    // ---

    q = (callee.Q||callee.Q={});

    const EPSILON = 1e-3,

          DOWN = 100, // Downscaling factor

          ANCH = +AnchorPosition.ANCHORED,

          ABOV = +AnchorPosition.ABOVE_LINE,

          INLN = +AnchorPosition.INLINE_POSITION,

          // ---

          CPAR = +CoordinateSpaces.parentCoordinates,

          CINN = +CoordinateSpaces.innerCoordinates,

          BVSB = +BoundingBoxLimits.outerStrokeBounds,

          // ---

          PAR0 = [+AnchorPoint.topLeftAnchor, BVSB],

          PAR1 = [+AnchorPoint.bottomRightAnchor, BVSB],

          INN0 = PAR0.concat(CPAR),

          INN1 = PAR1.concat(CPAR),

          MATX = [1,0,0,1, 0,0];

    // Checkpoint.

    // ---

    if( !(doc=app.properties.activeDocument) )

        { alert("No document!"); return; }

    if( !(t=doc.textPreferences).properties.smartTextReflow )

        { alert("SmartTextReflow must be turned on!"); return; }

    if( !(t=doc.pages[0].appliedMaster) )

    {

        if( !confirm("No applied master on first page. Fix this?") ) return;

        t = doc.pages[0].appliedMaster = doc.masterSpreads[0];

    }

    if( !t.primaryTextFrame )

        { alert("No primary frame on spread "+t.name+"."); return; }

    // [ADD180621] Prepare text reflow.

    // ---

    doc.pages.itemByRange(1,-1).remove();

    t.properties = {

        addPages:                 +AddPageOptions.END_OF_STORY,

        deleteEmptyPages:          true,

        limitToMasterTextFrames:   true,

        preserveFacingPageSpreads: true,

    };

    // Get anchored items from all stories, and the respective parent char.

    // ---

    t = doc.stories.everyItem().texts.everyItem().pageItems;

    if( !t.length ){ alert("No anchored item."); return; }

    items = (t=t.everyItem()).getElements(); // array of anchored items

    chars = t.parent;                        // array of anchor characters

    // Safe scaling options are definitely needed.

    // ---

    t = +WhenScalingOptions.ADJUST_SCALING_PERCENTAGE;

    wso = +app.transformPreferences.whenScaling;

    wso==t ? (wso=0) : (app.transformPreferences.whenScaling=t);

    // [180618] Patch. Looping here from top to bottom (in

    // each story stream) we try to restore missing bounding boxes

    // due to 'formal heights' being higher than the parent frame.

    // A flag is then set in q[_id] to save those special cases.

    // ---

    for( n=items.length, z=-1 ; ++z < n ; )

    {

        // `o` is a PageItem which typically contains

        // a Graphic which typically controls a Link.

        // ---

        o = items;

        if( o.properties.visibleBounds ) continue;

       

        // `o` has no parent text frame because it's too high!

        // Let's temporarily apply a hard downscaling to it.

        // ---

        if( !(x=o.properties.horizontalScale) ) continue;

        if( !(y=o.properties.verticalScale) ) continue;

        o.horizontalScale = x/DOWN; // 1%

        o.verticalScale = y/DOWN;   // 1%

        q['_'+o.id] = 1; // flag

    }

    // [180619] Force recomposition now.

    // ---

    doc.recompose();

    // Scan each anchor character and its respective parent frame (if any!)

    // [REM] Original reason for looping upwards: "Get as many parent frames

    // as possible while rescaling." Sounds pointless now, but keeping the

    // logic won't hurt.

    // ---

    for( z=0 ; (c=chars.pop()) && (o=items.pop()) ; )

    {

        // c in overset text -> no parent available.

        // ---

        if( !(t=(c.parentTextFrames||0)[0]) ) continue;

        // Filtering conditions on `o` (you may add your own.)

        // Here we check that the anchor is of inline/aboveLine kind.

        // ---

        aos = o.properties.anchoredObjectSettings||0;

        if( (!aos) || ANCH==+aos.anchoredPosition ) continue;

       

        // [FIX180621] Force inline.

        // ---

        aos.anchoredPosition = INLN;

        // Visible width and height of the text frame (if not in cache yet.)

        // ---

        if( !(wh=q[k=t.id]) )

        {

            wh = q = t.resolve(PAR1,CINN)[0];

            xy = t.resolve(PAR0,CINN)[0];

            wh[0] -= xy[0];

            wh[1] -= xy[1];

        }

        // Temporarily store the (w,h) of `o` (in parent space.)

        // ---

        t = o.resolve(INN1,CPAR)[0].concat(o.resolve(INN0,CPAR)[0]);

        t[0] -= t[2];

        t[1] -= t[3];

        t.length = 2;

        // The x factor is required in either case.

        // ---

        x = wh[0]/t[0];

       

        // If `o` has been previously downscaled to make it show up,

        // we need to find the *smallest fit factor*.

        // ---

        y = q['_'+o.id] ? wh[1]/t[1] : false;

       

        // If `o` hasn't been downscaled, prevent it from being upscaled.

        // ("Width shorter than the frame width -> do nothing.")

        // ---

        if( (!y) && 1 <= x+EPSILON ) continue;

        // Rescale.

        // ---

        y && y < x && (x=y);

        MATX[0] = MATX[3] = x;

        o.transform(CPAR,INN0,MATX);

        ++z;

    }

    wso && (app.transformPreferences.whenScaling=wso);

    alert( "Processed items: " + z);

};

app.doScript(fixAndDownscaleInlines, void 0, void 0, UndoModes.entireScript, "FixAndDownscaleInlines");

@+

Marc

Votes

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
Explorer ,
Jun 21, 2018 Jun 21, 2018

Copy link to clipboard

Copied

Hey Marc,

Thank you for clarifying the mistakes. I tried the new version with the document. However, before placing the document, I went through the following steps:

Created a new document with "Primary Text Frame" option ticked to let A-Master spread have chained primary frames.

Then, I rechecked the first page to have A-Master applied and used the Place Gun to import the document.

After the file import, I ran the script, however, like before, the script processed first two items and download all other images to the size of dot, as discussed before.

I am not able to figure out, where I am going wrong. I tried to run the script following the above steps, it didn't change the size of the first image frame and deleted all other image frames.

Hence, if possible, I would request you to please attach the script applied sample document so that I may compare the properties applied to ascertain the glitches.

And, Mr. Marc, Thank you very much for taking out the time and being so patient and helpful. I am grateful to you for all the help and trouble, you went through.

Regards,

Aman

Votes

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
Guide ,
Jun 21, 2018 Jun 21, 2018

Copy link to clipboard

Copied

Hi Aman,

Sample document properly prepared is here:

http://indiscripts.com/blog/public/SampleDocument-OK.idml

And here is how the script works:

sample-ok.gif

@+

Marc

Votes

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
Enthusiast ,
Jun 19, 2018 Jun 19, 2018

Copy link to clipboard

Copied

Merci Marc pour les commentaire dans le script ça aide.

A+

Philou

Votes

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 ,
Mar 22, 2021 Mar 22, 2021

Copy link to clipboard

Copied

LATEST

Hi Marc, 

I just wanted to give you a big thank you as I needed a script to resize inline graphics proportionally as we have changed trim size on our products. The one above worked perfectly and in seconds. I went through about 20 scripts before I found this one and it did the trick, so thank you!

Votes

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 ,
Jun 18, 2018 Jun 18, 2018

Copy link to clipboard

Copied

Hi Aman,

is it width of text column or width of text frame what you need?

Regards,
Uwe

Votes

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
Explorer ,
Jun 18, 2018 Jun 18, 2018

Copy link to clipboard

Copied

Hi Uwe,

Thank you replying to the thread. I need the over-bound images (only the over-bound images) to adjust withing the width and height of the text frame and not text column as I do not use more than one column in a page.

Basically, I am looking for a solution which can search the entire document for over-bound images (images sizing beyond text frame size: 5 inch {w} x 7.7 inch {h} either by width, height or both) and rescale (not trim) the images to fit under the frame size all the while leaving all the in-bound images unaffected.

Regards,

Aman Mittal

Votes

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 ,
Jun 18, 2018 Jun 18, 2018

Copy link to clipboard

Copied

So we can assume that all text frames are with the same size?

Regards,
Uwe

Votes

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