Skip to main content
Known Participant
August 10, 2012
Question

Restart illustrator through script (or eliminate PARM error)

  • August 10, 2012
  • 2 replies
  • 4931 views

I'm working on a javascript that goes through a folder, rasterizes the paths inside each file, and saves the results as separate files in another folder. My script works fine on individual files as well as for several simple files. However, once it gets going on some of the big ones, it starts to give me PARM errors.

What I'm working with:

  • Illustrator CS5.1
  • Windows XP, SP3 (work computer)
  • Javascript
  • The CAD export that created the pdf and eps files broke any curves into tons of tiny straight lines. As a result, these drawings can have 15-35 thousand paths per image.

Summary of my code:

  • Get the source and destination directories
  • Open a file from the source directory
  • Go to the first layer of the file
  • Loop through all text items to move them to their own layer
  • Loop through all path and compound paths to move them to a group
  • Rasterize the group of path items
  • Repeat for the next layer and so on
  • Save the file to the destination directory
  • Repeat the process for the next file and so on

The scripting guide suggests it could be from conflicting functions or global variables overwriting each other. However, my script is now entirely contained within its own function, and all variables are declared locally. Running from a clean illustrator and ESTK startup, it will still produce a PARM error after a few large files.

The guide also suggests having the script quit and re-launch Illustrator after working on many files. Since I assume these huge diagrams are probably several "normal" files' worth of objects each, I figured it probably just needs to restart Illustrator after x amount of stuff goes through. So I look in the guide's section on launching Illustrator through javascript. That basically says "Why would you ever need to do that?" Gee, thanks. I tried looking it up in the tools guide, but that document isn't very clear at all.

So, onto my actual questions:

1. What would I have to do so Illustrator doesn't throw a PARM error on the line marked below? (besides just putting it in a try/catch and pretending it didn't happen) It doesn't consistently happen on the same file or even at the same point in the file, but always at that line.

This is just a tiny part of the script. objectClass is a placeholder for PathItems, CompoundPathItems, etc. Looping backwards and setting the group to null at the end were just experiments, neither of which had any effect on the error.

if(objectClass.length > 0){

    var objectGroup = myLayer.groupItems.add();

    for(var i = objectClass.length; i > 0; i--){

        objectClass[i-1].move(objectGroup, ElementPlacement.PLACEATBEGINNING); //This one keeps breaking stuff.

    }

    sourceDoc.rasterize(objectGroup, rastBounds, rastOptions);

    objectGroup = null;

}

2. Failing that, how can I relaunch Illustrator through javascript? Or a limited amount of VBScript, though my knowledge of that is limited too.

This topic has been closed for replies.

2 replies

Larry G. Schneider
Community Expert
Community Expert
August 13, 2012

Does it make any difference if you use  for(var i = objectClass.length-1; i => 0; i--)

BobH3Author
Known Participant
August 13, 2012

No difference at all. It appears to hang just after opening it, before it even makes the text layer

Inspiring
August 13, 2012

I have not had the time to test your script… After a quick overview… Question what is the visiible reason for moving before rasterizing files? Could you not have just opened in Photoshop and rasterize the file? Sorry just trying to justify what you are doing here…? While you can pass complex objects ( array, function, object etc.  ) through bridgetalk using toSource() you will need to eval on the other side…

Inspiring
August 11, 2012

"#target estoolkit" and use BridgeTalk to run your script function.

a basic example: https://gist.github.com/3321845

BobH3Author
Known Participant
August 13, 2012

I'm trying everything, but I can't get this to work. For the longest time I was stuck with the message simply not doing anything. Then I figured out the exact syntax I needed to send it. Then I discovered that single-line comments were breaking the function since it gets read like it's one continuous line. Now I'm stuck with the thing just locking up Illustrator in such a way that even Task Manager has trouble killing it. What on earth does it take to make this thing work?

Also, is there any way to get the script running synchronously? It tries calculating the totals before Illustrator has even finished opening.

#target estoolkit

rasterizeFolder();

/********************************************************************************************/

function rasterizeFolder()

