python-javabridge
python-javabridge copied to clipboard
How to decode java object returned by using javabridge?
I am trying to call some methods in python package python-bioformats that uses javabridge to call a java lib called Bioformats.
When I call one of those methods, it returns following.
<Java object at 0x246ef80>
How can I check what this object is and how can I use it in python? Docs in Bioformats says it should be HashTable. If it is, I have no idea how to iterate it.
Hi Malhar - glad you're using bioformats and javabridge. Look at this page for hints on how to do what you want: https://github.com/LeeKamentsky/python-javabridge/blob/master/docs/highlevel.rst
In particular, you probably want to use javabridge.JWrapper. If you use it in something like a Jupyter notebook, you can use code completion to look at the available methods, I think.
The tests might give you a good idea of how to use it: https://github.com/LeeKamentsky/python-javabridge/blob/master/javabridge/tests/test_wrappers.py
Hope this helps. Please close the issue if it does.
Hey @LeeKamentsky . I appreciate your reply. The issue is my script doesn't use javabridge directly but through another package called python-bioformat. So, I am not sure if your comments apply in my case.
They do. python-bioformats uses Javabridge under the hood.
Yeah that is why I am not sure how to apply what you said, to my problem.
Post the code you're using to access bioformats that returns your Java object.
Here is my code.
if __name__ == "__main__":
javabridge.start_vm(class_path=bioformats.JARS)
tif_file_path = "/tmp/xyz.tif"
try:
with get_image_reader('my_image_key', tif_file_path) as reader:
r = reader.rdr
print(f"Metadata: {r.getMetadata()}")
except Exception as e:
print(e)
javabridge.kill_vm()
It prints Metadata: <Java object at 0x26fdf40>.
Now, I don't know how to use this Java object. It has only a single method called addr().
Here is how python-bioformat implements it, in case it helps. https://github.com/CellProfiler/python-bioformats/blob/c03fb0988caf686251707adc4332d0aff9f02941/bioformats/formatreader.py#L122
Try something like this:
from javabridge.wrappers import JWrapper
if __name__ == "__main__":
javabridge.start_vm(class_path=bioformats.JARS)
tif_file_path = "/tmp/xyz.tif"
try:
with get_image_reader('my_image_key', tif_file_path) as reader:
r = reader.rdr
metadata = JWrapper(r.getMetadata())
print(metadata.toString())
print(metadata.getClass().toString())
except Exception as e:
print(e)
javabridge.kill_vm()
For my TIFF file, this printed
{XResolution=1.0, PhotometricInterpretation=BlackIsZero, MetaDataPhot
ometricInterpretation=Monochrome, ImageLength=2048, BitsPerSample=16, Resolutio
nUnit=None, Compression=Deflate (Zlib), SamplesPerPixel=1, NumberOfChannels=1,
Software=tifffile.py, MetaMorph=no, ImageWidth=2048, YResolution=1.0}
class java.util.Hashtable
So it's a hashtable and you can do things to look inside it like metadata.keySet() and such.
It alt least show some meaningful but still unable to iterate the HashTable. I use following code.
m = JWrapper(r.getGlobalMetadata())
keys = m.keySet()
for k in keys.iterator():
print(k)
It throws java.util.Hashtable$Enumerator@74a2a94c is not a Collection and does not support __iter__. I understand this message but then how to iterate it. If I iterate m then it throws following which is same issue but with long message.
{PhotometricInterpretation=BlackIsZero, MetaDataPhotometricInterpretation=Monochrome, <prop id="number-of-planes" type="int" value="1"/>, Comment=<MetaData>
<PlaneInfo>
</PlaneInfo>
<SetInfo>
</SetInfo>
</MetaData>
, NewSubfileType=2, ImageLength=2048, BitsPerSample=16, Compression=Uncompressed, SamplesPerPixel=1, NumberOfChannels=1, Software=MetaSeries, MetaMorph=no, ImageWidth=2048, Orientation=1st row -> top; 1st column -> left, DateTime=20210204 11:17:35.363, <custom-prop id="Z Thickness" type="float" value="3.98"/>} is not a Collection and does not support __iter__
Tried this one.
m = JWrapper(r.getGlobalMetadata())
while m.elements().hasMoreElements():
print(m.elements().nextElement())
It prints BlackIsZero infinitely.
Also, tried following.
while m.keys().hasMoreElements():
print(m.keys().nextElement())
It prints PhotometricInterpretation infinitely.
Got success with following code.
m = JWrapper(r.getMetadata())
entry_set = m.entrySet()
entry_set_iterator = entry_set.iterator()
while entry_set_iterator.hasNext():
entry = entry_set_iterator.next()
print(entry.getKey())
print(entry.getValue())
print("-----------------")