Skip to content

Commit

Permalink
Merge pull request #31 from GenevieveBuckley/colormaps-update
Browse files Browse the repository at this point in the history
Simplify colormaps
  • Loading branch information
GenevieveBuckley authored Jul 9, 2024
2 parents 33a9426 + 8102c81 commit 7dd6c3b
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 70 deletions.
49 changes: 3 additions & 46 deletions napari_tiff/napari_tiff_colormaps.py
Original file line number Diff line number Diff line change
@@ -1,56 +1,13 @@
import numpy
from vispy.color import Colormap


def alpha_colormap(bitspersample=8, samples=4):
"""Return Alpha colormap."""
n = 2**bitspersample
ramp = numpy.linspace(0.0, 1.0, n).astype("float32")
a = numpy.zeros((n, samples), dtype="float32")
a[:, 3] = ramp[::-1]
return Colormap(a)


def rgb_colormaps(bitspersample=8, samples=3):
"""Return RGB colormaps."""
n = 2**bitspersample
ramp = numpy.linspace(0.0, 1.0, n).astype("float32")
r = numpy.zeros((n, samples), dtype="float32")
r[:, 0] = ramp
g = numpy.zeros((n, samples), dtype="float32")
g[:, 1] = ramp
b = numpy.zeros((n, samples), dtype="float32")
b[:, 2] = ramp
if samples > 3:
r[:, 3:] = 1.0
g[:, 3:] = 1.0
b[:, 3:] = 1.0
return [Colormap(r), Colormap(g), Colormap(b)]


def cmyk_colormaps(bitspersample=8, samples=3):
"""Return CMYK colormaps."""
n = 2**bitspersample
ramp = numpy.linspace(1.0, 0.0, n).astype("float32")
c = numpy.zeros((n, samples), dtype="float32")
c[:, 1] = ramp
c[:, 2] = ramp
m = numpy.zeros((n, samples), dtype="float32")
m[:, 0] = ramp
m[:, 2] = ramp
y = numpy.zeros((n, samples), dtype="float32")
y[:, 0] = ramp
y[:, 1] = ramp
k = numpy.zeros((n, samples), dtype="float32")
k[:, 0] = ramp
k[:, 1] = ramp
k[:, 2] = ramp
if samples > 3:
c[:, 3:] = 1.0
m[:, 3:] = 1.0
y[:, 3:] = 1.0
k[:, 3:] = 1.0
return [Colormap(c), Colormap(m), Colormap(y), Colormap(k)]
alpha_cmap = numpy.zeros((n, samples), dtype="float32")
alpha_cmap[:, 3] = ramp[::-1]
return {"name": "alpha", "colors": alpha_cmap}


def int_to_rgba(intrgba: int) -> tuple:
Expand Down
38 changes: 16 additions & 22 deletions napari_tiff/napari_tiff_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,8 @@

import numpy
from tifffile import PHOTOMETRIC, TiffFile, xml2dict
from vispy.color import Colormap

from napari_tiff.napari_tiff_colormaps import (
alpha_colormap,
cmyk_colormaps,
int_to_rgba,
rgb_colormaps,
)
from napari_tiff.napari_tiff_colormaps import alpha_colormap, int_to_rgba


def get_metadata(tif: TiffFile) -> dict[str, Any]:
Expand Down Expand Up @@ -62,7 +56,7 @@ def get_tiff_metadata(tif: TiffFile) -> dict[str, Any]:
page = next(p for p in series.pages if p is not None)
extrasamples = page.extrasamples

rgb = page.photometric in (2, 6) and shape[-1] in (3, 4)
rgb = page.photometric in (PHOTOMETRIC.RGB, PHOTOMETRIC.YCBCR) and shape[-1] in (3, 4)
name = None
scale = None
colormap = None
Expand All @@ -71,18 +65,18 @@ def get_tiff_metadata(tif: TiffFile) -> dict[str, Any]:
channel_axis = None
visible = True

