|
8 | 8 | import sys
|
9 | 9 | from datetime import datetime
|
10 | 10 | from importlib.util import find_spec
|
| 11 | +from pathlib import Path |
11 | 12 |
|
| 13 | +import numpy as np |
| 14 | +from PIL import Image |
12 | 15 | from rich.logging import RichHandler
|
13 | 16 |
|
14 | 17 | from fancylog.tools.git import (
|
@@ -574,3 +577,62 @@ def disable_logging():
|
574 | 577 | no argument doesn't work.
|
575 | 578 | """
|
576 | 579 | logging.disable(2**63 - 1)
|
| 580 | + |
| 581 | + |
| 582 | +def log_image( |
| 583 | + image: np.ndarray, |
| 584 | + name: str, |
| 585 | + logging_dir: str, |
| 586 | + subfolder: str = "media/images", |
| 587 | + metadata: dict | None = None, |
| 588 | +): |
| 589 | + """Save an image to the logging dir and record its path in the log.""" |
| 590 | + output_dir = Path(logging_dir) |
| 591 | + image_dir = output_dir / subfolder |
| 592 | + image_dir.mkdir(parents=True, exist_ok=True) |
| 593 | + |
| 594 | + if image.dtype != np.uint8: |
| 595 | + image = ((image - image.min()) / (np.ptp(image) + 1e-5) * 255).astype( |
| 596 | + np.uint8 |
| 597 | + ) |
| 598 | + |
| 599 | + filepath = image_dir / f"{name}.tiff" |
| 600 | + Image.fromarray(image).save(filepath, format="TIFF") |
| 601 | + |
| 602 | + if metadata: |
| 603 | + meta_path = image_dir / f"{name}_meta.json" |
| 604 | + with open(meta_path, "w") as f: |
| 605 | + json.dump(metadata, f, indent=2) |
| 606 | + |
| 607 | + logging.getLogger(__name__).info( |
| 608 | + f"[fancylog] Saved image: {filepath.relative_to(output_dir)}" |
| 609 | + ) |
| 610 | + return filepath |
| 611 | + |
| 612 | + |
| 613 | +def log_data_object( |
| 614 | + data, |
| 615 | + name: str, |
| 616 | + logging_dir: str, |
| 617 | + subfolder: str = "media/data", |
| 618 | + ext: str = "json", |
| 619 | +): |
| 620 | + """Save structured data (e.g., dict, list, numpy array) to disk.""" |
| 621 | + output_dir = Path(logging_dir) |
| 622 | + data_dir = output_dir / subfolder |
| 623 | + data_dir.mkdir(parents=True, exist_ok=True) |
| 624 | + |
| 625 | + path = data_dir / f"{name}.{ext}" |
| 626 | + |
| 627 | + if isinstance(data, (dict | list)): |
| 628 | + with open(path, "w") as f: |
| 629 | + json.dump(data, f, indent=2) |
| 630 | + elif isinstance(data, np.ndarray): |
| 631 | + np.save(path, data) |
| 632 | + else: |
| 633 | + raise ValueError("Unsupported data type for logging") |
| 634 | + |
| 635 | + logging.getLogger(__name__).info( |
| 636 | + f"[fancylog] Saved data object: {path.relative_to(output_dir)}" |
| 637 | + ) |
| 638 | + return path |
0 commit comments