IJ.open() works really slow inside a plugin

I have written a plugin for Imagej with a GUI which has specific tools I need. It also has open method for me to open an image to work on. Even though it works, it opens images really slowly compared to open method inside Imagej’s main window. For example, sometimes I work on images with high resolution which can be over 50 mb. Imagej can open it up almost instantly, but my plugin waits for about 5 to 6 minutes (yes I have waited to see how long would it take to open :laughing: ) which is ridiculously long.
Anyone have an idea why does that happen ? I use the method as itself, so should’nt it be the same to open an image from main window or from my plugin ?
I cannot use macro as I need to create a GUI, so is there any solution for this inside plugin?
My code for open button is as follows:

Opener opener = new Opener();
opener.open();

What kind of GUI do you need to make? Have you considered writing a script using script parameters to automate the GUI generation? Are you targeting ImageJ1 or ImageJ2?

Is it possible that you have “Use SCIFIO” checked in the “Edit - Options - ImageJ2…” dialog? For some file types like .zip it can take minutes, even hours. Unchecking it could solve this problem.

Why “File - Open” is different than new Opener().open() remains to be investigated, but @Wayne could shed light on whether there should be any difference.

Hello, thank you for reply!
I am using Imagej1, I have already made GUI, it only contains some buttons to open tools like versatile wand tool, ROI, plot profile etc.

Hi, thanks for reply!
I have not tried to open a zip yet but my plugin struggles to open file formats like .CR2 or .tif as they can get bigger and bigger in size.
Is there any other way rather than using opener().open() to make it faster maybe ?

First you’d have to determine what is causing the slow down.

If “Use SCIFIO” is unchecked in the “Edit - Options - ImageJ2”, then ImageJ is using its own internal libraries, or if the format is unknown to ImageJ, it delegates to the BioFormats library.

If your image is e.g. a TIFF file, use then ij.io.TiffDecoder directly, see TiffDecoder, and also see Opener at its openImage method, whose code is self-explanatory.

To bypass it all, if your image is uncompressed, you can also open images raw. One high-level way is to use the Raw class, by passing it to a FileInfo.open that you filled in with the details (dimensions, bit type, filepath, etc.).

If your file format is uncompressed, you can also read the image data directly into an array and make the appropriate ImageProcessor from that. E.g. if you know the dimensions and pixel depth, read the image part of from the file with a RandomAccessFile by skipping the length of the header, reading the data into a byte[] of length width * height * pixelDepth, then wrapping the byte[] array in a ByteBuffer, then converting the buffer to that of the pixel type (e.g. a float, therefore a FloatBuffer) and reading the data by filling an e.g. float[] array (if the image is 32-bit gray) from the FloatBuffer.

Here is an example of reading a 32-bit image into a FloatProcessor using the RandomAccessFile approach: https://github.com/acardona/scripts/blob/master/python/imagej/IsoView-GCaMP/lib/io.py#L38

def readFloats(path, dimensions, header=0, byte_order=ByteOrder.LITTLE_ENDIAN):
  """ Read a file as an ArrayImg of FloatType """
  size = reduce(operator.mul, dimensions)
  ra = RandomAccessFile(path, 'r')
  try:
    if header < 0:
      # Interpret from the end: useful for files with variable header lengths
      # such as some types of uncompressed TIFF formats
      header = ra.length() + header
    ra.skipBytes(header)
    bytes = zeros(size * 4, 'b')
    ra.read(bytes)
    floats = zeros(size, 'f')
    ByteBuffer.wrap(bytes).order(byte_order).asFloatBuffer().get(floats)
    return ArrayImgs.floats(floats, dimensions)
  finally:
    ra.close()

There are many ways. But first you should determine why the slow loading is happening.