{

    //Get the source and destination folders.

    //If either window is cancelled, end the script.

    var sourceFolder = getSourceFolder ();

    if(sourceFolder == null){return;}

    var destinationFolder = getDestinationFolder ();

    if(destinationFolder == null){return;}

   

    //Stuff for end-of-script statistics

    var fileCount = 0;

    var itemsProcessed = 0;

    var itemsToReset = 5000;   //Used to periodically close and reopen Illustrator to avoid memory issues.

    var startTime = new Date().getTime();

    var endTimeMS = 0;

    var endSecs = 0;

    var endMins = 0;

   

    //Rasterize files by type.

    rasterizeAllOfType ("*.eps");

    rasterizeAllOfType ("*.pdf");

   

    //Get the time taken for the script in milliseconds, and convert to minutes and seconds.

    endTimeMS = new Date().getTime() - startTime;

    endSecs = Math.floor(endTimeMS/1000);

    endMins = Math.floor(endSecs/60);

    endSecs -= (endMins*60);

   

    //Tell the user how long this took.

    alert(fileCount + " files rasterized in " + endMins + " minutes, " + endSecs + " seconds.");

   

   

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    function getSourceFolder(){

        var sourceFolder = Folder.selectDialog("Choose the folder you wish to rasterize.");

       

        if(sourceFolder == null){

            //User cancelled, do nothing.

            return;

        } else if(sourceFolder.getFiles().length < 1){

            //The folder contains nothing, make the user select another.

            alert("The source folder you selected contains no files. Select a different one.");

            sourceFolder = getSourceFolder ();

            return sourceFolder;

        } else {

            //We have a usable folder.

            return sourceFolder;

        }

    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    function getDestinationFolder(){

        var destinationFolder = Folder.selectDialog ("Where should the rasterized files go?");

       

        if(destinationFolder == null){

            //User cancelled, do nothing.

            return;

           

        } else if (destinationFolder.getFiles().length < 1){

            //The folder contains nothing and is therefore safe to use.

            return destinationFolder;

           

        } else if (sourceFolder.getFiles()[0].path == destinationFolder.getFiles()[0].path){

            //The user chose the same folder for the source and destination.

            //See if it's okay to overwrite the files in there.

            var OKtoOverwrite = confirm("Source and destination are the same. Files will be overwritten. Do you want to continue?");

           

            if (OKtoOverwrite == true){

                //Okay to overwrite, proceed.

                return destinationFolder;

            } else {

                //Not okay, make a different choice.

                destinationFolder = getDestinationFolder ();

                return destinationFolder;

            }

       

        } else {

            //Folder has contents, but turned out to be different than the source folder.

            return destinationFolder;

        }

    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    function rasterizeAllOfType(filetype)

    {

        //Get all files of the type I'm working on

        var fileList = new Array();

            fileList = sourceFolder.getFiles(filetype);

       

        if(fileList.length > 0){

            //There are files to work with of this type.

           

            //New code here.

            var j = 0;

            //AIrasterize (name); //EDIT ME

            AIrasterize(fileList, destinationFolder, itemsProcessed, itemsToReset);

            fileCount += fileList.length;

            return;asdfasdfasdf

           

        } else {

            //No files of this type are in the folder.

            return;

        }

        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

        function AIrasterize(fileList, destinationFolder, itemsProcessed, itemsToReset) {

            /*

              NOTICE:   If a function is being sent via bridgetalk, it must NOT contain any

                        single-line comments! The entire function is read as if it were only

                        a single line, so any // comments will kill the rest of the function.

              */

            var bt = new BridgeTalk();

            bt.target = 'illustrator';

            bt.body = rasterizeDoc.toSource() + "("+fileList.toSource()+","+destinationFolder.toSource()+","+itemsProcessed+","+itemsToReset+");";

            bt.onResult = function (resultMsg) {

//~                 while (BridgeTalk.getStatus('illustrator') != 'ISNOTRUNNING') $.sleep(20);

//~                 ++j < fileList.length && AIrasterize(fileList, destinationFolder, itemsProcessed, itemsToReset);

            }

            bt.send();

        }

        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

        function testing(something, sourceDoc)

        {

            alert("Hello. The passed variables are " + something + " and " + sourceDoc +".");

        }

        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

        function rasterizeDoc(myDoc, destinationFolder, itemsProcessed, itemsToReset)

        {

            /*Open the file*/

            app.open(myDoc);

            sourceDoc = myDoc;

           

            /*Set rasterize boundaries and options.*/

            var rastBounds = sourceDoc.visibleBounds;

            var rastOptions = new RasterizeOptions;

                rastOptions.antiAliasingMethod = AntiAliasingMethod.None;

                rastOptions.clippingMask = false;

                rastOptions.resolution = 300;

                rastOptions.convertSpotColors = false;

                rastOptions.transparency = true;

           

            /*Create a layer for text.*/

            var textLayer = sourceDoc.layers.add();

            textLayer.name = "Text Layer";

            /*Get the number of layers, then cycle through them.*/

            var layerCount = sourceDoc.layers.length;

            for(var i = 0; i < layerCount; i++){

                var myLayer = sourceDoc.layers;

                if(myLayer.locked == false && myLayer.visible == true && myLayer.name != "Text Layer"){

                   

                    /*Ungroup everything*/

                    ungroup(myLayer);

                    /*if(myLayer.groupItems.length > 0){alert("Ungrouping failure.");}*/

                   

                    /*Send all text frames and legacy text items to text layer*/

                    moveAllToLayer(myLayer.textFrames, textLayer);

                    moveAllToLayer(myLayer.legacyTextItems, textLayer);

                   

                    /*Rasterize all other kinds of object.*/

                    rasterizeObjectClass(myLayer.rasterItems);

                    rasterizeObjectClass(myLayer.pluginItems);

                    rasterizeObjectClass(myLayer.compoundPathItems);

                    rasterizeObjectClass(myLayer.pathItems);

                }

            }

       

            /*Get the full file path.*/

            var saveName = new File(destinationFolder + '/' + sourceDoc.name);

           

            /*Save the file as the appropriate type.*/

            switch(filetype){

                case "*.eps":

                    var saveSettingsEPS = new EPSSaveOptions;

                    sourceDoc.saveAs(saveName, saveSettingsEPS);

                    break;

                case "*.pdf":

                    var saveSettingsPDF = new PDFSaveOptions;

                    sourceDoc.saveAs(saveName, saveSettingsPDF);

                    break;

                default:

                    sourceDoc.saveAs(saveName);

                    break;

            }

           

            /*Close the file and clear the reference from memory.*/

            sourceDoc.close(SaveOptions.DONOTSAVECHANGES);

            sourceDoc = null;

           

            if(itemsProcessed > itemsToReset){

                alert("Processed " + itemsProcessed + " objects. Resetting to clear memory");

            }

            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

            function ungroup(myObject)

            {

                /*Note: myObject is always either a group or a layer.*/

               

                /*Get a list of everything inside this object.

                  This array is used instead of the actual callout so we can loop easier.*/

                var objectContents = new Array();

                for(var i=0; i < myObject.pageItems.length; i++){

                    objectContents.push(myObject.pageItems);

                }

                if(objectContents.length < 1){

                    /*destroy empty groups.*/

                    if(myObject.typename=="GroupItem"){

                        myObject.remove();

                    }

                    return;

                }else{

                    /*Loop through group contents*/

                    for(var i=objectContents.length; i > 0; i--){

                        try{

                            if(objectContents[i-1].parent.typename != "Layer"){

                                /*If I'm in a group, take me out of it and put me one level higher.*/

                                objectContents[i-1].moveBefore(myObject);

                            }

                            if(objectContents[i-1].typename == "GroupItem"){

                                /*If I AM a group, ungroup my contents.*/

                                ungroup(objectContents[i-1]);

                            }

                        }catch(err){

                        }

                    }

                }

            }

            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

            function moveAllToLayer(objectCollection, destLayer)

            {

                /*Make it workable*/

                var objectClass = new Array();

                    objectClass = objectCollection;

                   

                /*Moves all of the chosen kind of object to a layer.*/

                for(var i = objectClass.length; i > 0; i--){

                    objectClass[i-1].moveToBeginning(destLayer);

                }

                objectClass = null;

            }

            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

            function rasterizeObjectClass(objectCollection)

            {

                /*Make it workable*/

                var objectClass = new Array();

                    objectClass = objectCollection;

               

                /*If I have any items of this type, group them together and rasterize the group.*/

                if(objectClass.length > 0){

                    var objectGroup = myLayer.groupItems.add();

                    for(var i = objectClass.length; i > 0; i--){

                        try{

                            objectClass[i-1].move(objectGroup, ElementPlacement.PLACEATBEGINNING);

                            itemsProcessed += 1;

                        } catch(e) {

                        }

                    }

                    sourceDoc.rasterize(objectGroup, rastBounds, rastOptions);

                    objectGroup = null;

                }

                objectClass = null;

            }

            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

        }

        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    return;

}

Inspiring
August 14, 2012

Sorry for the "single-line comments" part. I should have advise you to use "toString()" to convert function to massage string, then there will be no problem.

So let's re-write the function:

function AIrasterize(fileList, destinationFolder, itemsProcessed, itemsToReset) {

    var bt = new BridgeTalk();

    bt.target = 'illustrator';

    bt.body = rasterizeDoc.toString() + ";rasterizeDoc(" + fileList.toSource() + "," + destinationFolder.toSource() + "," + itemsProcessed + "," + itemsToReset + ");";

    bt.onResult = function(resultMsg) {

        //~                 while (BridgeTalk.getStatus('illustrator') != 'ISNOTRUNNING') $.sleep(20);

        //~                 ++j < fileList.length && AIrasterize(fileList, destinationFolder, itemsProcessed, itemsToReset);

    }

    // tell you where error occur

    bt.onError = function(a) {

        alert(a.body + "(" + a.headers["Error-Code"] + ")")

    }

    bt.send();

    $.writeln(bt.body); // also you can use this code to debug, you will see you made some mistake in your code

}

Two major mistake in your code:

app.open(myDoc);
sourceDoc = myDoc;

myDoc is a File object here, not document!

Second, due to bridgeTalk, "filetype" should be an argument of AIrasterize and rasterizeDoc function.

As for the time count, you should get the end time within the BridgeTalk, either send start time to BT or send BT result back to calculate.

Hopeful with some debug, you can finally get you code work.