Javascript how-to noob


#1

Can someone point me int he right direction on how to use image calculator in javascripting? I’m trying to convert macro language to something faster in current FIJI. I’ve recorded the step via script recorder (in javascript mode) and see:
ic = new ImageCalculator();
imp1 = WindowManager.getImage(“wrk”);
imp2 = WindowManager.getImage(“MED”);
imp3 = ic.run(“Subtract”, imp1, imp2);
imp3.show();

I import Classes importClass(Packages.ij.IJ); importClass(Packages.ij.plugin.ImageCalculator);
I have already created imagePlus 3 and 4, so I thought I could write:
imp5 = ic.run(“Subtract”, imp4, imp3);

But that fails:
java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.runtime.Undefined to ij.ImagePlus
at java.lang.invoke.MethodHandleImpl.newClassCastException(MethodHandleImpl.java:361)
at java.lang.invoke.MethodHandleImpl.castReference(MethodHandleImpl.java:356)
So I tried to add the recorder text WindowManager.getImage and the imp name, but that threw error that it didn’t recognize WindowManager. If I used IJ.WindowManager.getImage, then it didn’t recognize the imp name. (my guess is I need to SHOW the imp as a window for this to work; that would be slow for my purpose)

If I have imp already defined, how can I run an imageCalculator? Example, please?


#2

I get this from the macro recorder (‘Substract create’) which works fine:

importClass(Packages.ij.plugin.ImageCalculator);
importClass(Packages.ij.WindowManager); 

ic = new ImageCalculator();
imp1 = WindowManager.getImage("MED");
imp2 = WindowManager.getImage("wrk");
imp3 = ic.run("Subtract create", imp1, imp2);
imp3.show();
imp5 = ic.run("Subtract create", imp2, imp3);
imp5.show();

Please note that the imports have to be made for javascript in FIJI. In Imagej they are default:

https://imagej.nih.gov/ij/developer/javascript.html


#3

thanks for the suggestions. Can this be done without windowmanager get image calls since the imp’s are pre-created? In other words, does mean I must open a window display for each image for this work?


#4

I found an older thread in the ImageJ mailing list which worked by setting the javascript in batch mode or using the -batch argument on the command line:

http://imagej.1557.x6.nabble.com/JavaScript-batch-mode-doesn-t-have-open-images-td3687827.html

importClass(Packages.ij.plugin.ImageCalculator);
importClass(Packages.ij.WindowManager); 

Packages.ij.macro.Interpreter.batchMode = true;
 
ic = new ImageCalculator();
imp1 = WindowManager.getImage("MED");
imp2 = WindowManager.getImage("wrk");
imp3 = ic.run("Subtract create", imp1, imp2);
imp4 = ic.run("Subtract create", imp2, imp3);

Packages.ij.macro.Interpreter.batchMode = false; 
//imp4.show();

#5

No need to use WindowManager at all if you have your ImagePlus objects in variables already. Just try it :slight_smile:

imp1 = // get your first image from somewhere
imp2 = // get your second image from somewhere else

ic = new ImageCalculator();
imp3 = ic.run("Subtract create", imp1, imp2);
imp4 = ic.run("Subtract create", imp2, imp3);

You won’t need to use any batch mode settings for this.


#6

Thanks, I tried that and got strange errors indicating the result imp was ‘null’; up to today. Today the code works with really no changes… [strange]

I’m almost running! One last hurdle is I create a running median IMP that I need to close to avoid building up images when running on a stack. I tried “imp4.close()” but the run now requires the user to hit ‘OK’ to close the image (it’s interactive). How to have it close the IMP without a prompt?
I did try the batchmode suggested above, and that does run without prompting, but my code crashed at the end where somehow an input imp got closed inappropriately. Being total noob, I am hoping to close without prompts vs trying to figure out the wrong-close-in-batch issue.


#7

Have a look at the ImageJ API:

https://imagej.nih.gov/ij/developer/api/ij/ImagePlus.html#close--

To avoid the “Save changes?” dialog, first set the public ‘changes’ variable to false.

https://imagej.nih.gov/ij/developer/api/ij/ImagePlus.html#changes


#8

Thank you Bio7! That tip saved me weeks of digging, no doubt.
imp3.changes = false; that turns off the ‘save changes’ nags. NICE

I’m using macro code to copy/paste between IMPs, but would “insert” be faster/more direct?
“insert(ImageProcessor ip, int xloc, int yloc)”
"Inserts the image contained in ‘ip’ at (xloc, yloc)."
versus

IJ.run(imp5, "Copy", "");
imp2.setSlice(i);
IJ.run(imp2, "Paste", "");

(so I would need to getProcessor for the IMP, then run this?)


#9

If that function is what you need (I never used it). You could always measure rough the effciency by yourself, by using something like: