Skip to content

Instantly share code, notes, and snippets.

@alea12
Last active June 18, 2026 10:20
Show Gist options
  • Select an option

  • Save alea12/e5ca0b249a2374def2f773de7e0284d2 to your computer and use it in GitHub Desktop.

Select an option

Save alea12/e5ca0b249a2374def2f773de7e0284d2 to your computer and use it in GitHub Desktop.
bmp_to_tiff_converter.py
#!/usr/bin/env python3
"""
BMP → TIFF Converter (Updated - Cleaner Logging)
"""
import argparse
import tkinter as tk
from tkinter import filedialog, messagebox
from pathlib import Path
from collections import defaultdict
from PIL import Image
def convert_bmp_to_tiff(root_dir: str):
root_path = Path(root_dir).resolve()
if not root_path.exists() or not root_path.is_dir():
print(f"ERROR: '{root_path}' is not a valid folder.")
return
print(f"Scanning: {root_path}")
print("-" * 60)
# Find all BMP files (handles both .bmp and .BMP)
bmp_files = list(root_path.rglob("*.bmp")) + list(root_path.rglob("*.BMP"))
if not bmp_files:
print("No BMP files found.")
return
# Group by parent folder
bmps_by_dir = defaultdict(list)
for bmp in bmp_files:
bmps_by_dir[bmp.parent].append(bmp)
total_converted = 0
total_skipped = 0
folders_processed = 0
for dir_path, bmp_list in sorted(bmps_by_dir.items()):
tiff_dir = dir_path / "TIFF"
tiff_dir.mkdir(exist_ok=True)
new_in_this_folder = 0
skipped_in_this_folder = 0
for bmp_path in sorted(bmp_list):
tif_path = tiff_dir / (bmp_path.stem + ".TIF")
if tif_path.exists():
skipped_in_this_folder += 1
continue
try:
with Image.open(bmp_path) as img:
img.save(tif_path, format="TIFF")
print(f"✅ {dir_path.name}/{bmp_path.name} → TIFF/{tif_path.name}")
new_in_this_folder += 1
total_converted += 1
except Exception as e:
print(f"❌ ERROR: {bmp_path} → {e}")
total_skipped += skipped_in_this_folder
folders_processed += 1
# Clean per-folder summary
if new_in_this_folder > 0 or skipped_in_this_folder > 0:
print(f" → {new_in_this_folder} new | {skipped_in_this_folder} already existed")
print("\n" + "=" * 60)
print("CONVERSION COMPLETE")
print(f" Folders processed : {folders_processed}")
print(f" Newly converted : {total_converted}")
print(f" Already existed : {total_skipped}")
print("=" * 60)
def main():
parser = argparse.ArgumentParser(
description="Convert BMP files to TIFF (creates TIFF/ subfolder). Skips files that already exist."
)
parser.add_argument(
"root_folder",
nargs="?",
default=None,
help="Root folder (optional - shows folder picker if omitted)"
)
args = parser.parse_args()
if args.root_folder:
root_dir = args.root_folder
else:
root = tk.Tk()
root.withdraw()
root.attributes("-topmost", True)
root_dir = filedialog.askdirectory(title="Select root folder containing BMPs")
root.destroy()
if not root_dir:
messagebox.showinfo("Cancelled", "No folder selected.")
return
convert_bmp_to_tiff(root_dir)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment