diff --git a/PROJECTS/metadata-scrubber-tool/README.md b/PROJECTS/metadata-scrubber-tool/README.md index 2edd3b9d..2c4b74b4 100644 --- a/PROJECTS/metadata-scrubber-tool/README.md +++ b/PROJECTS/metadata-scrubber-tool/README.md @@ -258,6 +258,17 @@ docs/ - **PDF embedded images** - Images inside PDFs retain their original metadata - **Large files** - Files are loaded into memory; very large files may be slow +### PNG Verification Behavior + +When a PNG file has no EXIF metadata (only PngInfo text chunks), the scrub operation removes all text keys. Attempting to verify or read the processed file will show: + +``` +Error during verification: No metadata found in the PNG image. +``` + +**This is expected behavior** - the error confirms that all metadata has been successfully removed. You can also use `mst read processed_file.png` to verify; the same error indicates a clean file. + + ### Potential Enhancements - HEIC/HEIF support (common on iOS devices) diff --git a/PROJECTS/metadata-scrubber-tool/src/services/image_handler.py b/PROJECTS/metadata-scrubber-tool/src/services/image_handler.py index 13ee901d..2db499c4 100644 --- a/PROJECTS/metadata-scrubber-tool/src/services/image_handler.py +++ b/PROJECTS/metadata-scrubber-tool/src/services/image_handler.py @@ -39,6 +39,7 @@ class ImageHandler(MetadataHandler): tags_to_delete: List of EXIF tags to remove during wipe operation. detected_format: Actual image format detected by Pillow. """ + def __init__(self, filepath: str): """ Initialize the image handler. @@ -47,11 +48,10 @@ class ImageHandler(MetadataHandler): filepath: Path to the image file to process. """ super().__init__(filepath) - self.processors: dict[str, - JpegProcessor | PngProcessor] = { - "jpeg": JpegProcessor(), - "png": PngProcessor(), - } + self.processors: dict[str, JpegProcessor | PngProcessor] = { + "jpeg": JpegProcessor(), + "png": PngProcessor(), + } self.tags_to_delete: list[int] = [] self.detected_format: str | None = None self.text_keys_to_delete: list[str] = [] @@ -105,7 +105,7 @@ class ImageHandler(MetadataHandler): self.metadata = result["data"] self.tags_to_delete = result["tags_to_delete"] # Store text keys for PNG processing - if isinstance(result, PngProcessor): + if isinstance(processor, PngProcessor): self.text_keys_to_delete = result.get("text_keys", []) return self.metadata @@ -128,16 +128,12 @@ class ImageHandler(MetadataHandler): with Image.open(Path(self.filepath)) as img: self.processed_metadata = cast( - dict[str, - Any], - processor.delete_metadata(img, - self.tags_to_delete) + dict[str, Any], processor.delete_metadata(img, self.tags_to_delete) ) # For PNG, also get clean PngInfo if isinstance(processor, PngProcessor): self.clean_pnginfo = processor.get_clean_pnginfo( - img, - self.text_keys_to_delete + img, self.text_keys_to_delete ) def save(self, output_path: str | Path | None = None) -> None: @@ -164,7 +160,7 @@ class ImageHandler(MetadataHandler): shutil.copy2(self.filepath, destination_file_path) with Image.open(destination_file_path) as img: exif_bytes = piexif.dump(self.processed_metadata) - img.save(destination_file_path, exif = exif_bytes) + img.save(destination_file_path, exif=exif_bytes) elif actual_format == "png": # PNG: Open original, save fresh copy without metadata @@ -173,9 +169,7 @@ class ImageHandler(MetadataHandler): # Preserve image mode and data integrity img.save( destination_file_path, - format = "PNG", - exif = None, - pnginfo = getattr(self, - "clean_pnginfo", - None), + format="PNG", + exif=None, + pnginfo=getattr(self, "clean_pnginfo", None), )