Skip to content

Instantly share code, notes, and snippets.

@weshford
Created August 8, 2026 10:04
Show Gist options
  • Select an option

  • Save weshford/a7b71db3350732b9bce387af4ae390d6 to your computer and use it in GitHub Desktop.

Select an option

Save weshford/a7b71db3350732b9bce387af4ae390d6 to your computer and use it in GitHub Desktop.
small python script to convert png jpgs etc to avif (in parallel hopefully). for me, this reduced filesizes from ~20GB to 7,9GB
#!/usr/bin/env python3
import os
from pathlib import Path
from multiprocessing import Pool, cpu_count
from PIL import Image
import pillow_avif # noqa: F401
from tqdm import tqdm
SOURCE = Path("/home/sonic/Desktop/alte")
DEST = Path("/home/sonic/Desktop/hallo")
WORKERS = 12 # your CPU cores
def find_images():
files = []
for ext in ("*.jpg", "*.jpeg", "*.png", "*.JPG", "*.JPEG", "*.PNG"):
files.extend(SOURCE.rglob(ext))
return files
def convert_file(path):
try:
relative = path.relative_to(SOURCE)
output = DEST / relative.with_suffix(".avif")
output.parent.mkdir(parents=True, exist_ok=True)
# Skip already converted files
if output.exists():
return ("skipped", str(path))
with Image.open(path) as img:
img = img.convert("RGB")
img.save(
output,
"AVIF",
quality=85,
speed=6
)
return ("success", str(path))
except Exception as e:
return ("failed", f"{path}: {e}")
def main():
DEST.mkdir(parents=True, exist_ok=True)
images = find_images()
if not images:
print("No images found.")
return
total = len(images)
print(f"Found {total} images")
print(f"Using {WORKERS} CPU workers")
print()
success = 0
failed = 0
skipped = 0
with Pool(WORKERS) as pool:
with tqdm(
total=total,
desc="Converting",
unit="img",
dynamic_ncols=True
) as bar:
for result, info in pool.imap_unordered(convert_file, images):
if result == "success":
success += 1
elif result == "failed":
failed += 1
print("\nFAILED:", info)
elif result == "skipped":
skipped += 1
bar.update(1)
bar.set_postfix(
ok=success,
fail=failed,
skip=skipped
)
print("\n========== Finished ==========")
print(f"Total: {total}")
print(f"Successful: {success}")
print(f"Failed: {failed}")
print(f"Skipped: {skipped}")
print(f"Remaining: {total - success - failed - skipped}")
print("==============================")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment