{"id":18964009,"url":"https://github.com/saalfeldlab/n5-ij","last_synced_at":"2026-01-18T13:54:09.844Z","repository":{"id":37894534,"uuid":"123156073","full_name":"saalfeldlab/n5-ij","owner":"saalfeldlab","description":"ImageJ convenience layer for N5","archived":false,"fork":false,"pushed_at":"2025-11-13T19:06:05.000Z","size":2909,"stargazers_count":18,"open_issues_count":28,"forks_count":12,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-11-13T20:28:10.444Z","etag":null,"topics":["fiji","fiji-plugin","hdf5","n5","ome-zarr-converter","zarr"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/saalfeldlab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-02-27T16:23:57.000Z","updated_at":"2025-11-13T08:40:47.000Z","dependencies_parsed_at":"2023-10-21T00:36:24.991Z","dependency_job_id":"3d242b9a-32ba-4997-8860-a24b165230a6","html_url":"https://github.com/saalfeldlab/n5-ij","commit_stats":{"total_commits":398,"total_committers":9,"mean_commits":44.22222222222222,"dds":"0.18341708542713564","last_synced_commit":"bcee066848e836f16945fb0633379b5a77a48db3"},"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/saalfeldlab/n5-ij","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saalfeldlab%2Fn5-ij","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saalfeldlab%2Fn5-ij/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saalfeldlab%2Fn5-ij/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saalfeldlab%2Fn5-ij/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saalfeldlab","download_url":"https://codeload.github.com/saalfeldlab/n5-ij/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saalfeldlab%2Fn5-ij/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28537353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T13:04:05.990Z","status":"ssl_error","status_checked_at":"2026-01-18T13:01:44.092Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fiji","fiji-plugin","hdf5","n5","ome-zarr-converter","zarr"],"created_at":"2024-11-08T14:22:37.885Z","updated_at":"2026-01-18T13:54:09.820Z","avatar_url":"https://github.com/saalfeldlab.png","language":"Java","funding_links":[],"categories":["Fiji Plugins"],"sub_categories":[],"readme":"# n5-ij [![Build Status](https://github.com/saalfeldlab/n5-ij/actions/workflows/build-main.yml/badge.svg)](https://github.com/saalfeldlab/n5-ij/actions/workflows/build-main.yml)\n\nA Fiji plugin for loading and saving image data to N5 containers. Supports [HDF5](https://www.hdfgroup.org/solutions/hdf5/), [Zarr](https://zarr.readthedocs.io/en/stable/#), [Amazon S3](https://aws.amazon.com/s3/), and [Google cloud storage](https://cloud.google.com/storage).\n\n## Open HDF5/N5/Zarr/OME-NGFF\n\nOpen HDF5/N5/Zarr/OME-NGFF datasets from Fiji with `File \u003e Import \u003e HDF5/N5/Zarr/OME-NGFF ... `. \n\nQuickly open a dataset by pasting the full path to the dataset and press `OK`.\nFor example, try `gs://example_multi-n5_bucket/mitosis.n5/raw` to open the sample mitosis image from Google\ncloud storage.\n\nClick the `Browse` button to select a folder on your filesystem.\n\n\u003cimg src=https://raw.githubusercontent.com/saalfeldlab/n5-ij/master/doc/OpenN5DialogWithBrowse.png width=\"600\"\u003e\n\nThe detected datasets will be displayed in the dialog. Select (highlight) the datasets you would like to open\nand press `OK`. In the example below, we will open the datasets `/blobs`, and `/t1-head/c0/s0`.\n\n\u003cimg src=https://raw.githubusercontent.com/saalfeldlab/n5-ij/master/doc/OpenN5DialogWithTree.png width=\"600\"\u003e\n\n### Virtual \n\nCheck the `Open as virtual` box to open the dataset as a [virtual stack in ImageJ](https://imagej.nih.gov/ij/docs/guide/146-8.html#toc-Section-8). \nThis enable the opening and viewing of image data that do not fit in RAM. Image slices are loaded on-the-fly, so\nnavigation will be slow when parts of the images are loaded.\n\n### Cropping \n\nSubsets of datasets can be opened by checking the `Crop` box in the dialog, then pressing `OK`.\nA separate dialog will appear for each selected dataset as shown below.\n\n\u003cimg src=https://raw.githubusercontent.com/saalfeldlab/n5-ij/master/doc/OpenN5DialogWithCrop.png width=\"700\"\u003e\n\nGive the min and max values for the field-of-view to open **in pixel / voxel units** a particular\nsubset. The opened interval includes both min and max values, so the image will be of size `max - min + 1` along\neach dimension.  In the example shown above, the resulting image will be of size `101 x 111 x 2 x 51`.\n\n## Export HDF5/N5/Zarr/OME-NGFF\n\nSave full images opened in Fiji as HDF5/N5/Zarr/OME-NGFF datasets with `File \u003e Save As \u003e Export HDF5/N5/Zarr/OME-NGFF ...`, and patch images into an existing dataset using `File \u003e Save As \u003e Export HDF5/N5/Zarr/OME-NGFF (patch)`.  The patch export exports the current image into an existing dataset with a given offset.  This offset and the size of the image do not need to align with the block raster of the dataset.\n\n\u003cimg src=https://raw.githubusercontent.com/saalfeldlab/n5-ij/master/doc/SaveN5Dialog.png width=\"280\"\u003e\n\nParameters\n* `Root url` - the root location of the n5 (see also [Container types](#container-types))\n* `Dataset` - the name of the dataset.\n* `Format` - the storage format to use: one of `Auto`, `Zarr`, `N5`, or `HDF5`\n    * `Auto` : try to infer the storage format from the url (see below)\n* `Chunk size` - chunk/block size as comma-separated list.  \n  * ImageJ's axis order is X,Y,C,Z,T. The chunk size must be specified in this order. You must skip any axis whose size is `1`, e.g. a 2D time-series without channels may have a chunk size of `1024,1024,1` (X,Y,T).\n  * You may provide fewer values than the data dimension. In that case, the list will be expanded to necessary size with the last value, for example `64`, will expand to `64,64,64` for 3D data.\n* `Create Pyramid` - If checked, a multiscale pyramid will be created (if possible). See below for details.\n* `Downsampling method` - The downsampling method to be used if a multiscale pyramid can be created. See below for details.\n* `Compression` - The compression method to be used for chunks / blocks. \n* `metadata type` - style and type of metadata to store (see also [Metadata](#metadata))\n* `Thread count` - number of threads used for parallel writing (see also [Cloud writing benchmarks](#cloud-writing-benchmarks))\n* `Overwrite` - If checked, existing data may be deleted and overwritten without warning.\n\n### Container types\n\nIf the \"Format\" option is set to `Auto`, the export plugin infers the storage format from the given url given. First, it checks scheme\nof the URL, next it checks the directory or file extension. Note that URLs may have two schemes [(as in neuroglancer)](https://connectomics.readthedocs.io/en/latest/external/neuroglancer.html#basic-usage),\nfor example: `zarr://s3://my-bucket/my-key`\n\n* Filesystem N5 \n    * Specify a URL starting with `n5:`\n        * example `n5:/path/to/my/data.ext`\n    * Specify a directory ending in `.n5` \n        * example `/path/to/my/data.n5`\n* Zarr\n    * Specify a URL starting with `zarr:`\n        * example `zarr:/Users/user/Documents/sample`\n    * Specify a directory ending in `.zarr` \n        * example `/Users/user/Documents/sample.zarr`\n* HDF5\n    * Specify a URL starting with `hdf5:`\n        * example `hdf5:C:\\user\\docs\\example.ims`\n    * Specify a file ending in `.h5` ,`.hdf5`, or `.hdf`\n        * example `C:\\user\\docs\\example.h5`\n \n### Backend\n\nSpecify the backend by protocol, \"file:\" or not protocol indicate the local file system:\n\n* Amazon S3 \n    * Specify one of two url styles:\n    * `s3://bucket-name/path/to/root.n5`\n    * `https://bucket-name.s3.amazonaws.com/path/to/root.n5`\n* Google cloud storage (one of two url styles)\n    * Specify one of two url styles:\n    * `gs://bucket-name/path/inside/bucket/root.n5`\n    * `https://bucket-name.s3.amazonaws.com/path/to/root.n5`\n \n## Multi-scale pyramids\n\n### How many scale levels will be created\n\nThe number of scale levels is determined by the image size and specified block size.\nThe exporter will downsample an image only if the block size is striclty smaller than \nthe image size in every dimension.\n\n#### Example 1\n\nIf image size is `100 x 100 x 100` and the block size is `100 x 100 x 100`\nwill write one scale level because the whole image fits into one block\nat the first scale level.\n\n#### Example 2\n\nIf image size is `100 x 100 x 100` and the block size is `64 x 64 x 64`\nwill write two scale levels: The first scale level will have a `2 x 2 x 2` grid\nof blocks.\n\n#### Example 3\n\nIf image size is `100 x 100 x 32` and the block size is `64 x 64 x 64`\nwill write one scale level because the third dimension of the image is\nsmaller than the third dimension of the block.\n\n### Downsampling\n\nThe N5 exporter always downsamples images by factors of two in all dimensions.\nThere are two downsampling methods:\n\n#### Sample\n\nN5 will take even-indexed samples and discard odd-indexed samples along\neach dimension.\n\n#### Averaging\n\nN5 will average adjacent samples along each dimension. This results in a\n\"half-pixel\" shift, which will be reflected in the metadata.\n\n## Overwriting\n\n### Warning messages\n\nIf the `overwrite` option is not selected in the dialog, the exporter will determine if the\nwrite operation would overwrite or invalidate existing data. If so, it prompts the user with a\nwarning dialog, asking if data should be overwritten. \n\nData could be overwritten if:\n\n* the path where data will be written already exists and contains data. \n* a parent of the path where data will be written already exists and contains data. \n    * here, the newly written data would be inaccessible, because data arrays must be leafs of the hierarchy tree.\n\nIf the `overwrite` option is selected in the initial dialog, the user will not be prompted, but\ndata will be overwritten if needed as explained below.\n    \n#### Example 1\n\nA dataset exists at `/image`. User attempts to write data into `/image`. This warns the user\nabout overwriting because an array already exists at that location.\n\n#### Example 2\n\nA dataset exists at `/data/s0`. User attempts to write data into `/data` using N5Viewer metadata.\nThis warns the user about overwriting because when writing N5Viewer metadata, the plugin will \nwrite the full resolution level of the multiscale pyramid at location `/data/s0`, but an array\nalready exists at that location.\n\n### Overwriting removes existing data\n\nIf the user decides to overwite data the N5 exporter will completely (array data and metadata)\nremove any groups that cause conflicts before writing the new data.\n\n* If a dataset already exists at a path where new data will be written, then all data at that path will be removed.\n* If a dataset already exists at a parent path where new data will be written, then all data at that parent path will be removed.\n\n#### Example 3\n\nA dataset exists at `/image`. User attempts to write data into `/image/channel0`. This warns\nthe user about overwriting because the newly written data would be a child path of existing\ndata, and therefore be invalid. If the user decides to overwrite, all data at `/image` will be\nremoved before writing the new data to `/image/channel0`.\n\n## Metadata \n\nThis plugin supports three types of image metadata:\n1) ImageJ-style metadata \n2) [N5-viewer](https://github.com/saalfeldlab/n5-viewer) metadata\n3) [COSEM](https://github.com/janelia-cosem/schemas/blob/master/multiscale.md) metadata\n4) [OME-NGFF v0.4](https://ngff.openmicroscopy.org/0.4/) metadata\n5) Custom metadata. [Read details here](CustomMetadata.md)\n\nThe metadata style for exported HDF5/N5/Zarr/OME-NGFF datasets is customizable, more detail coming soon.\n\n## For developers\n\nImageJ convenience layer for N5\n\nBuild into your Fiji installation:\n```bash\nmvn -Dscijava.app.directory=/home/saalfelds/packages/Fiji.app -Ddelete.other.versions=true clean install\n```\n\nThen, in Fiji's Script Interpreter (Plugins \u003e Scripting \u003e Script Interpreter), load an N5 dataset into an `ImagePlus`:\n```java\nimport org.janelia.saalfeldlab.n5.*;\nimport org.janelia.saalfeldlab.n5.ij.*;\n\nimp = N5IJUtils.load(new N5FSReader(\"/home/saalfelds/example.n5\"), \"/volumes/raw\");\n```\n\nor save an `ImagePlus` into an N5 dataset:\n```java\nimport ij.IJ;\nimport org.janelia.saalfeldlab.n5.*;\nimport org.janelia.saalfeldlab.n5.ij.*;\n\nN5IJUtils.save(\n    IJ.getImage(),\n    new N5FSWriter(\"/home/saalfelds/example.n5\"),\n    \"/volumes/raw\",\n    new int[] {128, 128, 64},\n    new GzipCompression()\n);\n```\n\nSave an image stored locally to cloud storage (using four threads):\n```java\nfinal ImagePlus imp = IJ.openImage( \"/path/to/some.tif\" );\nfinal ExecutorService exec = Executors.newFixedThreadPool( 4 );\nN5IJUtils.save( imp, \n    new N5Factory().openWriter( \"s3://myBucket/myContainer.n5\" ), \n    \"/myDataset\", \n\tnew int[]{64, 64, 64},\n\tnew GzipCompression(), \n\texec );\nexec.shutdown();\n```\n\nSee also scripts demonstrating\n* [how to read and write imglib2 images with the methods in `N5Utils`](https://github.com/saalfeldlab/n5-imglib2/blob/master/scripts/readProcessWriteDemo.bsh)\n* [how to read and write ImageJ images with the methods in `N5IJUtils`](https://github.com/saalfeldlab/n5-ij/blob/master/scripts/readProcessWriteIJDemo.bsh)\n\n## Details\n\n* This plugin supports images of up to 5 dimensions, and the datatypes supported by ImageJ (`uint8`, `uint16`, `float32`) For higher dimensions and other datatypes, we recommend [n5-imglib2](https://github.com/saalfeldlab/n5-imglib2).\n\n* This plugin supports only the datatypes supported by ImageJ, namely uint8, uint16, and float32. For other datatypes, use [n5-imglib2](https://github.com/saalfeldlab/n5-imglib2).\n\n### Cloud writing benchmarks\n\nBelow are benchmarks for writing images of various sizes, block sizes, and with \nincreasing amount of parallelism.  \n\n#### Amazon S3\n\nTime in seconds to write the image data. Increased parallelism speeds\nup writing substantially when the total number of blocks is high.\n\n|  Image size  | Block size |  1 thread  |  2 threads  |  4 threads  |  8 threads  |  16 threads  |\n| ------------ | ---------- | ---------- | ----------- | ----------- | ----------- | ----------- |\n|  64x64x64  | 32x32x32 | 0.98 | 0.60 | 0.45 | 0.50 | 0.51 | \n|  128x128x128  | 32x32x32 | 4.72 | 2.64 | 1.62 | 1.00 |\n|  256x256x256  | 32x32x32 | 37.09 | 19.11 | 9.09 | 5.20 | 3.2 |\n|  256x256x256  | 64x64x64 | 10.56 | 5.04 | 3.23 | 2.17 | 1.86 |\n|  512x512x512  | 32x32x32 | 279.28 | 156.89 | 74.72 | 37.15 | 19.77 |\n|  512x512x512  | 64x64x64 | 76.63 | 38.16 | 19.86 | 10.16 | 6.14 |\n|  512x512x512  | 128x128x128 | 27.16 | 14.32 | 8.01 | 4.70 | 3.31 |\n|  1024x1024x1024  | 32x32x32 | 2014.73 | 980.66 | 483.04 | 249.83 | 122.36 |\n|  1024x1024x1024  | 64x64x64 | 579.46 | 289.53 | 149.98 | 75.85 | 38.18 |\n|  1024x1024x1024  | 128x128x128 | 203.47 | 107.23 | 55.11 | 27.41 | 15.33 |\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaalfeldlab%2Fn5-ij","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaalfeldlab%2Fn5-ij","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaalfeldlab%2Fn5-ij/lists"}