|
11 | 11 | import pytest |
12 | 12 | from hyperspy.io import load as hs_load |
13 | 13 | from hyperspy.misc.utils import stack as hs_stack |
| 14 | +from PIL import Image as PILImage |
14 | 15 |
|
15 | 16 | from nexusLIMS.extractors.plugins.preview_generators import ( |
16 | 17 | hyperspy_preview, |
@@ -384,6 +385,41 @@ def test_tif_to_thumbnail(self, output_path, image_thumb_source_tif): |
384 | 385 | image_to_square_thumbnail(image_thumb_source_tif, output_path, 500) |
385 | 386 | assert_images_equal(baseline_thumb_tif, output_path) |
386 | 387 |
|
| 388 | + def test_16bit_tif_contrast_stretch(self, tmp_path, output_path): |
| 389 | + """Test 16-bit TIFFs get percentile contrast stretching applied. |
| 390 | +
|
| 391 | + Without contrast stretching, PIL would naively truncate uint16 values to |
| 392 | + 8-bit (e.g. 40000 becomes ~156 via 40000/256). With the stretch applied, |
| 393 | + the bright pixels are mapped to 255, confirming the stretch ran. |
| 394 | + """ |
| 395 | + arr = np.zeros((100, 100), dtype=np.uint16) |
| 396 | + arr[10:90, 10:90] = 40000 # bright outer region |
| 397 | + arr[20:80, 20:80] = 1000 # intermediate inner region |
| 398 | + tif_path = tmp_path / "test_16bit.tif" |
| 399 | + PILImage.fromarray(arr).save(tif_path) |
| 400 | + |
| 401 | + result = image_to_square_thumbnail(tif_path, output_path, 500) |
| 402 | + |
| 403 | + assert result is True |
| 404 | + assert output_path.exists() |
| 405 | + out_arr = np.array(PILImage.open(output_path).convert("L")) |
| 406 | + # Without stretch, 40000 would truncate to ~156; with stretch it maps to 255 |
| 407 | + assert out_arr.max() == 255 |
| 408 | + # Intermediate values (1000) should appear as non-zero after stretching |
| 409 | + assert out_arr.mean() > 1 |
| 410 | + |
| 411 | + def test_unidentified_image_removes_partial_output( |
| 412 | + self, unreadable_image_file, output_path |
| 413 | + ): |
| 414 | + """Test that an existing output file is removed on UnidentifiedImageError.""" |
| 415 | + output_path.write_bytes(b"partial output") |
| 416 | + assert output_path.exists() |
| 417 | + |
| 418 | + result = image_to_square_thumbnail(unreadable_image_file, output_path, 500) |
| 419 | + |
| 420 | + assert result is False |
| 421 | + assert not output_path.exists() |
| 422 | + |
387 | 423 | def test_assert_image_fail(self, image_thumb_source_tif, quanta_test_file): |
388 | 424 | """Sanity check that for images that are not the same.""" |
389 | 425 | with pytest.raises(AssertionError): |
|
0 commit comments