Skip to content

Commit 19d92a8

Browse files
Copilotadamjtaylor
andcommitted
Fix PIL array shape handling for RGB OME-TIFF thumbnails
- Read from base series instead of smallest pyramid level to avoid tiny images - Add np.squeeze() to remove singleton dimensions - Handle 1D arrays by reshaping to 2D - Handle >3D arrays by taking first slice - Fixes TypeError: Cannot handle this data type: (1, 1, 138), |u1 Co-authored-by: adamjtaylor <14945787+adamjtaylor@users.noreply.github.com>
1 parent 8dadf28 commit 19d92a8

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

modules/make_miniature.nf

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,35 @@ process make_miniature {
2121
from PIL import Image
2222
import numpy as np
2323
24-
# Open the OME-TIFF file
24+
# Open the OME-TIFF file and read the base (full resolution) image
25+
# Let PIL handle the resizing via thumbnail() - it's more robust
2526
with tifffile.TiffFile('$image') as tif:
26-
# For pyramidal images, use the smallest level for efficiency
27-
if len(tif.series) > 0 and hasattr(tif.series[0], 'levels') and len(tif.series[0].levels) > 1:
28-
# Get the smallest pyramid level
29-
level = tif.series[0].levels[-1]
30-
img_array = level.asarray()
27+
# Always read from the base series (full resolution)
28+
# Don't try to use pyramid levels as they may be too small or have odd shapes
29+
if len(tif.series) > 0:
30+
img_array = tif.series[0].asarray()
3131
else:
32-
# No pyramid or single level, read the full resolution
3332
img_array = tif.asarray()
3433
34+
# Handle array shape - squeeze out singleton dimensions
35+
img_array = np.squeeze(img_array)
36+
37+
# Ensure we have at least 2D array
38+
if img_array.ndim < 2:
39+
# After squeezing, if we end up with 1D, reshape to 2D
40+
img_array = img_array.reshape(1, -1)
41+
42+
# Handle different array shapes
43+
# Expected shapes: (Y, X), (Y, X, 3), (Y, X, 4) for grayscale, RGB, or RGBA
44+
if img_array.ndim > 3:
45+
# If more than 3 dimensions after squeeze, take first slice
46+
# This handles cases like (C, Y, X, S) -> take first channel
47+
img_array = img_array[0]
48+
img_array = np.squeeze(img_array)
49+
# Check again after squeezing
50+
if img_array.ndim < 2:
51+
img_array = img_array.reshape(1, -1)
52+
3553
# Ensure proper data type for PIL (uint8)
3654
if img_array.dtype != np.uint8:
3755
# Scale to uint8 range if needed
@@ -50,6 +68,7 @@ process make_miniature {
5068
thumb = Image.fromarray(img_array)
5169
5270
# Create thumbnail (maintains aspect ratio)
71+
# PIL's thumbnail is efficient and handles large images well
5372
thumb.thumbnail((512, 512))
5473
5574
# Ensure RGB mode

0 commit comments

Comments
 (0)