How to replace a graphic with given file in InDesign via script?

2.8k Views Asked by At

I need to replace some images in an InDesign document with a given file. This happens using the InDesign server, but scripting is almost the same as with regular InDesign, except no user interaction is possible.

What I have is a InDesign Document, the ID of an Rectangle containing some image and the Path to a new image that should replace the image.

The image should be replaced, but the settings like FitOptions etc. should stay the same. Also, the new file shall be embedded in the InDesign Document. There is already some code that sort of works:

function changeImages(doc) {
    var arrayLength = changeImage.length;
    for (var i = 0; i < arrayLength; i++) {
        var fr = doc.textFrames.itemByID(1 * changeImage[i].id);
        if (!fr)
            continue;
        var file = File(imagePath + changeImage[i].file);
        fr.place(file);
        fr.fit (FitOptions.CONTENT_TO_FRAME);
        fr.fit (FitOptions.PROPORTIONALLY);
        fr.fit (FitOptions.CENTER_CONTENT);

    }
}

This doesn't seem right. Why is it using doc.textFrames when the object is a rectangle? I am actually confused this even works.

Also it just sets some FitOptions, but I want to keep the existing.

I am very new to InDesign scripting, so I am lost here. I am reading the docs and other resources, but I am confused. e.g why is there doc.textFrames.itemByID but nothing like that for other Frames? Do I have to iterate doc.allPageItems and compare ids?

2

There are 2 best solutions below

0
On

Josef,

I've had the same problem with InDesign CS4 with keeping the original FitOptions. I was never able to figure out how to get the settings currently being used in InDesign CS4.

To get around the problem what I did was to set the value in the Fitting on Empty Frame in the Frame Fitting Options in the InDesign document.

enter image description here

Then in code I used that setting, something like this:

changeImages (app.activeDocument);
function changeImages(doc)
{
    with(doc)
    {
        var rec = doc.rectangles.itemByID(207);
        var file = new File("c:\\new_image.png");
        rec.place(file);
        rec.fit(rec.frameFittingOptions.fittingOnEmptyFrame);
    }
}
1
On

itemByID is a method available for all pageItems and both textFrames and rectangles are subclass of pageItem. So you have access to this method from both, and it'll give the same result. You should be able to use doc.rectangles.itemByID as well. See: http://www.indesignjs.de/extendscriptAPI/indesign11/#Rectangles.html#d1e201999__d1e202138

But you are right that the description is a bit confusing, it says:

Returns the TextFrame with the specified ID.

which is obviously not the case. If you already have the IDs you want to target, you could use doc.pageItems.itemByID, which is maybe less confusing, since basically you're looking for pageItems when using itemByID.

As for fitting options, they are a property of your rectangle object, so placing a new image shouldn't change the fitting options. If you want to keep the same, simply remove the calls to fit(). See in property list of Rectangle, frameFittingOptions: http://www.indesignjs.de/extendscriptAPI/indesign11/#Rectangle.html