LOCI Bio-Formats dialog opens when calling IJ.openImage

In a script, I am using IJ.openImage() to open a two-channel 16-bit signed single-slice TIF file that has been encoded with the two’s complement.

The LOCI bio-formats dialog opens, and all that is needed to do is push ‘OK’.

How can one prevent the dialog from opening in the first place?

Opening the file manually using the bio-formats API is possible. Here is one attempt at it, that works, but surely it could be simpler?

from loci.formats import ChannelSeparator
#from java.nio import ByteBuffer, ByteOrder
from fiji.scripting import Weaver
from ij.process import ShortProcessor
from ij import ImagePlus, ImageStack, CompositeImage
from jarray import zeros

# *** EDIT HERE ***
filepath = ...


# An embedded piece of java code to parse the raw bytes into signed 16-bit pixels, decoded with two's complement.
# If the two's complement wasn't needed, there would be no need for the Weaver: ByteBuffer would suffice.
arrays = [None, None]
asShorts = Weaver.inline(
  """
  final byte[] bytes = (byte[])arrays.get(0);
  final short[] shorts = (short[])arrays.get(1);
  
  for (int i=0, k=0; i<shorts.length; i+=1, k+=2) {
    // In little endian and with two's complement
    shorts[i] = (short) (~(bytes[k+1]&0xff | (bytes[k]&0xff << 8)) + 1);
  }

  return null;
  """, {"arrays": arrays})

# A LOCI bio-formats decoder for the TIFF file
reader = ChannelSeparator()
reader.setGroupFiles(False)
reader.setId(filepath)

width = reader.getSizeX()
height = reader.getSizeY()

# Pre-allocated array for reuse in reading each image plane
bytes = zeros(width * height * 2, 'b')

stack = ImageStack(width, height)

# Read each of the two image planes, one for each channel
for i in xrange(reader.getImageCount()):
  reader.openBytes(i, bytes)
  shorts = zeros(width * height, 'h') # 'h' is for short (16-bit)
  # Should work, but doesn't do the two's complement, which is needed because these TIFF files are signed 16-bit.
  #ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts)
  # So instead we do it manually with the Weaver:
  arrays[0] = bytes
  arrays[1] = shorts
  asShorts.call()
  stack.addSlice(ShortProcessor(reader.getSizeX(), reader.getSizeY(), shorts, None))

# Show the stack as an ImageJ composite image
imp = ImagePlus("all", stack)
imp.setDimensions(2, stack.getSize() / 2, 1) # channels, slices and time frames
comp = CompositeImage(imp, CompositeImage.COMPOSITE)
comp.show()

Surely there is a simpler way?

1 Like

@albertcardona,

Fairly recently, I came across Plugins > Bio-Formats > Bio-Formats Plugins Configuration.
The panel that opens let me select “Windowless” on a per-format basis.
Now Bioformats does not open that dialog for me anymore (for NifTi files) - hopefully this will do the trick for you too.

John

2 Likes

As @bogovicj says, you can disable the Bio-Formats dialog on a per-format basis via the Bio-Formats Plugins Configuration dialog. However, be warned! It will then always use the same settings from the last time that dialog appeared. So e.g. if you disable for Zeiss CZI, and then you open a Zeiss LSM and set the settings differently for that type of data, then try opening a CZI again, it will behave with the settings you specified for LSM last time.

The newer and more general “ImageJ2 way” to open images without popping any dialogs is:

# @File file
# @IOService io
# @OUTPUT Object data
data = io.open(file.getAbsolutePath())

This will use SCIFIO as appropriate, which uses Bio-Formats under the hood as appropriate. No dialogs will ever pop up.

If you want to guarantee that the file contains image data, and fail otherwise:

# @File file
# @DatasetIOService datasetIO
# @OUTPUT Dataset imageData
imageData = datasetIO.open(file.getAbsolutePath())

This forces the use of SCIFIO, and gives stronger typing guarantees.

If you want to customize the image loading behavior:

# @File file
# @DatasetIOService datasetIO
# @OUTPUT Dataset imageData

from io.scif.config import SCIFIOConfig
config = SCIFIOConfig()
config.imgOpenerSetComputeMinMax(False)
imageData = datasetIO.open(file.getAbsolutePath(), config)

(API of SCIFIOConfig kind of sucks right now, and is still subject to change in future. Suggestions welcome.)

See above.

If you want to stick to Bio-Formats specifically, you can use the loci.formats.BF utility class. It is much higher level, returning ImagePlus[]. Here is a simple example. You can also customize its behavior; see the Scripting section of the Bio-Formats page, as well as Opening an image using Bio-Formats from the Scripting Toolbox page.

3 Likes

Thanks @ctrueden, this fully answers my question. But it raises another one: where can one read documentation about all the injected magic in the commented out code? Does it have a name, for search?

Yes! They are called script parameters. Click that link for details.

2 Likes