Skip to main content
Known Participant
June 16, 2024
Question

Image swapping script scale issue question

  • June 16, 2024
  • 2 replies
  • 431 views

Hello 

 

I have a script below which I have been working on - it allows the user to select two things and swap the sizes. 

For example you need to swap the main image with a drop in image - this allows for the swap to happen with one shortcut.

The bad news is I am having a hard time getting the images inside frames to fit portionally once swapped  they still have the old sizing and do not adapt for the changing frame sizes. 

 

Any help on this would be great!

 

Many thanks 

 

Smyth

 

The samples below show the script before and after using coloured boxes and then a sample with phototos and the issue that arrises.

 

Before

 

After 

they have swaped placed 

 

 

and an example with photos below 

before

after  - it looks like there is nothing there but it because the images have not fitted proportionality

when I fit them myself i can see that they are there  - would be good if the script could also do this part so then the user only needs to adjust the crop to their liking 

 

 

 

 

 

 

 

 

#target indesign

app.doScript(function() {
    if (app.selection.length !== 2) {
        alert("Please select exactly two objects.");
    } else {
        var firstObject = app.selection[0];
        var secondObject = app.selection[1];

        // Ensure both objects are valid
        if (!firstObject.isValid || !secondObject.isValid) {
            alert("Invalid selection. Please select two valid objects.");
        } else {
            // Get the geometric bounds of both objects
            var firstBounds = firstObject.geometricBounds;
            var secondBounds = secondObject.geometricBounds;

            // Swap the geometric bounds (sizes and positions)
            firstObject.geometricBounds = secondBounds;
            secondObject.geometricBounds = firstBounds;

            // Adjust images within the swapped rectangles
            adjustImage(firstObject);
            adjustImage(secondObject);
        }
    }
}, ScriptLanguage.JAVASCRIPT, null, UndoModes.ENTIRE_SCRIPT, "Swap Object Sizes and Positions");

function adjustImage(rect) {
    if (rect.constructor.name === "Rectangle" && rect.graphics.length > 0) {
        var graphic = rect.graphics[0];
        if (graphic && graphic.itemLink && graphic.itemLink.isValid) {
            // Get the new dimensions of the rectangle
            var rectWidth = rect.geometricBounds[3] - rect.geometricBounds[1];
            var rectHeight = rect.geometricBounds[2] - rect.geometricBounds[0];

            // Get the current dimensions of the image
            var imageWidth = graphic.itemLink.imageProxy.width;
            var imageHeight = graphic.itemLink.imageProxy.height;

            // Calculate the scaling ratios
            var ratioWidth = rectWidth / imageWidth;
            var ratioHeight = rectHeight / imageHeight;

            // Determine the scaling ratio to fit the image proportionally within the rectangle
            var scaleRatio = Math.min(ratioWidth, ratioHeight);

            // Resize the image proportionally
            graphic.horizontalScale = scaleRatio * 100;
            graphic.verticalScale = scaleRatio * 100;
        }
    }
}

 

 

 

This topic has been closed for replies.

2 replies

rob day
Community Expert
Community Expert
June 17, 2024

Hi @SmythWharf , It might be easier to simply swap the links rather than deal the bounds. Something like this:

 

app.doScript(swapImages, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Swap Images');

function swapImages(){
    if (app.selection.length !== 2) {
        alert("Please select exactly two objects.");
    } else {
        var firstObject = app.selection[0];
        var secondObject = app.selection[1];
        if (!firstObject.isValid || !secondObject.isValid) {
            alert("Invalid selection. Please select two valid objects.");
        } else {
            var fp1 = firstObject.images[0].itemLink.filePath;
            var fp2 = secondObject.images[0].itemLink.filePath;
            firstObject.place(fp2);
            firstObject.fit(FitOptions.PROPORTIONALLY);
            secondObject.place(fp1);
            secondObject.fit(FitOptions.PROPORTIONALLY);
        }
    }
}

 

 

 

 

Known Participant
June 18, 2024

Hello,

Thank you Rob for taking time to look into this. 

I had a go and you have lead me down a positive track. 

The most ideal script would be able to swap anything, from text boxes, images and groups which comprises of both. 

I have had a go at updating the script and have tried content aware fit option 

It seems to work, fingers crossed. 

Best, 

Smyth

 

 

#target indesign

app.doScript(function() {
    if (app.selection.length !== 2) {
        alert("Please select exactly two objects.");
    } else {
        var firstObject = app.selection[0];
        var secondObject = app.selection[1];

        // Ensure both objects are valid
        if (!firstObject.isValid || !secondObject.isValid) {
            alert("Invalid selection. Please select two valid objects.");
        } else {
            // Get the geometric bounds of both objects
            var firstBounds = firstObject.geometricBounds;
            var secondBounds = secondObject.geometricBounds;

            // Swap the geometric bounds (sizes and positions)
            firstObject.geometricBounds = secondBounds;
            secondObject.geometricBounds = firstBounds;

            // Function to fit the images using content-aware fit in the given object
            function contentAwareFitImages(object) {
                if (object.constructor.name === "Rectangle" && object.images.length > 0) {
                    object.fit(FitOptions.CONTENT_AWARE_FIT);
                } else if (object.constructor.name === "Group") {
                    for (var i = 0; i < object.allPageItems.length; i++) {
                        if (object.allPageItems[i].constructor.name === "Rectangle" && object.allPageItems[i].images.length > 0) {
                            object.allPageItems[i].fit(FitOptions.CONTENT_AWARE_FIT);
                        }
                    }
                }
            }

            // Apply content-aware fit to images in both objects
            contentAwareFitImages(firstObject);
            contentAwareFitImages(secondObject);
        }
    }
}, ScriptLanguage.JAVASCRIPT, null, UndoModes.ENTIRE_SCRIPT, "Swap Object Sizes and Positions");

 

 

 

 

SychevKA
Inspiring
June 17, 2024

Hello,
First, you need to decide what is more important to you: the appearance of the image in the first frame or the characteristics of the second frame. Then set the properties.

my_graphic_frame.properties = {
		frameFittingOptions:{
			autoFit: ,
			fittingOnEmptyFrame: ,
			fittingAlignment: ,
			topCrop: ,
			bottomCrop: ,
			leftCrop: ,
			rightCrop:
		}
	}