imagej / imagej/ImageJ

Overlays don't show for compressed multi-page tifs

Open
#296 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
786
Forks
267
PR merge metrics
No merged PRs in 30d

Description

### Problem

When I open a multi-page ImageJ TIFF that embeds ROI overlays and uses LZW compression, the image loads but **no overlays appear**. The same file written without compression shows overlays correctly.

### Minimal reproducer
Four images were generated using this python script:
```python
import numpy as np
import roifile
import tifffile

# enable / disable compression
for compression in (None, "lzw"):

# single-frame image when n=1
# stack when n=10
for n in (1, 10):
path = f"overlay_test_{compression or 'uncompressed'}_{n}.tif"
print(f"{compression=!r}, {n=!r} -> {path!r}")

# create a rectangle roi
overlay = roifile.ImagejRoi(
left=10,
top=10,
right=40,
bottom=40,
name="test_roi",
roitype=roifile.ROI_TYPE.RECT,
stroke_color=bytes((255, 255, 255, 255)),
version=228,
).tobytes()

# write the image
tifffile.imwrite(
path,
np.zeros((n, 64, 64)),
compression=compression,
metadata={"Overlays": [overlay]},
imagej=True,
)

```
Rois show up correctly for 3/4 examples, failing in `overlay_test_lzw_10.tif`

**Expected:**
- Overlays embedded in the IJ metadata block (tag 50839) are displayed regardless of compression, since the overlay bytes are present in both files.

**Observed:**
- Overlays show in LZW compressed single images, uncompresed image stacks, but not compressed image stacks.

### Potential Cause \*

1. `TiffDecoder.saveImageDescription()` only sets `fi.nImages` from `images=N` when `fi.compression == COMPRESSION_NONE` (`TiffDecoder.java` ~214).

2. With LZW, `images=2` is ignored, so ImageJ reads both IFDs via `Opener.openTiffStack()`'s multi-IFD branch instead of the `fi.nImages > 1` → `FileOpener.openImage()` path.

3. `FileOpener.openStack()` calls `setOverlay()` when `fi.overlay != null`; the multi-IFD branch in `Opener.openTiffStack()` (~914–929) does not.

So `fi.overlay` appears to be parsed from metadata but never applied on the LZW / multi-IFD code path.

### Potential Fix \*

One approach might be to call `setOverlay()` in `Opener.openTiffStack()`'s multi-IFD branch when `fi.overlay != null`, similar to `FileOpener.openStack()`. Alternatively, setting `fi.nImages` from `images=N` regardless of compression (if that is safe for LZW contiguous stacks) could route through the existing overlay path.

---

*\* Sections marked with a trailing asterisk were written with generative AI.*

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with TiffDecoder.saveImageDescription(), then compare FileOpener.openStack() with the multi-IFD branch in Opener.openTiffStack(). Reproduce the four TIFF cases from the supplied Python script, focusing on overlay_test_lzw_10.tif. Done means embedded overlays appear for compressed multi-page TIFFs without regressing the other three cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
computer-vision
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.