Python Script for reading CZI images

Hi all, I am playing around for a while now with all the nice options on how to read CZI images in Fiji using python scripting. What I got is not perfect, but works quite well in most cases.

So feel free to use it and even improve it or share feedback.

You find the script here:



Hi there, thanks for the contribution. Sorry, I haven’t had the chance to try your script yet, but I was wondering if you could add a comment on how your script differs and/or improves on Fiji’s capabilities with .czi files. I have been using Fiji to read and analyze .czi files for some time and find it rather satisfactory already, but perhaps your script provides features I don’t (yet) know I need?


for most things just using the very powerful BioFormats plugin suffienct and will do the job thanks to work of the BioFormats guys and the the good communication with our DevTeam at ZEISS.

The reason why I created this script has several reasons.

  • CZI image do have a pyramidal structure with different resolution levels. While it is possible to open them using BioFormats by choosing the correct image series, this is cumbersome to automate
  • the script allows you to directly specify the desired pyramid level to read
  • additional is sets the scaling for the pyramid level correctly, which did not work using the BioFormats plugin only (or I do not know how … :-))
  • the need to automate opening CZI in headless mode required to write some kind of script and not using method, because and BioFormats do not work in headless mode
  • see this post: Strange Issue with using BioFormats from python script in headless mode only
  • this headless things is really crucial to run our Docker containers on APEER (, where we use Fiji + BoFormats quite often to create image processing modules like this one: Measure 3D Objects

So basically it offers a bit more flexibility and allows automating reading CZIs via BioFormats by exposing all the options of BioFormats (and some additional minor things) and wrapping them inside a python script by using the cool scripting parameters, which makes life in headless mode and inside Docker containers easy.

Feel free to test it and let me know if it works or how it could be improved, since I am pretty sure my script still has some hidden “glitches” …

Sebi (from ZEISS)


Hi, I’ve found this thread after struggling for a while to figure out how to open CZI file via fiji in headless mode. It seems that - just like you described in your post - I can’t simply use open(“file.czi”) in a myMacro.ijm to open it (I get Java Error: Bad Operand).

My goal is to automate the process of:

  1. read czi file
  2. Stack to RGB (in Fiji, the macro command is: run(“Stack to RGB”)
  3. save as Tiff (in Fiji: saveAs(“Tiff”, outputPath/file))

Would your fjij python toolkit library for reading czi help to automate the pipeline above? I am not sure how to use your python scripts with fiji, but if the toolkit would be able to be used for the described task, I’d greatly appreciate if you could suggest a direction. Thanks!

Hi @KSL,

to read a CZI you should either use the BioFormats plugin from the macro or for more flexibility have a look into this script (requires

Can confirm, the bioformats importer doesn’t work in Fiji in headless mode, so you will need something else (that script should certainly work, but I haven’t tried personally); to do the rest of your macro in python in Fiji, you basically just need to add a from ij import IJ to the import section and put IJ. in front of each of your commands).

If you aren’t wedded to a Fiji-only solution, that would be a super simple pipeline in CellProfiler- configure the input modules to read your CZI files, one “GrayToColor” module to make your RGB image, and one “SaveImages” module to save it out. But obviously without knowing the rest of your workflow it’s not clear if that would be simpler here.

Hi @bcimini and @KSL,

for me the BioFormats Importer does work quite well in headless mode or do I misunderstand the problem?

Or do you mean how to read CZI in "normal python? Here I always use AICSImageIO or aicspylibczi, which both work very nicely.

@sebi06 @bcimini Thanks for the reply.

@sebi06 For me BioFormats importer does not work in headless mode it seems.

For example, I wrote a simple ijm macro to just open a file:

#@String file



#@String file

run("Bio-Formats Importer", "open=[" + file + "] color_mode=Default view=Hyperstack stack_order=XYCZT");

When I run either macro

/Applications/ --ij2 --headless --console --run test.ijm ‘file=“test.czi”’

I get the same following error:

java.lang.VerifyError: Bad type on operand stack
Exception Details:
    loci/plugins/in/MainDialog.rebuildDialog(Lij/gui/GenericDialog;)V @1926: invokestatic
    Type 'ij/gui/GenericDialog' (current frame, stack[0]) is not assignable to 'java/awt/Container'
  Current Frame:
    bci: @1926
    flags: { }
    locals: { 'loci/plugins/in/MainDialog', 'ij/gui/GenericDialog', 'java/util/List', 'java/util/List', 'java/util/List', 'java/awt/Label', 'java/awt/Label', 'java/awt/Label', 'java/awt/Label', '[Ljava/awt/Component;', 'java/lang/String', 'java/lang/String', 'com/jgoodies/forms/builder/PanelBuilder', 'com/jgoodies/forms/layout/CellConstraints', integer }
    stack: { 'ij/gui/GenericDialog' }
    0x0000000: 014d 014e 013a 0401 3a05 013a 0601 3a07
    0x0000010: 013a 082b b600 533a 0919 09c6 0266 bb00
    0x0000020: 5459 b700 554d bb00 5459 b700 554e bb00
    0x0000030: 5459 b700 553a 0403 360a 150a 1909 bea2
    0x0000040: 008a 1909 150a 32c1 0056 9900 2b19 0915
    0x0000050: 0a32 c000 563a 0b19 0b2a b600 5719 0b2a
    0x0000060: b600 5819 0b2a b600 592c 190b b900 5a02
    0x0000070: 0057 a700 5119 0915 0a32 c100 5b99 002b
    0x0000080: 1909 150a 32c0 005b 3a0b 190b 2ab6 005c
    0x0000090: 190b 2ab6 005d 190b 2ab6 005e 2d19 0bb9
    0x00000a0: 005a 0200 57a7 001e 1909 150a 32c1 005f
    0x00000b0: 9900 1319 0419 0915 0a32 c000 5fb9 005a
    0x00000c0: 0200 5784 0a01 a7ff 7403 360a 0336 0b03
    0x00000d0: 360c 2a2c 150a 840a 01b9 0060 0200 c000
    0x00000e0: 56b5 0061 2a2d 150b 840b 01b9 0060 0200
    0x00000f0: c000 5bb5 0062 1904 150c 840c 01b9 0060
    0x0000100: 0200 c000 5f3a 052a 2c15 0a84 0a01 b900
    0x0000110: 6002 00c0 0056 b500 632a 2c15 0a84 0a01
    0x0000120: b900 6002 00c0 0056 b500 642a 2c15 0a84
    0x0000130: 0a01 b900 6002 00c0 0056 b500 652a 2c15
    0x0000140: 0a84 0a01 b900 6002 00c0 0056 b500 662a
    0x0000150: 2c15 0a84 0a01 b900 6002 00c0 0056 b500
    0x0000160: 6784 0a01 2a2c 150a 840a 01b9 0060 0200
    0x0000170: c000 56b5 0068 2a2c 150a 840a 01b9 0060
    0x0000180: 0200 c000 56b5 0069 2a2c 150a 840a 01b9
    0x0000190: 0060 0200 c000 56b5 006a 2a2d 150b 840b
    0x00001a0: 01b9 0060 0200 c000 5bb5 006b 1904 150c
    0x00001b0: 840c 01b9 0060 0200 c000 5f3a 062a 2c15
    0x00001c0: 0a84 0a01 b900 6002 00c0 0056 b500 6c2a
    0x00001d0: 2c15 0a84 0a01 b900 6002 00c0 0056 b500
    0x00001e0: 6d2a 2c15 0a84 0a01 b900 6002 00c0 0056
    0x00001f0: b500 6e2a 2c15 0a84 0a01 b900 6002 00c0
    0x0000200: 0056 b500 6f2a 2d15 0b84 0b01 b900 6002
    0x0000210: 00c0 005b b500 4a19 0415 0c84 0c01 b900
    0x0000220: 6002 00c0 005f 3a07 2a2d 150b 840b 01b9
    0x0000230: 0060 0200 c000 5bb5 0070 1904 150c 840c
    0x0000240: 01b9 0060 0200 c000 5f3a 082a 2c15 0a84
    0x0000250: 0a01 b900 6002 00c0 0056 b500 712a 2c15
    0x0000260: 0a84 0a01 b900 6002 00c0 0056 b500 722a
    0x0000270: 2c15 0a84 0a01 b900 6002 00c0 0056 b500
    0x0000280: 732a 01b7 0049 2abb 0074 59b7 0075 b500
    0x0000290: 3d2a b400 3d2a b400 612a b400 20b6 0076
    0x00002a0: b900 7703 0057 2ab4 003d 2ab4 0062 2ab4
    0x00002b0: 0020 b600 78b9 0077 0300 572a b400 3d19
    0x00002c0: 052a b400 20b6 0078 b900 7703 0057 2ab4
    0x00002d0: 003d 2ab4 0063 2ab4 0020 b600 79b9 0077
    0x00002e0: 0300 572a b400 3d2a b400 642a b400 20b6
    0x00002f0: 007a b900 7703 0057 2ab4 003d 2ab4 0065
    0x0000300: 2ab4 0020 b600 7bb9 0077 0300 572a b400
    0x0000310: 3d2a b400 662a b400 20b6 007c b900 7703
    0x0000320: 0057 2ab4 003d 2ab4 0067 2ab4 0020 b600
    0x0000330: 7db9 0077 0300 572a b400 3d2a b400 682a
    0x0000340: b400 20b6 007e b900 7703 0057 2ab4 003d
    0x0000350: 2ab4 0069 2ab4 0020 b600 7fb9 0077 0300
    0x0000360: 572a b400 3d2a b400 6a2a b400 20b6 0080
    0x0000370: b900 7703 0057 2ab4 003d 2ab4 006b 2ab4
    0x0000380: 0020 b600 81b9 0077 0300 572a b400 3d19
    0x0000390: 062a b400 20b6 0081 b900 7703 0057 2ab4
    0x00003a0: 003d 2ab4 006c 2ab4 0020 b600 82b9 0077
    0x00003b0: 0300 572a b400 3d2a b400 6d2a b400 20b6
    0x00003c0: 0083 b900 7703 0057 2ab4 003d 2ab4 006e
    0x00003d0: 2ab4 0020 b600 84b9 0077 0300 572a b400
    0x00003e0: 3d2a b400 6f2a b400 20b6 0085 b900 7703
    0x00003f0: 0057 2ab4 003d 2ab4 004a 2ab4 0020 b600
    0x0000400: 86b9 0077 0300 572a b400 3d19 072a b400
    0x0000410: 20b6 0086 b900 7703 0057 2ab4 003d 2ab4
    0x0000420: 0070 2ab4 0020 b600 87b9 0077 0300 572a
    0x0000430: b400 3d19 082a b400 20b6 0087 b900 7703
    0x0000440: 0057 2ab4 003d 2ab4 0071 2ab4 0020 b600
    0x0000450: 88b9 0077 0300 572a b400 3d2a b400 722a
    0x0000460: b400 20b6 0089 b900 7703 0057 2ab4 003d
    0x0000470: 2ab4 0073 2ab4 0020 b600 8ab9 0077 0300
    0x0000480: 5712 8b3a 0a12 8c3a 0bbb 008d 59bb 008e
    0x0000490: 5919 0a19 0bb7 008f b700 903a 0cbb 0091
    0x00004a0: 59b7 0092 3a0d 0436 0e19 0c12 9319 0d04
    0x00004b0: 150e 06b6 0094 b600 9557 840e 0219 0c19
    0x00004c0: 0719 0d04 150e b600 96b6 0097 5719 0c2a
    0x00004d0: b400 4a19 0d06 150e b600 96b6 0097 5784
    0x00004e0: 0e02 190c 1908 190d 0415 0eb6 0096 b600
    0x00004f0: 9757 190c 2ab4 0070 190d 0615 0eb6 0096
    0x0000500: b600 9757 840e 0619 0c12 9819 0d04 150e
    0x0000510: 06b6 0094 b600 9557 840e 0219 0c2a b400
    0x0000520: 652a 190d 0415 0e06 b700 99b6 0097 5784
    0x0000530: 0e02 190c 2ab4 0066 2a19 0d04 150e 06b7
    0x0000540: 0099 b600 9757 840e 0219 0c2a b400 712a
    0x0000550: 190d 0415 0e06 b700 99b6 0097 5784 0e02
    0x0000560: 190c 2ab4 0067 2a19 0d04 150e 06b7 0099
    0x0000570: b600 9757 840e 0219 0c2a b400 632a 190d
    0x0000580: 0415 0e06 b700 99b6 0097 5784 0e02 190c
    0x0000590: 2ab4 0073 2a19 0d04 150e 06b7 0099 b600
    0x00005a0: 9757 840e 0219 0c12 9a19 0d04 150e 06b6
    0x00005b0: 0094 b600 9557 840e 0219 0c19 0519 0d04
    0x00005c0: 150e b600 96b6 0097 5719 0c2a b400 6219
    0x00005d0: 0d06 150e b600 96b6 0097 5784 0e02 190c
    0x00005e0: 2ab4 0061 2a19 0d04 150e 06b7 0099 b600
    0x00005f0: 9757 840e 0204 360e 190c 129b 190d 0815
    0x0000600: 0e06 b600 94b6 0095 5784 0e02 190c 2ab4
    0x0000610: 0068 2a19 0d08 150e 06b7 0099 b600 9757
    0x0000620: 840e 0219 0c2a b400 692a 190d 0815 0e06
    0x0000630: b700 99b6 0097 5784 0e02 190c 2ab4 006a
    0x0000640: 2a19 0d08 150e 06b7 0099 b600 9757 840e
    0x0000650: 0219 0c19 0619 0d08 150e b600 96b6 0097
    0x0000660: 5719 0c2a b400 6b19 0d10 0715 0eb6 0096
    0x0000670: b600 9757 840e 0219 0c12 9c19 0d08 150e
    0x0000680: 06b6 0094 b600 9557 840e 0219 0c2a b400
    0x0000690: 722a 190d 0815 0e06 b700 99b6 0097 5784
    0x00006a0: 0e02 190c 2ab4 006c 2a19 0d08 150e 06b7
    0x00006b0: 0099 b600 9757 840e 0219 0c2a b400 642a
    0x00006c0: 190d 0815 0e06 b700 99b6 0097 5784 0e04
    0x00006d0: 190c 129d 190d 0815 0e06 b600 94b6 0095
    0x00006e0: 5784 0e02 190c 2ab4 006f 2a19 0d08 150e
    0x00006f0: 06b7 0099 b600 9757 840e 0219 0c2a b400
    0x0000700: 6d2a 190d 0815 0e06 b700 99b6 0097 5784
    0x0000710: 0e02 190c 2ab4 006e 2a19 0d08 150e 06b7
    0x0000720: 0099 b600 9757 190c 129e 190d 1009 04b6
    0x0000730: 0096 b600 9557 2abb 009f 59b7 00a0 b500
    0x0000740: 402a b400 4012 a1b6 00a2 2ab4 0040 03b6
    0x0000750: 00a3 2ab4 0040 12a5 b600 4619 0cbb 00a6
    0x0000760: 592a b400 40b7 00a7 190d 1009 0604 150e
    0x0000770: b600 a8b6 0097 572b b600 a92b 190c b600
    0x0000780: aab6 00ab 572b b800 ac2b b200 adb6 00ae
    0x0000790: b1
  Stackmap Table:

	at ij.IJ.runUserPlugIn(
	at ij.IJ.runPlugIn(
	at ij.Executer.runCommand(
	at ij.macro.Functions.doRun(
	at ij.macro.Functions.doFunction(
	at ij.macro.Interpreter.doStatement(
	at ij.macro.Interpreter.doStatements(
	at ij.plugin.Macro_Runner.runMacro(
	at ij.IJ.runMacro(
	at ij.IJ.runMacro(
	at net.imagej.legacy.IJ1Helper$
	at net.imagej.legacy.IJ1Helper$
	at net.imagej.legacy.IJ1Helper.runMacroFriendly(
	at net.imagej.legacy.IJ1Helper.runMacro(
	at net.imagej.legacy.plugin.IJ1MacroEngine.eval(
	at org.scijava.thread.DefaultThreadService.lambda$wrap$2(
	at java.util.concurrent.ThreadPoolExecutor.runWorker(
	at java.util.concurrent.ThreadPoolExecutor$

I’ve tried searching google for similar errors related to opening czi in ImageJ via headless mode, but have not been able to find a solution yet.

FYI, I am working with a czi file that is a histology slice of a brain region. I tried opening a different czi file (like cell microscopy images), but I got the same error, so I do not think the error is due to different czi files.

Did you not encounter a similar error when trying to run a macro in headless mode to open a czi file?

I tried this on my local (mac) machine and remote computing cluster (centOS), but both had the same error so I thought czi cannot be read in headlessmode via ImageJ.


hmmm, so have no clue why this does not work for me. Can you share a CZI file, which does not work for you?

Sure thing! Here’s the test.czi file I could not open in headless mode (in GUI Fiji I can open just fine)

@sebi06 , I’ve run into that before, and I’m not the only one, curious to know if you have any counter-example scripts where you’ve tried to invoke the Bioformats importer in headless ImageJ and HAVE had it work! That might help with the tracing and fixing of the issue.

Hi @bcimini ,

i created a little test python script.

# @File(label = "Image File", persist=True) FILENAME
# @UIService uiService
# @LogService log

import os
import sys
from loci.formats import MetadataTools
from loci.formats import ImageReader
from loci.plugins. in import ImporterOptions
from loci.plugins.util import LociPrefs
from loci.plugins import BF
from loci.formats. in import ZeissCZIReader
from loci.formats. in import DynamicMetadataOptions
from ij import IJ, ImagePlus, ImageStack, Prefs
from ij.measure import Calibration
from org.scijava.log import LogLevel

def setCZIReaderOptions(imagefile, czi_options, setflatres=True):

        czireader = ZeissCZIReader()

        return czireader

def setReaderOptions(imagefile, stitchtiles=False,

        czi_options = DynamicMetadataOptions()
        czi_options.setBoolean("zeissczi.autostitch", stitchtiles)
        czi_options.setBoolean("zeissczi.attachments", attach)

        # set the option for the CZIReader
        czireader = setCZIReaderOptions(imagefile, czi_options, setflatres=setflatres)

        # Set the preferences in the ImageJ plugin
        # Note although these preferences are applied, they are not refreshed in the UI
        Prefs.set("bioformats.zeissczi.allow.autostitch", str(stitchtiles).lower())
        Prefs.set("bioformats.zeissczi.include.attachments", str(attach).lower())

        # set the option for the BioFormats import
        reader_options = ImporterOptions()

        return reader_options, czireader

# get the FILENAME as string
imagefile = FILENAME.toString()
pylevel = 0

# define the reader options
reader_options, czireader = setReaderOptions(imagefile, stitchtiles=True,

# open the ImgPlus using BioFormats
imps = BF.openImagePlus(reader_options)

# get the series
imp = imps[pylevel]

# close czireader

# get the stack and some info
imgstack = imp.getImageStack()
slices = imgstack.getSize()
width = imgstack.getWidth()
height = imgstack.getHeight()

log.log(LogLevel.INFO, '---------------------------------------------')
log.log(LogLevel.INFO, 'Filename : ' + imagefile)
log.log(LogLevel.INFO, 'Slices   : ' + str(slices))
log.log(LogLevel.INFO, 'Width    : ' + str(width))
log.log(LogLevel.INFO, 'Height   : ' + str(height))
log.log(LogLevel.INFO, 'Done.')

# exit

# to run it use with your respective (!) paths (on WIN10, Fiji is up-to-date):
# ImageJ-win64.exe --ij2 --headless --console --run "C:\Fiji\scripts\" "FILENAME='C:\Testdata_Zeiss\CellDivision_T=3_Z=5_CH=2_X=240_X=170.czi'"

# or if the script should really exit (this trick I was told by Curtis Rueden a long time ago ...) you should 
# us the complete commandline, which one can get using: ImageJ-win64.exe --dry-run --ij2 --headless --console
# java -Dpython.cachedir.skip=true -Dplugins.dir=C:\\Fiji -Xmx24446m -Djava.awt.headless=true -Dapple.awt.UIElement=true -Xincgc -XX:PermSize=128m -Djava.class.path=C:\\Fiji/jars/imagej-launcher-5.0.3.jar -Dimagej.dir=C:\\Fiji -Dij.dir=C:\\Users\\m1srh\\DOCUME~1\\Fiji -Dfiji.dir=C:\\Fiji -Dfiji.defaultLibPath=bin/server/jvm.dll -Dfiji.executable=C:\\Fiji\\ImageJ-win64.exe -Dij.executable=C:\\Fiji\\ImageJ-win64.exe -Djava.library.path=C:\\Fiji/lib/win64;C:\\Fiji/mm/win64 -Dscijava.context.strict=false net.imagej.launcher.ClassLauncher -ijjarpath jars -ijjarpath plugins net.imagej.Main --run "C:\Fiji\scripts\" "FILENAME='C:\Testdata_Zeiss\CellDivision_T=3_Z=5_CH=2_X=240_X=170.czi'"

If you run this one from the commandline I see the following output:

(PrismaLearn) C:\Fiji>Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=128m; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: Using incremental CMS is deprecated and will likely be removed in a future release
[WARNING] Not overwriting extension 'py':
        proposed = net.haesleinhuepf.clijx.te_oki.TeOkiLanguage [file:/C:/Fiji/plugins/clijx-assistant_-
        existing = org.scijava.plugins.scripting.jython.JythonScriptLanguage [file:/C:/Fiji/jars/scripting-jython-1.0.0.jar
[WARNING] Not overwriting extension 'ijm':
        proposed = net.clesperanto.macro.interpreter.ClEsperantoMacroLanguage [file:/C:/Fiji/plugins/clijx-assistant_-
        existing = net.imagej.legacy.plugin.IJ1MacroLanguage [file:/C:/Fiji/jars/imagej-legacy-0.37.4.jar
[INFO] Overriding Ice ; identifier: script:LUTs/_CMOcean/Ice_.ijm; jar: file:/C:/Fiji/jars/scijava-common-2.83.3.jar
[INFO] Overriding BIOP VSI Reader; identifier: script:ActionBar/Biop Bars/BIOP_VSI_Reader.ijm; jar: file:/C:/Fiji/jars/scijava-common-2.83.3.jar
[INFO] Overriding BIOP VSI Reader; identifier: script:ActionBar/Shared Bars/BIOP_VSI_Reader.ijm; jar: file:/C:/Fiji/jars/scijava-common-2.83.3.jar
[INFO] Overriding Common Tools; identifier: script:ActionBar/Shared Bars/Common_Tools.ijm; jar: file:/C:/Fiji/jars/scijava-common-2.83.3.jar
[INFO] Overriding JaCoP Tools; identifier: script:ActionBar/Shared Bars/JaCoP_Tools.ijm; jar: file:/C:/Fiji/jars/scijava-common-2.83.3.jar
[INFO] Overriding BIOP Run Macro...; identifier: command:ch.epfl.biop.macrorunner.B_Run_Macro; jar: file:/C:/Fiji/plugins/BIOP/B_Run_Macro-1.0.0-SNAPSHOT.jar
[INFO] Overriding Get Spine From Circle Rois; identifier: command:Cirlces_Based_Spine; jar: file:/C:/Fiji/plugins/Max_Inscribed_Circles-1.1.0.jar
[INFO] Overriding Distribution Plotter; identifier: script:Distribution_Plotter.ijm; jar: file:/C:/Fiji/jars/scijava-common-2.83.3.jar
[INFO] Overriding Visualise vector field (experimental); identifier: command:net.haesleinhuepf.clijx.piv.visualisation.VisualiseVectorFieldsPlugin; jar: file:/C:/Fiji/plugins/clijx_-
[INFO] Overriding ROI Color Coder; identifier: script:ROI_Color_Coder.ijm; jar: file:/C:/Fiji/jars/scijava-common-2.83.3.jar
[INFO] ---------------------------------------------
[INFO] Filename : C:\Testdata_Zeiss\CellDivision_T=3_Z=5_CH=2_X=240_X=170.czi
[INFO] Slices   : 30
[INFO] Width    : 240
[INFO] Height   : 170
[INFO] Done.

I hope it helps.

Ok! So it seems like the underlying LIBRARIES work fine in headless mode, just not the ImageJ command “Run Bioformats Headless Importer” (or Exporter, based on your 2016 post in the linked thread from my last post).

@ctrueden or @hinerm or whomever, does it make sense to clarify that in the ImageJ documentation or anywhere else?

Hi @bcimini ,

just to add this, the BioFormats Exporter also works headless for me (despite writing OME-TIFF is reather slow) by using code along those lines:

paramstring = "outfile=[" + savepath + "] windowless=true compression=Uncompressed saveROI=false"
            plugin = LociExporter()
            plugin.arg = paramstring
            exporter = Exporter(plugin, imp)