Skip to content

Optionally use ICC profiles with OpenSlide images#2045

Merged
petebankhead merged 5 commits intoqupath:mainfrom
petebankhead:icc-openslide
Dec 5, 2025
Merged

Optionally use ICC profiles with OpenSlide images#2045
petebankhead merged 5 commits intoqupath:mainfrom
petebankhead:icc-openslide

Conversation

@petebankhead
Copy link
Member

@petebankhead petebankhead commented Dec 5, 2025

Addresses #982, albeit in a limited way.

Main changes

  1. ICC profiles can optionally be used to transform pixel values at the point they are read (i.e., not limited to the viewer) when using OpenSlide
  2. New persistent preference are added to turn ICC profiles on (off by default)
    • Bonus preference to request that OpenSlide images are cropped to their bounding box (on by default)
  3. OpenSlide is now used ahead of Bio-Formats for compatible DICOM images

Use

The expected use is by toggling the preference. Then the DICOM image from #982 (comment) looks like this:

image

Note that the 'server type' is used to indicate that it is not using the original pixels.

The source profile is that provided by OpenSlide, the destination is from Java via ICC_Profile.getInstance(ICC_ColorSpace.CS_sRGB).

With the checkbox turned off, it looks as before.

image

It's also possible to specify that the profile should be used by passing the argument --icc-profile when importing an image to a project.

This gives some additional options to explore alternative source and destination profiles in a form compatible with ICC_Profile.getInstance(String). For example --icc-profile --icc-profile-dest LINEAR_RGB.pf would use an alternative destination, and adding --icc-profile-source file_name would give a different source.

Based on the javadocs for ICC_Profile, setting a system property for java.iccprofile.path would potentially make it possible to access alternative profiles in a different location... but this is rather experimental and not to be recommended as it hasn't been tested at all.

Compatibility

Projects created using these transforms can be opened with older versions of QuPath but they won't apply the ICC profiles.

I'd prefer that the projects wouldn't open, but the approach taken here was to encode the information about the profiles into the string arguments the are already stored for each entry in a project - since this avoided making more drastic changes.

Things I tried (and gave up on)

Supporting Bio-Formats / anything other than OpenSlide

OpenSlide provides straightforward access to the ICC profile stored in an image, but Bio-Formats does not. I initially tried adding some support to pull out the ICC profiles from TIFF images, but this proved tricky (considering that there might be multiple images in a single file, and I struggled to access the required info through the Bio-Formats API).

A generic wrapper for any image

I also experimented creating a new ImageServer implementation that would wrap up any image, and then have JSON-serializable way to store the necessary ICC profile information - both for embedded profiles, and profiles saved as external files.

In the end, this became too complex - mostly because of the need to

  1. serialise things properly, without breaking compatibility
  2. handle the fact that files move (and so paths need updated)
  3. cope with the fact that QuPath ImageServers can be wrapped in other ImageServers lots of times, and these might perform spatial/intensity transforms
  4. make the UI intuitive, and clearly show when a transform has been applied... rather than hope the user remembers.

ICC profiles applied only in the viewer

This was tricky firstly because applying the required transform is slow enough to require caching, which meant that the most effective way to do it would be to write the generic wrapper in the last section.

Also, QuPath's viewer doesn't focus on showing RGB images - it supports multiplexed images, LUT changes, and extra tricks like live color deconvolution - and so it was hard to figure out where exactly the profiles should be applied.

Outlook

Hopefully this helps address most of the need for ICC profile support in QuPath well enough, while also giving some flexibility to explore without changing the code (by passing in other args).

Within the next year or two, we want to write an entirely new viewer and also an entirely different way to access pixels. This will give a chance to consider how ICC profiles should be considered from the start, rather than needing to squeeze them in later.

This is currently done using optional args. Behavior may change (soon)...
If an MRXS file couldn't be opened by OpenSlide (e.g. the directory wasn't there), a low-resolution version would previously be created - probably by ImageJ. This was more confusing for users than reporting an error.
@petebankhead petebankhead added this to the v0.7.0 milestone Dec 5, 2025
@petebankhead petebankhead merged commit 3c40ea6 into qupath:main Dec 5, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant