[R] Rjava, RImageJ, and/or S4 question.

Romain Francois romain.francois at dbmail.com
Wed Oct 28 09:13:27 CET 2009


On 10/28/2009 12:21 AM, Robert Baer wrote:
> I am out of my league with this question.   The following code starts the java imaging program ImageJ from within R, and displays an image (assuming ImageJ is installed on your computer).

It does not assume ImageJ is installed, a version of the imagej jar file 
is shipped with the package.

> library(RImageJ)
> img<-  IJ$openImage( file.choose() )   #pick an available .tif file
> img$show()    #  make the image object visible
> # An image is now displayed

str is not particularly useful in that case. jobj is an external pointer 
to the java object and jclass is the class name of the object, so IJ is 
a pointer to an instance of the ij.IJ class.

> # find out about the objects involved
>> str(IJ)
> Formal class 'jobjRef' [package "rJava"] with 2 slots
>    ..@ jobj  :<externalptr>
>    ..@ jclass: chr "ij/IJ"
>> str(img)
> Formal class 'jobjRef' [package "rJava"] with 2 slots
>    ..@ jobj  :<externalptr>
>    ..@ jclass: chr "java/lang/Object"
> # now use an IJ java method to find out existing screen size
> IJ$getScreenSize()
> [1] "Java-Object{java.awt.Dimension[width=1680,height=1050]}"

What you get here is an object of class java.awt.Dimension, for which 
the standard java has documentation.


You can access the information you want by one of these options:

# access the fields width and height of the Dimension object
 > size <- IJ$getScreenSize()
 > size$height
[1] 1050
 > size$width
[1] 1680

# call methods of the java object
 > size$getHeight()
[1] 1050
 > size$getWidth()
[1] 1680

IJ is an instance of the ij.IJ class which is a class of ImageJ, you'll 
find documentation about it here:

Now if you use a recent version of rJava, you can get completion on java 
objects, so for example :

 > size$<TAB>
size$clone()      size$getClass()   size$getSize()    size$hashCode() 
size$notify()     size$setSize(     size$wait(        size$width
size$equals(      size$getHeight()  size$getWidth()   size$height 
size$notifyAll()  size$toString()   size$wait()

You can also query methods and fields of the object this way :

 > .jmethods( size )
  [1] "public int java.awt.Dimension.hashCode()"
  [2] "public boolean java.awt.Dimension.equals(java.lang.Object)"
  [3] "public java.lang.String java.awt.Dimension.toString()"
  [4] "public java.awt.Dimension java.awt.Dimension.getSize()"
  [5] "public void java.awt.Dimension.setSize(double,double)"
  [6] "public void java.awt.Dimension.setSize(java.awt.Dimension)"
  [7] "public void java.awt.Dimension.setSize(int,int)"
  [8] "public double java.awt.Dimension.getHeight()"
  [9] "public double java.awt.Dimension.getWidth()"
[10] "public java.lang.Object java.awt.geom.Dimension2D.clone()"
[11] "public void 
[12] "public final native void java.lang.Object.wait(long) throws 
[13] "public final void java.lang.Object.wait(long,int) throws 
[14] "public final void java.lang.Object.wait() throws 
[15] "public final native java.lang.Class java.lang.Object.getClass()"
[16] "public final native void java.lang.Object.notify()"
[17] "public final native void java.lang.Object.notifyAll()"
 > .jfields( size )
[1] "public int java.awt.Dimension.width"
[2] "public int java.awt.Dimension.height"

>> str(IJ$getScreenSize())
> Formal class 'jobjRef' [package "rJava"] with 2 slots
>    ..@ jobj  :<externalptr>
>    ..@ jclass: chr "java/lang/Object"
> I am gathering that the RJava library (which is required by the RImageJ library) is using 'slots' which are related to S4????

You don't really need to know about that, just consider that these are 
java objects on which you call methods.

> My question is whether there is any way to extract the width and height information from the IJ$getScreenSize() command which has the vague appearance of being a string vector

size is a java object

 > class( size )
[1] "jobjRef"
[1] "rJava"
 > typeof( size )
[1] "S4"

you can get the java class of the object this way:

 > .jclass( size )
[1] "java.awt.Dimension"

 > size$getClass()$getName()

> or list but is obviously something far more complex like a java str object?

> Question 2.  Is there recommended reading on how one coerces objects back and forth in this type of situation.  For example the ImageJ documentation for the IJ class shows the following for the makeOval method:
> static void makeOval(int x, int y, int width, int height)
> Creates an elliptical selection.
> Here is what happens in R:
>> IJ$makeOval(694, 265, 274, 129);
> Error in .jrcall(x, name, ...) :
>    Cannot find Java method `makeOval' matching the supplied parameters.

You need to either use as.integer to coerce numbers to integers, or use 
the L notation:

 > IJ$makeOval( as.integer(694), as.integer(265), as.integer(274), 
as.integer(129) )
 > IJ$makeOval(694L, 265L, 274L, 129L)

This is because:

 > typeof( 694 )
[1] "double"
 > typeof( 694L )
[1] "integer"


> Can anyone point me in the direction of much-needed self-education :-)
> Thanks for any insight.
> Rob

Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
|- http://tr.im/BcPw : celebrating R commit #50000
|- http://tr.im/ztCu : RGG #158:161: examples of package IDPmisc
`- http://tr.im/yw8E : New R package : sos

More information about the R-help mailing list