Image Processing Course Macros, Java & Plugins Day 2 Overview • Java – The Java Programming Language – Plugins vs. Macros – Eclipse IDE setup – Introduction to Java – The Plugin, PluginFilter and IJ Classes – Your first Plugin! • Day 3: MathLab & CellProfiler 2 Fiji / ImageJ are Written in Java • ImageJ was written in Java because of its platform independence and high-level programming capabilities. – People could contribute Plugins (Small Java programs that can be read by ImageJ) with little effort. • Fiji helped formalize the structure in the plugins and take it many steps further (Version Control, Maven Project Integration, ImgLib2, Wiki, etc…). • We are not going to cover the perfect, programmer-indented way to create plugins, but the simpler “Classical” ImageJ approach. 3 ImageJ/Fiji Plugins and Java • Java: a computer programming language that is concurrent, class-based, objectoriented and WORA (“write once, run anywhere”). • To code in Java, 3 things are needed: – A Java Compiler. – A Java Virtual Machine (JVM). – A text editor, or better, an IDE (Integrated development environment). 1. 2. You edit your code in the IDE, which helps you navigate through your program structure. You then compile it (.class file) and finally run it on the JVM. 4 Compiling • Compiling is the process through which humanreadable code is translated into machine-readable code. 5 What are JRE/JDK in Java? • To run Fiji, you need to have Java installed – What people commonly call Java is the JRE (Java Runtime Environment) • To create Java code, you need the JDK (Java Development Kit) 6 Compiling vs. Scripts or Macros • Scripting languages must interpret each line as you run the command (Make a mini-compilation step and run it.). – This adds flexibility but at the cost of speed. Vs. • Java is a hybrid – It compiles a ‘universal’ Bytecode – The Bytecode is read by the Java Virtual Machine – The JVM converts it to machine language specific to your system (Mac, Win, Unix/Linux). • It is almost as fast as compiled languages like C++ Platform independent Same program, but compiled for different platforms 7 Your First ImageJ Plugin 8 Your First ImageJ Plugin 8 Your First ImageJ Plugin 8 Your First ImageJ Plugin 8 Your First ImageJ Plugin 8 Your First ImageJ Plugin 8 Your First ImageJ Plugin 8 Your First ImageJ Plugin 8 Your First ImageJ Plugin 8 Your First ImageJ Plugin C:\Fiji\My_Plugin.java:12: cannot find symbol symbol : variable imp location: class My_Plugin IJ.setAutoThreshold(imp, "Default"); ^ C:\Fiji\My_Plugin.java:14: cannot find symbol symbol : variable imp location: class My_Plugin IJ.run(imp, "Convert to Mask", ""); ^ 2 errors 8 Your First ImageJ Plugin • The Structure 9 Java Classes • The missing variable imp is a Java variable of class ImagePlus. This is how Fiji stores the images. • Similarily, the IJ class contains a getImage function, and a setAutoThreshold function. 10 Java Classes • The missing variable imp is a Java variable of class ImagePlus. This is how Fiji stores the images. • Similarily, the IJ class contains a getImage function, and a setAutoThreshold function. All are classes 10 Java Functions • Java functions can have multiple inputs, and have only one output. public static void main(String[] args) // Here is where you write // what the function does } public int count(String name) { // Return number of characters return name.length() } public double multiply(double a, double b) { // Return multiplication return a*b; } 11 Java Variables • • A variable contains something. It can be a number (int, double, float), text (String, char) or a Class (ImageProcessor, ImagePlus) . Java requires that each variable be given a type. This is called explicit typecasting. int a_number = 10; //Declaring an integer double another_number = 14.2; //Declaring a number with double precision float and_another = (float) 35.2245; //Declaring a number with single precision long yet_another_number = (long) 2.3; //Declaring a number with twice the bytes as a double String my_string = "A text string"; //Declare a string and initialize it. ImageProcessor ip = new FloatProcessor(100, 100); //Declare a new ImageProcessor 12 Java Variables • • A variable contains something. It can be a number (int, double, float), text (String, char) or a Class (ImageProcessor, ImagePlus) . Java requires that each variable be given a type. This is called explicit typecasting. int a_number = 10; //Declaring an integer double another_number = 14.2; //Declaring a number with double precision float and_another = (float) 35.2245; //Declaring a number with single precision long yet_another_number = (long) 2.3; //Declaring a number with twice the bytes as a double String my_string = "A text string"; //Declare a string and initialize it. ImageProcessor ip = new FloatProcessor(100, 100); //Declare a new ImageProcessor • In Java, exept for the base types, EVERYTHING is a class 12 Inheritance • Classes build on other classes. They inherit the functions of their parent and can add functionality. Extends keyword. public class Shape { void draw() { //Draw the shape } void erase() {//Erase the shape } void move() { //move the shape the shape } int[] getColor() { //return color as int array } void setColor(int[] color) { //set the color } } public class Triangle extends Shape{ void flipVertical() { //Flip shape} void flipHorizontal() {//Flip shape } } Triangle MyTriangle = new Triangle(); Int[] color = myTriangle.getColor(); myTriangle.setColor(new int[]{255,0,0}); myTriangle.flipVertical(); myTriangle.draw(); 13 Inheritance, Interfaces • Interfaces are “empty” Java Classes that explicitly state what functions you should write (implement, in Java slang). • PlugIn and PlugInFilter are Interfaces public class MyPlugIn implements PlugInFilter {… public class MyPlugIn implements PlugIn {… • That way ImageJ knows that whatever you write, it can use the run function to launch your plugin! 14 Inheritance, Interfaces • Interfaces are “empty” Java Classes that explicitly state what functions you should write (implement, in Java slang). • PlugIn and PlugInFilter are Interfaces public class MyPlugIn implements PlugInFilter {… PlugInFilter: void run(ImageProcessor ip) Filters use this method to process the image. int setup(java.lang.String arg, ImagePlus imp) This method is called once when the filter is loaded. public class MyPlugIn implements PlugIn {… PlugIn: void run(java.lang.String arg) This method is called when the plugin is loaded. • That way ImageJ knows that whatever you write, it can use the run function to launch your plugin! 14 Example PlugInFilter interface setup () method is invoked first when plugin is executed. Static variable of type integer (int) run() method receives an object (ip) of type ImageProcessor. Taken from:W. Burger, M.J. Burge Digital Image Processing, Springer Science 2008, p.33 27 Example PlugIn interface Declaration of local variables (they can only be used inside this method). Loop to calculate the values for the new image (iterate over all image coordinates). Display Image (=ImagePlus) 28 Usage of methods Declaration of global variables (they can be used/modified inside the entire class). run() method calls (javaish for executes or goto) two methods(). methods (): only executed when explicitly called. 29 Making Java Classes • • • • • • • • Classes are containers They can have methods (functions), and fields (variables). The fields are accessible by all functions. They are global. They can import other classes and use them. They can inherit other classes You access what is inside a class by using the “dot” (.) operator. Private fields or methods are not accessible except by the class itself. public class MyNameClass { // Class fields. These are accessible to all the functions inside the class private String number; //private means that other classes cannot access it. private String name; // Constructor public MyNameClass(String name, String number) { setNumber(number); setName(name); } // Public Methods // Setters public void setNumber(String a_new_number) { int length = a_new_number.length(); if(length == 10) { this.number = a_new_number; } else { System.out.println("Could not set number '“ +a_new_number+"'.\n is “ +length+" characters. Expected 10"); } } public void setName(String a_new_name) { this.name = a_new_name; } // Getters public String getName() { return this.name; } public String getNumber() {return this.number;} What does this class do? } private String prettyNumber() { String pretty_num = this.number.substring(0, 3)+"-“ +this.number.substring(3, 6)+" "+this.number.substring(6, 10); return pretty_num; } public void printData() { System.out.println("Name: "+getName()+" \tnumber: "+prettyNumber()); } 15 Making Java Classes: Getters and Setters • The best way to access methods is through setters and getters. • They start with the get or set words. • This makes searching for functions easy. – – public class MyNameClass { // Class fields. These are accessible to all the functions inside the class private String number; //private means that other classes cannot access it. private String name; // Constructor public MyNameClass(String name, String number) { setNumber(number); setName(name); } // Public Methods // Setters public void setNumber(String a_new_number) { int length = a_new_number.length(); if(length == 10) { this.number = a_new_number; } else { System.out.println("Could not set number '“ +a_new_number+"'.\n is “ +length+" characters. Expected 10"); } } For example. To set the title of an image, on might search for a setTitle function If we are looking to get the name of the image, we should start by looking for a getTitle function. public void setName(String a_new_name) { this.name = a_new_name; } // Getters public String getName() { return this.name; } public String getNumber() {return this.number;} } private String prettyNumber() { String pretty_num = this.number.substring(0, 3)+"-“ +this.number.substring(3, 6)+" "+this.number.substring(6, 10); return pretty_num; } public void printData() { System.out.println("Name: "+getName()+" \tnumber: "+prettyNumber()); } 16 Making Java Classes: Getters and Setters • The best way to access methods is through setters and getters. • They start with the get or set words. • This makes searching for functions easy. – – public class MyNameClass { // Class fields. These are accessible to all the functions inside the class private String number; //private means that other classes cannot access it. private String name; // Constructor public MyNameClass(String name, String number) { setNumber(number); setName(name); } // Public Methods // Setters public void setNumber(String a_new_number) { int length = a_new_number.length(); if(length == 10) { this.number = a_new_number; } else { System.out.println("Could not set number '“ +a_new_number+"'.\n is “ +length+" characters. Expected 10"); } } For example. To set the title of an image, on might search for a setTitle function If we are looking to get the name of the image, we should start by looking for a getTitle function. public void setName(String a_new_name) { this.name = a_new_name; } // Getters public String getName() { return this.name; } public String getNumber() {return this.number;} } private String prettyNumber() { String pretty_num = this.number.substring(0, 3)+"-“ +this.number.substring(3, 6)+" "+this.number.substring(6, 10); return pretty_num; } public void printData() { System.out.println("Name: "+getName()+" \tnumber: "+prettyNumber()); } 16 Making Java Classes: Getters and Setters • The best way to access methods is through setters and getters. • They start with the get or set words. • This makes searching for functions easy. – – public class MyNameClass { // Class fields. These are accessible to all the functions inside the class private String number; //private means that other classes cannot access it. private String name; // Constructor public MyNameClass(String name, String number) { setNumber(number); setName(name); } // Public Methods // Setters public void setNumber(String a_new_number) { int length = a_new_number.length(); if(length == 10) { this.number = a_new_number; } else { System.out.println("Could not set number '“ +a_new_number+"'.\n is “ +length+" characters. Expected 10"); } } For example. To set the title of an image, on might search for a setTitle function If we are looking to get the name of the image, we should start by looking for a getTitle function. public void setName(String a_new_name) { this.name = a_new_name; } // Getters public String getName() { return this.name; } public String getNumber() {return this.number;} } private String prettyNumber() { String pretty_num = this.number.substring(0, 3)+"-“ +this.number.substring(3, 6)+" "+this.number.substring(6, 10); return pretty_num; } public void printData() { System.out.println("Name: "+getName()+" \tnumber: "+prettyNumber()); } 16 Making Java Classes: Getters and Setters • The best way to access methods is through setters and getters. • They start with the get or set words. • This makes searching for functions easy. public class MyNameClass { // Class fields. These are accessible to all the functions inside the class private String number; //private means that other classes cannot access it. private String name; // Constructor public MyNameClass(String name, String number) { setNumber(number); setName(name); } // Public Methods // Setters public void setNumber(String a_new_number) { int length = a_new_number.length(); if(length == 10) { this.number = a_new_number; } else { System.out.println("Could not set number '“ +a_new_number+"'.\n is “ +length+" characters. Expected 10"); } } For example. To set the title of an image, on might search for a setTitle ImagePlus Setters function – If we are looking to get the name of the image, we should start by looking for a getTitle function. – public void setName(String a_new_name) { this.name = a_new_name; } // Getters public String getName() { return this.name; } public String getNumber() {return this.number;} } private String prettyNumber() { String pretty_num = this.number.substring(0, 3)+"-“ +this.number.substring(3, 6)+" "+this.number.substring(6, 10); return pretty_num; } public void printData() { System.out.println("Name: "+getName()+" \tnumber: "+prettyNumber()); } 16 Making Java Classes: Getters and Setters • The best way to access methods is through setters and getters. • They start with the get or set words. • This makes searching for functions easy. public class MyNameClass { // Class fields. These are accessible to all the functions inside the class private String number; //private means that other classes cannot access it. private String name; // Constructor public MyNameClass(String name, String number) { setNumber(number); setName(name); } // Public Methods // Setters public void setNumber(String a_new_number) { int length = a_new_number.length(); if(length == 10) { this.number = a_new_number; } else { System.out.println("Could not set number '“ +a_new_number+"'.\n is “ +length+" characters. Expected 10"); } } For example. To set the title of an image, on might search for a setTitle ImagePlus Setters function ImagePlus Getters – If we are looking to get the name of the image, we should start by looking for a getTitle function. – public void setName(String a_new_name) { this.name = a_new_name; } // Getters public String getName() { return this.name; } public String getNumber() {return this.number;} } private String prettyNumber() { String pretty_num = this.number.substring(0, 3)+"-“ +this.number.substring(3, 6)+" "+this.number.substring(6, 10); return pretty_num; } public void printData() { System.out.println("Name: "+getName()+" \tnumber: "+prettyNumber()); } 16 An advanced example Constructors; name must be identical to the class name set() & get() methods 36 An advanced example public void iterate(int shift){ for (int i=0;i<width;i++){ for (int j=0;j<height;j++){ double dist=Math.sqrt(Math.pow(i+shift, 2)+Math.pow(j,2)); int value=(int)(256*Math.sin(dist/frequ)); ip.putPixel(i, j, value); } } } Can you find the differences? 37 Introducing The Eclipse IDE • IDEs Can: • Autocomplete • Detect syntax errors • Suggest corrections • Automate integration (into FIJI) after compilation. 17 Installing Eclipse • Get Java Development Kit at http://tiny.cc/adip-java • Download Eclipse at http://tiny.cc/adip-eclipse – Extract to Disk / Mount 18 Installing Eclipse • Get Java Development Kit at http://tiny.cc/adip-java • Download Eclipse at http://tiny.cc/adip-eclipse – Extract to Disk / Mount 18 Launching Eclipse • Launch Eclipse • Enter the folder where all your projects will be stored. 19 Launching Eclipse • Launch Eclipse • Enter the folder where all your projects will be stored. 19 Launching Eclipse 20 The Eclipse Layout 21 The Eclipse Layout All your plugins will appear here 21 The Eclipse Layout Your code will appear here All your plugins will appear here 21 The Eclipse Layout Your code will appear here All your plugins will appear here The structure of your program will appear here 21 The Eclipse Layout Your code will appear here All your plugins will appear here The structure of your program will appear here Errors and warnings will appear here. 21 ImageJ-Eclipse ImageJ Wiki-The ImageJ Eclipse Howto Author: Patrick Pirrotte http://imagejdocu.tudor.lu/doku.php?id=howto:plugins:the_imagej_eclipse_howto 49 Import a Sample Java Application • Go to tiny.cc/adip-java-sample, and unzip the file somewhere. 22 Import a Sample Java Application • Go to tiny.cc/adip-java-sample, and unzip the file somewhere. 22 Import a Sample Java Application • Go to tiny.cc/adip-java-sample, and unzip the file somewhere. 22 Import a Sample Java Application • Go to tiny.cc/adip-java-sample, and unzip the file somewhere. 22 Import a Sample Java Application • Go to tiny.cc/adip-java-sample, and unzip the file somewhere. 22 Import a Sample Java Application • Go to tiny.cc/adip-java-sample, and unzip the file somewhere. 22 Import a Sample Java Application • Go to tiny.cc/adip-java-sample, and unzip the file somewhere. 22 Import a Sample Java Application • Go to tiny.cc/adip-java-sample, and unzip the file somewhere. 22 Import a Sample Java Application • Go to tiny.cc/adip-java-sample, and unzip the file somewhere. 22 Import a Sample Java Application • Go to tiny.cc/adip-java-sample, and unzip the file somewhere. 22 Running A Java Application • Open MyMainProgram.java • Run it public class MyMainProgram { public static void main(String[] args) { MyNameClass MyData = new MyNameClass("Olivier Burri", "0216932629"); // Calling the constructor System.out.println("My name is "+MyData.getName()+" and my number is: "+MyData.getNumber()); System.out.println("Changing my number to 021 369 88888"); MyData.setNumber("021 369 88888"); // Prepare three copies of MyNameClass as an array MyNameClass[] PeopleData = new MyNameClass[3]; PeopleData[0] = new MyNameClass("Romain Guiet", "0216932629"); PeopleData[1] = MyData; PeopleData[2] = new MyNameClass("Arne Seitz", "0216932632"); • Console output: System.out.println("Printing contents of the PeopleData Array:"); for(int i=0; i<3; i++) { PeopleData[i].printData(); } } } 23 How Does It Run? • When a Class needs to be run, it contains the main method. public static void main(String[] args) { • The JVM takes this as the starting point for the program. – It calls the main method with the arguments contained in args. • In ImageJ the Plugins Manager starts the Plugin by calling the run method (Or setup, then run, if it is a PlugInFilter) 24 Plugins: A Minimalistic Plugin • Go to tiny.cc/adip-first-plugin , and unzip the file somewhere. 25 Plugins: A Minimalistic Plugin • Go to tiny.cc/adip-first-plugin , and unzip the file somewhere. 25 Plugins: A Minimalistic Plugin • Go to tiny.cc/adip-first-plugin , and unzip the file somewhere. 25 Plugins: A Minimalistic Plugin • Go to tiny.cc/adip-first-plugin , and unzip the file somewhere. 25 Plugins: A Minimalistic Plugin • Go to tiny.cc/adip-first-plugin , and unzip the file somewhere. 25 Plugins: A Minimalistic Plugin • Go to tiny.cc/adip-first-plugin , and unzip the file somewhere. 25 Plugins: A Minimalistic Plugin • Go to tiny.cc/adip-first-plugin , and unzip the file somewhere. 25 Plugins: A Minimalistic Plugin • Go to tiny.cc/adip-first-plugin , and unzip the file somewhere. 25 Plugins: A Minimalistic Plugin • Go to tiny.cc/adip-first-plugin , and unzip the file somewhere. 25 Plugins: A Minimalistic Plugin • Go to tiny.cc/adip-first-plugin , and unzip the file somewhere. 25 Build Run Minimalistic Plugin - Build creates the .jar file and copies it to the Fiji Folder. - Run launches ImageJ and runs your plugin 26 Configure Build and Run 27 Configure Build and Run 27 Configure Build and Run 27 Configure Build and Run 27 Configure Build and Run 27 Configure Build and Run 27 Configure Build and Run 27 Configure Build and Run 27 Configure Build and Run 27 Configure Build and Run 27 Configure Build and Run 27 Configure Build and Run 27 Configure Build and Run 27 Configure Build and Run 27 The Ant File: Building Made… “Simple” • Open build.xml Where Fiji is located Must have same name The files your plugin needs in order to run. 28 The Ant File: Building Made… “Simple” • Open build.xml Where Fiji is located Must have same name The files your plugin needs in order to run. 28 Why suffer? • Get http://tiny.cc/adip-speedTest • And run the macro as well as the plugin. 29 Import example plugins 1 2 3 30 Import example plugins 4 31 Now Onwards to Java! 32 Now Onwards to Java! Imports are packages that contain other java classes 32 Now Onwards to Java! Imports are packages that contain other java classes This is your class. It is public and implements the PlugIn interface 32 Now Onwards to Java! Imports are packages that contain other java classes This is your class. It is public and implements the PlugIn interface @ tags are annotations, a form of metadata 32 Now Onwards to Java! Imports are packages that contain other java classes This is your class. It is public and implements the PlugIn interface @ tags are annotations, a form of metadata run is a function inside the class My_First_Plugin It takes an argument called arg0 which is a String (another Class) It is a public function and has no return argument (void) 32 Now Onwards to Java! Imports are packages that contain other java classes This is your class. It is public and implements the PlugIn interface @ tags are annotations, a form of metadata run is a function inside the class My_First_Plugin It takes an argument called arg0 which is a String (another Class) It is a public function and has no return argument (void) showAbout is another function inside the class My_First_Plugin It takes no argument and is a private function. 32 Now Onwards to Java! Imports are packages that contain other java classes This is your class. It is public and implements the PlugIn interface @ tags are annotations, a form of metadata run is a function inside the class My_First_Plugin It takes an argument called arg0 which is a String (another Class) It is a public function and has no return argument (void) showAbout is another function inside the class My_First_Plugin It takes no argument and is a private function. In showAbout, we call the IJ class, which we imported from the ij package with import ij.* and use the static function showMessage from that class to display a message. showMessage takes 2 arguments, both Strings. 32 How To Find Anything in Java? AutoComplete! • There are thousands of classes, it’s impossible to remember everything. • Eclipse can autocomplete things after you press the . operator. You can get a lot of information this way. 1. 2. A list of all methods and variables available in the class. It also displays whatever documentation was written by the programmer The documentation is called JavaDoc 33 Getting the ImageJ Javadoc and making plugins! • The most useful classes are – IJ (Accessing of most of ImageJ’s menus) – GenericDialog (Creating macro-recordable dialog boxes) – ResultsTable (Display results after analyses) – RoiManager (Get and manipulate ROIs) – They are all inside the ij.jar file – You can also navigate to http://imagej.nih.gov/ij/developer/api/ Configuring the Javadoc for making plugins • http://imagej.nih.gov/ij/developer/api/ 34 PlugIn Interface • The simplest plugin to use. May not even need an image. public class PlugIn_Plugin implements PlugIn { @Override public void run(String arg0) { //Your code here } • Exercise: Get the name of the current image and display it in the log. • Start from My_First_Plugin.java 35 Simple Plugin • Complete the function public class My_First_Plugin implements PlugIn { @Override public void run(String arg0) { // Get the current Image ImagePlus imp = IJ.getImage(); // Use IJ.getImage(); // Write this to the ImageJ log IJ.log("Image Name is: "+imp.getTitle() ); // Use IJ.log(); } } 36 Simple Plugin • Complete the function public class My_First_Plugin implements PlugIn { @Override public void run(String arg0) { // Get the current Image ImagePlus imp = IJ.getImage(); // Use IJ.getImage(); // Write this to the ImageJ log IJ.log("Image Name is: "+imp.getTitle() ); // Use IJ.log(); } } 37 Simple Plugin • Complete the function public class My_First_Plugin implements PlugIn { @Override public void run(String arg0) { // Get the current Image ImagePlus imp = IJ.getImage(); // Use IJ.getImage(); // Write this to the ImageJ log IJ.log("Image Name is: "+imp.getTitle() ); // Use IJ.log(); } } 38 Useful Class Functions • IJ.run(options); • IJ.getImage(); 39 Apply an ImageJ command or Plugin • Use the recorder in Java mode • Apply a “Find Edges” Filter to find the Java syntax. • Exercise: Get the image, duplicate it and find the edges on the new image. Display the new image 40 Apply an ImageJ command or Plugin • Use the recorder in Java mode • Apply a “Find Edges” Filter to find the Java syntax. • Exercise: Get the image, duplicate it and find the edges on the new image. Display the new image 40 Apply an ImageJ command or Plugin • Use the recorder in Java mode • Apply a “Find Edges” Filter to find the Java syntax. • Exercise: Get the image, duplicate it and find the edges on the new image. Display the new image 40 Apply a command or Plugin • Correction // Get the current Image ImagePlus imp = IJ.getImage(); // Use IJ.getImage(); // Write this to the ImageJ log IJ.log("Image Name is: "+imp.getTitle() ); // Use IJ.log(); ImagePlus edgeImp = imp.duplicate(); IJ.run(edgeImp, "Find Edges", ""); // Duplicate image // Run Find Edges edgeImp.setTitle(imp.getTitle()+" Edges"); // Rename the new image edgeImp.show(); // Display it 40 Apply a command or Plugin • Correction // Get the current Image ImagePlus imp = IJ.getImage(); // Use IJ.getImage(); // Write this to the ImageJ log IJ.log("Image Name is: "+imp.getTitle() ); // Use IJ.log(); ImagePlus edgeImp = imp.duplicate(); IJ.run(edgeImp, "Find Edges", ""); // Duplicate image // Run Find Edges edgeImp.setTitle(imp.getTitle()+" Edges"); // Rename the new image edgeImp.show(); // Display it 40 Apply a command or Plugin • Correction // Get the current Image ImagePlus imp = IJ.getImage(); // Use IJ.getImage(); // Write this to the ImageJ log IJ.log("Image Name is: "+imp.getTitle() ); // Use IJ.log(); ImagePlus edgeImp = imp.duplicate(); IJ.run(edgeImp, "Find Edges", ""); // Duplicate image // Run Find Edges edgeImp.setTitle(imp.getTitle()+" Edges"); // Rename the new image edgeImp.show(); // Display it 40 Apply a command or Plugin • Correction // Get the current Image ImagePlus imp = IJ.getImage(); // Use IJ.getImage(); // Write this to the ImageJ log IJ.log("Image Name is: "+imp.getTitle() ); // Use IJ.log(); ImagePlus edgeImp = imp.duplicate(); IJ.run(edgeImp, "Find Edges", ""); // Duplicate image // Run Find Edges edgeImp.setTitle(imp.getTitle()+" Edges"); // Rename the new image edgeImp.show(); // Display it 40 Apply a command or Plugin • Correction // Get the current Image ImagePlus imp = IJ.getImage(); // Use IJ.getImage(); // Write this to the ImageJ log IJ.log("Image Name is: "+imp.getTitle() ); // Use IJ.log(); ImagePlus edgeImp = imp.duplicate(); IJ.run(edgeImp, "Find Edges", ""); // Duplicate image // Run Find Edges edgeImp.setTitle(imp.getTitle()+" Edges"); // Rename the new image edgeImp.show(); // Display it 40 The PluginFilter Interface • Slightly more complex. Must operate on an image public class PlugInFilter_Plugin implements PlugInFilter { protected ImagePlus image; @Override public int setup(String arg, ImagePlus imp) { // Is run when the plugin is launched // Your code here // You should look for or ask for parameters here. image = imp; // Must return an int that says what the plugin can do. return DOES_8G | DOES_16 | DOES_32 | DOES_RGB | DOES_STACKS | CONVERT_TO_FLOAT; } @Override public void run(ImageProcessor ip) { // Your code here. } 41 Add a Dialog • When you need the user to provide data, there is the GenericDialog class. GenericDialog gd = new GenericDialog("pixels"); // Declare a new Dialog gd.addNumericField("value", 0.00, 2); // Add a number field gd.showDialog(); if (gd.wasCanceled()) return false; // Display the dialog // Check that the user clicked OK value = gd.getNextNumber(); // Get the number 42 Add a Dialog • When you need the user to provide data, there is the GenericDialog class. GenericDialog gd = new GenericDialog("pixels"); // Declare a new Dialog gd.addNumericField("value", 0.00, 2); // Add a number field gd.showDialog(); if (gd.wasCanceled()) return false; // Display the dialog // Check that the user clicked OK value = gd.getNextNumber(); // Get the number • Useful methods • addNumericField • addString • addChoice • addCheckbox to get a number to get a string to get a dropdown menu to get a checkbox 42 PluginFilter Dialog • Exercise – Code a dialog box that asks the user for a value and runs a median filter on the current image. – Use http://tiny.cc/adip-plugin-filter as a starting point 43 PluginFilter Dialog @Override public int setup(String arg, ImagePlus imp) { this.imp = imp; GenericDialog gd = new GenericDialog("Median Filter");// Declare the dialog gd.addNumericField("Median Filter Size", 2.0, 2); // Add the numeric field gd.showDialog();// Display the dialog // If the user did not click Cancel, continue if (!gd.wasCanceled()) { medianValue = gd.getNextNumber(); // Recover the value the user entered } // Explain the type of images that work with this plugin return DOES_8G | DOES_16 | DOES_32 | DOES_RGB; } 44 PlugInFilter Dialog in a Macro • What happens when we run the Macro Recorder on our plugin? • GenericDialog creates everything for us! 45 ResultsTable • Exercise: Measure the mean intensity of the image and display it in a ResultsTable. • Start from My_First_Plugin.java 46 ResultsTable • Solution tiny.cc/adip-measure-image • Static variables belong to the Class and not the Instance… 47 ResultsTable • Solution tiny.cc/adip-measure-image • Static variables belong to the Class and not the Instance… 47 Flexibility 123
© Copyright 2025