Working with lots of images? Whether you’re handling user-uploads, prepping assets for the web, or just cleaning up a folder of photos, automating conversion and compression will save you hours of manual work—and bandwidth!
In this tutorial you’ll learn how to:
Batch-convert any image (PNG, WEBP, TIFF, BMP…) to JPEG
Optimize the resulting JPEGs for web-friendly file sizes
Package it all into a one-file Python script
🛠️ Prerequisites:
Python 3.6+ installed on your machine
Basic comfort with the command line
(Optional) A virtualenv or Conda environment
pip install pillow
📂 Project Structure:
Create a folder called image-converter with two subfolders:
image-converter/
├─ input_images/ ← put your source files here
└─ output_images/ ← optimized JPGs will land here
🔥 The Script:
Create convert_images.py in image-converter/ and paste:
from PIL import Image
import os
import sys
# 1️⃣ Determine script’s own directory
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# 2️⃣ Define input/output folders
input_folder = os.path.join(BASE_DIR, 'input_images')
output_folder = os.path.join(BASE_DIR, 'output_images')
# 3️⃣ Sanity checks
if not os.path.isdir(input_folder):
print(f"❌ Input folder not found: {input_folder}")
sys.exit(1)
os.makedirs(output_folder, exist_ok=True)
# 4️⃣ Gather images
valid_exts = ('png', 'webp', 'jpeg', 'jpg', 'tiff', 'bmp')
files = [f for f in os.listdir(input_folder)
if f.lower().endswith(valid_exts)]
if not files:
print("❌ No images found in", input_folder)
sys.exit(1)
print(f"🔍 Found {len(files)} image(s):")
for f in files: print(" •", f)
# 5️⃣ Conversion loop
for fname in files:
src_path = os.path.join(input_folder, fname)
img = Image.open(src_path).convert('RGB') # ensure JPEG-compatible
base, _ = os.path.splitext(fname)
dst_path = os.path.join(output_folder, f"{base}.jpg")
# quality=85 is usually a sweet spot; optimize=True shrinks a bit more
img.save(dst_path, "JPEG", quality=85, optimize=True)
print(f"✅ Saved: {dst_path}")
print(f"\n🎉 Done! Converted & optimized {len(files)} files.")
🚀 How It Works
Absolute paths
We compute BASE_DIR so you can run the script from anywhere, and it will always locate the right folders.File filtering
We only pick files with common image extensions—even skips over stray text files or hidden folders.RGB conversion
JPEG doesn’t support alpha/transparency. Converting to RGB ensures no errors.-
Quality & optimization
- quality=85 retains visual fidelity with ~30–50% smaller size than 100.
- optimize=True applies an extra compression pass.
✅ Running It
Drop all your images into input_images/.
From the terminal (inside image-converter/):
python convert_images.py
Hope this saves you time and bandwidth. If you 💚 it, give it a clap, and drop any questions or improvements below!