>>> img = WindowManager.getCurrentImage()
>>> def toStack(image):
... stack = ImageStack(image.width, image.height)
... for i in range(10):
... stack.addSlice(image.getTitle(), image.getProcessor().crop())
...
... ImagePlus("stack", stack).show()
...
>>> toStack(img)
>>> from java.awt import FileDialog >>> fd = FileDialog(IJ.getInstance(), "Open", FileDialog.LOAD) >>> fd.show() >>> file_name = fd.getFile() >>> if None != file_name: ... Opener().openImage(fd.getDirectory(), file_name).show() ... >>>
Perhaps it is better to use ImageJ's way of bringing up a file dialog, which may be a JFileChooser if the user ticked the right checkbox in the Edit - Options. It's also shorter:
>>> od = OpenDialog("Choose image file", None)
>>> file_name = od.getFileName()
>>> if None != file_name:
... Opener().openImage(od.getDirectory(), file_name).show()
...
>>>
Note that java methods whose return type is void print 'None'. Also note that doCommand will run in a separate thread.
>>> IJ.run("Select All")
None
>>> IJ.doCommand("Select All")
None
>>> from java.io import File, FilenameFilter
>>> import re
>>> class Filter(FilenameFilter):
... def accept(self, dir, name):
... reg = re.compile("\.tif$")
... m = reg.search(name)
... if m:
... return 1
... else:
... return 0
...
>>>
>>> folder = "/images/art/"
>>> tifs = [Opener().openImage(folder, file.name) for file in File(folder).listFiles(Filter())]
>>> print tifs
[imp[image1.tif 600x900x1], imp[image2.tif 600x900x1], imp[image3.tif 600x900x1]]
In this case, it is used to make the '+' sign add together several copies of the currently active image into a single stack.
Note the usage of imp.title : despite 'title' being private to class ImagePlus, jython can read it automatically from the getTitle() method (this is called 'beans' functionality).
>>> class Stack(ImageStack):
... def __init__(self, title, imp):
... ImageStack.__init__(self, imp.width, imp.height)
... self.title = title
... self.addSlice(imp.title, imp.getProcessor())
...
... def __add__(self, imp):
... if imp.width == self.width and imp.height == self.height:
... self.addSlice(imp.title, imp.getProcessor())
... else:
... print "image", imp.title, "has different dimensions. Ignoring."
... return self
...
... def show(self):
... ImagePlus(self.title, self).show()
...
>>>
>>> img = WindowManager.getCurrentImage()
>>> stack = Stack("stack", img) + img + img + img
>>> stack.show()
Actually, only those of the same size as the first image in the list. Requires the class Stack defined in example 5.
...
>>> w = WindowManager
>>> stack = None
>>> for id in w.getIDList():
... img = w.getImage(id)
... if None == stack: stack = Stack("all", img)
... else: stack += img
...
>>>
>>> stack.show()
>>> from javax.swing import JFrame
>>> from java.awt import Color, Dimension
>>> f = JFrame("Test", size=Dimension(400,400), \
... windowClosing=lambda msg: IJ.showMessage("Closing the window!"), \
... visible=1, background=Color.yellow)
...
>>>
>>> img = WindowManager.getCurrentImage()
>>> ic = img.getWindow().getCanvas()
>>> f.getContentPane().add(ic)
In pure java the above code would have taken lots of code lines. The only truly missing step is a way to check whether any image is open, but since this is a dynamic interpreter, if the 'img' var is null an error will show when trying to get the ImageCanvas 'ic', and thus it can be adjusted on the fly.
The above code could be even shorter, but then it may lose readability.
By java bean is understood the property/ies a class has such as, in JFrame, 'size', with its corresponding get and set methods. In jython any such bean can be specified within the constructor. See jython webpage on java bean properties and events.
For events, jython reads which listeners can be added to a class instance, and then which methods such listeners implement. Then any such method can be specified directly in the constructor such as the 'windowClosing' method of the WindowListener for the JFrame above, without having to generate subclasses or any redundant stuff.
In your jython installation folder, there is a jython compiler that compiles jython code to both .java and .class files. Such .class files can be executed without the jython.jar present in the classpath.
The above means that you can create a jython ImageJ script, then compile it, and give it to people who don't even need to know that jython exists.
To compile a jython file named Add_Noise.py, using something like:
$ cd ImageJ/plugins/Jython/ $ jython-2.1/jythonc -J -classpath ij.jar -w . Add_Noise_1.py
The above creates Add_Noise.java and two .class files. Delete the .class files and adjust the Add_Noise.java to implement ij.plugin.PlugIn and to have a run(String) method that calls the main(String[]) present in Add_Noise.java. Then compile it as any other ImageJ plugin.
Voilà, you have now a pure java ImageJ plugin with can be executed without the jython jar present in the classpath.