-
Notifications
You must be signed in to change notification settings - Fork 70
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Motivation
When processing large single-layer TIFF files, the current OpenSlideWSI.get_thumbnail() method is extremely slow. Performance testing shows OpenSlide takes ~10 seconds while a tifffile-based approach takes ~0.5 seconds (about 20x faster) for the same thumbnail generation.
Proposed Solution
Proposed Solution:
Implement a hybrid approach in OpenSlideWSI.get_thumbnail() that:
Uses tifffile library with smart downsampling for single-layer TIFF files
Falls back to OpenSlide's native method for other WSI formats (.svs, .ndpi, etc.)
Maintains full backward compatibility
def get_thumbnail(self, size: tuple[int, int]) -> Image.Image:
"""
Generate a thumbnail of the WSI using optimized method based on file type.
For single-layer TIFF files, uses tifffile for better performance.
For other WSI formats, uses OpenSlide's native method.
Parameters
----------
size : tuple of int
Desired (width, height) of the thumbnail.
Returns
-------
PIL.Image.Image
RGB thumbnail as a PIL Image.
"""
# Use tifffile optimization for TIFF files
if self.slide_path.lower().endswith(('.tiff', '.tif')):
try:
import tifffile
with tifffile.TiffFile(self.slide_path) as tif:
page = tif.pages[0]
shape = page.shape
h, w = shape[:2]
# Calculate aspect-preserving thumbnail size
aspect_ratio = w / h
target_w, target_h = size
if aspect_ratio > (target_w / target_h):
final_w = target_w
final_h = round(target_w / aspect_ratio)
else:
final_h = target_h
final_w = round(target_h * aspect_ratio)
# Calculate optimal downsampling steps
step_h = max(1, h // (final_h * 2))
step_w = max(1, w // (final_w * 2))
# Read downsampled data
if len(shape) == 2: # Grayscale
data = page.asarray()[::step_h, ::step_w]
img = Image.fromarray(data, mode='L').convert('RGB')
else: # Color
data = page.asarray()[::step_h, ::step_w, :]
img = Image.fromarray(data[:, :, :3], mode='RGB')
# Resize to exact target dimensions
return img.resize((final_w, final_h), Image.Resampling.LANCZOS)
except ImportError:
pass # tifffile not available, fall back to OpenSlide
except Exception:
pass # tifffile failed, fall back to OpenSlide
# Use OpenSlide's native method for other formats (.svs, .ndpi, etc.)
return self.img.get_thumbnail(size).convert('RGB')
This would significantly improve user experience for single-layer TIFF processing while preserving existing functionality for multi-layer WSI workflow
Who does this help?
None
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request