if page.photometric == 5:
if page.photometric == PHOTOMETRIC.SEPARATED:
# CMYK
channel_axis = axes.find("S")
if channel_axis >= 0 and shape[channel_axis] >= 4:
colormap = cmyk_colormaps()
colormap = ["cyan", "magenta", "yellow", "gray"]
name = ["Cyan", "Magenta", "Yellow", "Black"]
visible = [False, False, False, True]
blending = ["additive", "additive", "additive", "additive"]
# TODO: use subtractive blending
else:
channel_axis = None
elif page.photometric in (2, 6) and (
elif page.photometric in (PHOTOMETRIC.RGB, PHOTOMETRIC.YCBCR) and (
page.planarconfig == 2
or (page.bitspersample > 8 and dtype.kind in "iu")
or (extrasamples and len(extrasamples) > 1)
Expand All @@ -98,7 +92,7 @@ def get_tiff_metadata(tif: TiffFile) -> dict[str, Any]:
else:
channel_axis = None
elif (
page.photometric in (0, 1)
page.photometric in (PHOTOMETRIC.MINISWHITE, PHOTOMETRIC.MINISBLACK)
and extrasamples
and any(sample > 0 for sample in extrasamples)
):
Expand All @@ -107,7 +101,7 @@ def get_tiff_metadata(tif: TiffFile) -> dict[str, Any]:
if channel_axis >= 0:
visible = [True]
colormap = ["gray"]
name = ["Minisblack" if page.photometric == 1 else "Miniswhite"]
name = ["Minisblack" if page.photometric == PHOTOMETRIC.MINISBLACK else "Miniswhite"]
blending = ["additive"]
else:
channel_axis = None
Expand All @@ -129,7 +123,7 @@ def get_tiff_metadata(tif: TiffFile) -> dict[str, Any]:
name.append("Alpha")
blending.append("translucent")

if channel_axis is None and page.photometric in (0, 1):
if channel_axis is None and page.photometric in (PHOTOMETRIC.MINISWHITE, PHOTOMETRIC.MINISBLACK):
# separate up to 3 samples in grayscale images
channel_axis = axes.find("S")
if channel_axis >= 0 and 1 < shape[channel_axis] < 4:
Expand All @@ -149,23 +143,23 @@ def get_tiff_metadata(tif: TiffFile) -> dict[str, Any]:
else:
channel_axis = None

if page.photometric == 3 and page.colormap is not None:
if page.photometric == PHOTOMETRIC.PALETTE and page.colormap is not None:
# PALETTE
colormap = page.colormap
if numpy.max(colormap) > 255:
colormap = colormap / 65535.0
else:
colormap = colormap / 255.0
colormap = Colormap(colormap.astype("float32").T)
colormap = colormap.astype("float32").T

if colormap is None and page.photometric == 0:
# MINISBLACK
if colormap is None and page.photometric == PHOTOMETRIC.MINISWHITE:
# MINISWHITE
colormap = "gray_r"

if (
contrast_limits is None
and dtype.kind == "u"
and page.photometric != 3
and page.photometric != PHOTOMETRIC.PALETTE
and page.bitspersample not in (8, 16, 32, 64)
):
contrast_limits = (0, 2**page.bitspersample)
Expand Down Expand Up @@ -195,7 +189,7 @@ def get_imagej_metadata(tif: TiffFile) -> dict[str, Any]:
axes = series.axes
shape = series.shape
page = series.pages[0]
rgb = page.photometric == 2 and shape[-1] in (3, 4)
rgb = page.photometric == PHOTOMETRIC.RGB and shape[-1] in (3, 4)
mode = ijmeta.get("mode", None)
channels = ijmeta.get("channels", 1)
channel_axis = None
Expand Down Expand Up @@ -243,7 +237,7 @@ def get_imagej_metadata(tif: TiffFile) -> dict[str, Any]:
rgb = False
n = shape[channel_axis]
visible = [True, True, True]
colormap = rgb_colormaps(samples=4)[:n]
colormap = ["red", "green", "blue", alpha_colormap()]
name = ["Red", "Green", "Blue", "Alpha"][:n]
blending = ["additive", "additive", "additive", "translucent"][:n]
else:
Expand Down Expand Up @@ -331,7 +325,7 @@ def get_ome_tiff_metadata(tif: TiffFile) -> dict[str, Any]:
colormap = int_to_rgba(int(color))
elif is_rgb and len(channels) > 1:
# separate channels provided for RGB (with missing color)
colormap = ["red", "green", "blue", "alpha"][channeli]
colormap = ["red", "green", "blue", alpha_colormap()][channeli]
if not name:
name = colormap

Expand Down
2 changes: 1 addition & 1 deletion napari_tiff/napari_tiff_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from typing import Any, Callable, Dict, List, Optional, Tuple, Union

from tifffile import TIFF, TiffFile, TiffSequence, xml2dict
from tifffile import TIFF, TiffFile, TiffSequence

from napari_tiff.napari_tiff_metadata import get_metadata

Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ dependencies = [
'imagecodecs',
'numpy',
'tifffile>=2023.9.26',
'vispy',
'zarr',
]

Expand Down

0 comments on commit 7dd6c3b

Please sign in to comment.