Create multiple thumbnail grids from slide images, max cols×(cols+1) images per grid.
(
image_paths,
cols,
width,
output_path,
placeholder_regions=None,
slide_dimensions=None,
)
| 272 | |
| 273 | |
| 274 | def create_grids( |
| 275 | image_paths, |
| 276 | cols, |
| 277 | width, |
| 278 | output_path, |
| 279 | placeholder_regions=None, |
| 280 | slide_dimensions=None, |
| 281 | ): |
| 282 | """Create multiple thumbnail grids from slide images, max cols×(cols+1) images per grid.""" |
| 283 | # Maximum images per grid is cols × (cols + 1) for better proportions |
| 284 | max_images_per_grid = cols * (cols + 1) |
| 285 | grid_files = [] |
| 286 | |
| 287 | print( |
| 288 | f"Creating grids with {cols} columns (max {max_images_per_grid} images per grid)" |
| 289 | ) |
| 290 | |
| 291 | # Split images into chunks |
| 292 | for chunk_idx, start_idx in enumerate( |
| 293 | range(0, len(image_paths), max_images_per_grid) |
| 294 | ): |
| 295 | end_idx = min(start_idx + max_images_per_grid, len(image_paths)) |
| 296 | chunk_images = image_paths[start_idx:end_idx] |
| 297 | |
| 298 | # Create grid for this chunk |
| 299 | grid = create_grid( |
| 300 | chunk_images, cols, width, start_idx, placeholder_regions, slide_dimensions |
| 301 | ) |
| 302 | |
| 303 | # Generate output filename |
| 304 | if len(image_paths) <= max_images_per_grid: |
| 305 | # Single grid - use base filename without suffix |
| 306 | grid_filename = output_path |
| 307 | else: |
| 308 | # Multiple grids - insert index before extension with dash |
| 309 | stem = output_path.stem |
| 310 | suffix = output_path.suffix |
| 311 | grid_filename = output_path.parent / f"{stem}-{chunk_idx + 1}{suffix}" |
| 312 | |
| 313 | # Save grid |
| 314 | grid_filename.parent.mkdir(parents=True, exist_ok=True) |
| 315 | grid.save(str(grid_filename), quality=JPEG_QUALITY) |
| 316 | grid_files.append(str(grid_filename)) |
| 317 | |
| 318 | return grid_files |
| 319 | |
| 320 | |
| 321 | def create_grid( |
no test coverage detected