Copy link to clipboard
Copied
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:
Summary of my code:
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.
Copy link to clipboard
Copied
"#target estoolkit" and use BridgeTalk to run your script function.
a basic example: https://gist.github.com/3321845
Copy link to clipboard
Copied
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;
}
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
Moluapple:
Okay, I'm making some progress now. I fixed up AIrasterize like you said and then uncommented the part that makes it loop. It starts to work, but now I have a few more questions (in order of importance).
1. The looping code, bt.onResult's function, just stops after processing the first four files (the first four, not skipping). I tried putting an alert in there, and then the order went all over the place. However, files were being processed continuously and in order any time the alert box was up. Any idea what's going on there?
2. The looping code currently requires AI to quit before going onto the next file (i.e. "wait if AI is running"). I tried a few different checks on the status, but can't figure out a way to make the script go through if AI is already running. Ideally, AI would just check the itemsProcessed and itemsToReset variables and quit itself only when deemed necessary. What should the status check be to make this work?
3. I'm a little bit lost on your explanation for the time count. Could you clarify that bit?
Copy link to clipboard
Copied
What's your whole code looks like now?
PS:
After read more explanation of you purpose, I think you'd better use other method: record an action is more powerful, the action can be like this image
Copy link to clipboard
Copied
I didn't try Actions at first since my boss said he had no luck with it. I just tried the action you listed, and it works for some files, but not all. The problem is that only some of the diagrams have text in them. Once the action reaches a textless image, it ends up pasting the previous image's text onto this one. Additionally, it keeps changing the filetype from EPS to AI.
Back to scripting, here's what my code looks like now:
#target estoolkitrasterizeFolder();
/********************************************************************************************/
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 statistics
var fileCount = 0;
var itemsProcessed = 0;
var itemsToReset = 9000; //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;
}
}//End of getSourceFolder
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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;
}
}//End of getDestinationFolder
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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(fileList, destinationFolder, itemsProcessed, itemsToReset, filetype);
fileCount += fileList.length;
return;
} else {
//No files of this type are in the folder.
return;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
function AIrasterize(fileList, destinationFolder, itemsProcessed, itemsToReset, filetype) {
/*
NOTICE: If a function is sent via bridgetalk, either use <function>.toString()
or avoid using single-line comments in it. If just sent normally, it
will be read as if it is all one line, and thus break from comments.
*/
var bt = new BridgeTalk();
bt.target = 'illustrator';
bt.body = rasterizeDoc.toString() + ";rasterizeDoc("+fileList
.toSource()+","+destinationFolder.toSource()+","+itemsProcessed+","+itemsToReset+",'"+filetype+"');"; bt.onResult = function (resultMsg) {
var myStatus = BridgeTalk.getStatus('illustrator');
while (BridgeTalk.getStatus('illustrator') != 'ISNOTRUNNING') $.sleep(20);
//alert(j);
++j < fileList.length && AIrasterize(fileList, destinationFolder, itemsProcessed, itemsToReset, filetype);
}
bt.onError = function(a){
alert(a.body+"("+a.headers["Error-Code"]+")");
}
bt.send();
$.writeln(bt.body); //used to debug.
}//End of AIrasterize
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
function rasterizeDoc(myDoc, destinationFolder, itemsProcessed, itemsToReset, filetype)
{
/*Open the file*/
app.open(myDoc);
sourceDoc = app.activeDocument;
/*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);
/*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);
app.quit(); /*Workaround for AIrasterize bug. BT only goes to the next when AI is closed. */
/*
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){
}
}
}
}//End of ungroup
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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;
}//End of moveAllToLayer
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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;
}//End of rasterizeObjectClass
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
}//End of rasterizeDoc
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
}//End of rasterizeAllOfType
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
return;
}//End of rasterizeFolder
Copy link to clipboard
Copied
From some testing on the AIrasterize function, I've determined that it quits because it simply timed out. I'm just not sure how high I need to set the timeout value for it to work, however. There are a couple files even in my test batch that take 5 minutes to process.
I also did some testing on my own for the Illustrator status and learned quite a bit that the documentation doesn't explain. I was under the assumption that "Pumping" status only means the instant when a message is sent or received, but it apparently means any kind of processing initiated by the message, not just the send/receive. Likewise, "idle" and "busy" are only in regards to its ability to send and receive messages, and have no relation whatsoever to any processing not started by bridgetalk. I don't know how Adobe expected that to be clear from the explanation given in the manual.
Copy link to clipboard
Copied
There are a couple files even in my test batch that take 5 minutes to process.
Therefore I think you'd better re-write your function. What if you group all non-text-object and rasterize them in one go?
And if break the process into two parts: first group all and save/close file, second reopen and rasterize groupItem. Can this method aovid the 'PARM' error?
Any way, I have modified your code, and it should work. See code comments for my logic. https://gist.github.com/3321845#file_a%20realworld%20example.jsx
Copy link to clipboard
Copied
Your changes worked great, thank you so much. I can make a few tweaks to optimize it later on, but I can work with this now. Thanks again
EDIT: Wait, nope. The script will still just stop processing somewhere in the middle, it just takes longer. How should I handle the timeout? The timeout always occurs during AI's reset, and sometimes coincides with AI starting again but not loading a file.
I was thinking that quitting AI was canceling out the return 0, but even with bridgetalk itself closing AI after getting a result, it will still time out. Any idea what's going on here?
EDIT 2: One other thing- Is there any way to preserve objects' z-order in this code? There are a handful of illustrator-made images lumped in with all of the converted CAD drawings, and the grouping sections of my code end up shuffling all the parts around, thus ruining the image. It's not a huge issue since only a few images are like this, I'd just prefer not having to watch out for it.
Copy link to clipboard
Copied
Try my suggestion in last reply:
1. Collect textFrames, group all others(I think you do not need ungroup groupItems first at all), save, close;
2. Re-open, rasterize the groupItem, save, close;
3. Repeat for the next file.
If this method work, then you don't need BridgeTalk at all.
For above script's problem, I think I have no idea without your testing files. Could you upload some sample files?
Also with sample files I can check if it is possible to combine action with script(a litter VBScript code).
Copy link to clipboard
Copied
Even with the process split up like you say, it will still encounter a PARM error when grouping things to rasterize them. The ungrouping is necessary, since the move and moveToBeginning methods refuse to do anything with items that are inside a group.
----
Back on the BridgeTalk version, I think I finally figured out why it keeps timing out:
The .send() method has a timeout parameter listed in the Tools Guide, which is what I've been using. However, I determined that the message was timing out at 1 minute, regardless of what I set as its value.
Looking at that section of the guide again, I found that there's also a timeout property for the BridgeTalk object. This one actually does work. I set that to what I think is a high enough number, and the script is working fine now. The number has to be pretty high, though. I've seen at least one drawing in the batch that had 98,000 page items in it.
----
I'll see what I can do about sample images for the other issue later.
Copy link to clipboard
Copied
Glad it finally works.
On the group issue, what I mean is loop through all pageItems, not each type separately.
Here is the main function follow my logic:
function layersCheck(doc) {
var oLayers = doc.layers,
len = oLayers.length,
oLayer;
for (; len-- > 0;) {
oLayer = oLayers[len];
oLayer.locked && oLayer.locked = false; // if locked, unlock it
!oLayer.visible && (oLayer.visible = true, oLayer.remove()); // if not visible, delete it
}
}
function extractText_RasterizeAll(doc) {
var t = (doc.legacyTextItems.convertToNative(), doc.textFrames),
l = t.length,
layer = doc.layers.add(),
group = layer.groupItems.add(),
i = -1,
rastOptions = new RasterizeOptions,
len, p, oLayer;
// collect text objects, legacyTextItems have been converted to native textItems
for (; ++i < l; t.move(layer, ElementPlacement.PLACEATBEGINNING));
// group all other objects, remove empty layers
while (doc.layers.length > 1) {
oLayer = doc.layers[doc.layers.length - 1];
for (p = oLayer.pageItems.length; p-- > 0; oLayer.pageItems
.move(group, ElementPlacement.PLACEATBEGINNING));
oLayer.remove();
}
// rasterize the group
rastOptions.antiAliasingMethod = AntiAliasingMethod.None;
rastOptions.clippingMask = false;
rastOptions.resolution = 300;
rastOptions.convertSpotColors = false;
rastOptions.transparency = true;
doc.rasterize(group, group.visibleBounds, rastOptions);
}
layersCheck(activeDocument);
extractText_RasterizeAll(activeDocument);
The result: a single raster image object and all text objects in one layer.
Note: Above code does not handle sublayers.
Copy link to clipboard
Copied
Does it make any difference if you use for(var i = objectClass.length-1; i => 0; i--)
Copy link to clipboard
Copied
No difference at all. It appears to hang just after opening it, before it even makes the text layer
Copy link to clipboard
Copied
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…
Copy link to clipboard
Copied
Muppet Mark:
Well, moving the text items to their own layer is actually just an artifact from the manual process I was automating. I realized the other day that it was sort of pointless to do in the script, but didn't get around to removing that bit just yet. All of the text must remain as actual text so it will be searchable when the images are used in a pdf manual.
Or were you asking about grouping all of the things I'm going to rasterize? Trying to rasterize the whole pathItems or pageItems objects just gives an error, but I read that it was doable with grouping so I went with that. I'm under the impression that having all of the pieces rasterized individually would still cause performance issues when viewing the final manual. (The manual is intended for use on a tablet, so having several complex images makes it slower to use than the paper manual it's set to replace)
And I hadn't thought of Photoshop, since I've only ever used it for raster. Am I overcomplicating things by using a vector program to do work on vector images? Somehow that wouldn't surprise me...
Moluapple:
I'll try your suggestion shortly.