Big photos are slowing down your website
A modern phone camera saves photos at 4000 to 8000 pixels wide, and a single uncompressed shot can weigh 5 to 15 megabytes. Put three of those on a blog page and most visitors on mobile data will give up before the page finishes loading. The fix is simple: resize images to the size they actually display at, and compress them before uploading. You can do both in seconds with free, open-source Python — no Photoshop subscription required.
Step 1: Install Pillow
Pillow is the maintained fork of the classic Python Imaging Library (PIL), and it does all the heavy lifting here: opening photos, resizing them, and re-saving them at a smaller file size. Install it with one command:
pip install Pillow
That is the only dependency. No accounts, no trials, no credit card.
Step 2: Shrink a single photo
The core trick is the thumbnail() method: it caps the longest side of an image at a maximum size while keeping the original aspect ratio, so nothing looks stretched. Pair it with the quality setting when saving, and a 6 MB original can drop under 300 KB with no visible difference on a screen:
from PIL import Image
img = Image.open("photo.jpg")
# Cap the long edge at 1600 px; aspect ratio is preserved
img.thumbnail((1600, 1600), Image.LANCZOS)
# Save a web-friendly copy: quality 80 is the sweet spot for photos
img.save("photo-web.jpg", optimize=True, quality=80)
A couple of details worth knowing. Image.LANCZOS is the highest-quality resampling filter Pillow offers, so downscaled images stay sharp. And 1600 pixels is plenty for anything displayed on a website or shared by email — most screens never show an image wider than that anyway.
Step 3: Process a whole folder at once
Doing this one photo at a time defeats the purpose. Here is a small script that loops over every image in a folder, resizes each one, and writes compressed copies into a separate output folder. Your originals stay untouched:
from pathlib import Path
from PIL import Image
SOURCE = Path("photos") # put your originals here
OUTPUT = Path("photos-web") # compressed copies land here
OUTPUT.mkdir(exist_ok=True)
MAX_SIZE = (1600, 1600) # cap the long edge
QUALITY = 80
for path in SOURCE.iterdir():
if path.suffix.lower() not in {".jpg", ".jpeg", ".png", ".webp"}:
continue
with Image.open(path) as img:
img.thumbnail(MAX_SIZE, Image.LANCZOS)
target = OUTPUT / f"{path.stem}-web.jpg"
img.convert("RGB").save(target, optimize=True, quality=QUALITY)
print(f"{path.name} -> {target.name}")
Run it with python shrink.py and watch it chew through hundreds of photos in seconds. The .convert("RGB") call matters if your folder includes PNGs with transparency, since JPEG has no alpha channel — without it, saving would fail on transparent images.
Step 4 (optional): Try the WebP format
If you want even smaller files, save as WebP instead of JPEG. WebP is supported by every modern browser and typically produces files 25 to 35 percent smaller than JPEG at the same visual quality. The change is one line:
from PIL import Image
img = Image.open("photo.jpg")
img.thumbnail((1600, 1600), Image.LANCZOS)
img.save("photo-web.webp", quality=80, method=6)
print("Saved photo-web.webp")
The method=6 option just asks the encoder to spend a little more time squeezing the file smaller — worth it when the script runs unattended.
Quick rules of thumb
- Never overwrite your originals. Always write compressed copies to a separate folder, exactly like the script above does.
- Match the size to the use. Blog post images rarely need more than 1200–1600 px; thumbnails get by with 600–800 px.
- Quality 75–85 is the safe zone for JPEG photos. Below 70, you start seeing blocky artifacts in skies and skin tones.
- Photographs compress well; screenshots and logos often don't as JPEG. Keep graphics with text or flat colors as PNG.
- Test before you bulk-run. Try the script on three or four photos first, zoom in, and confirm the quality before pointing it at your whole library.
The takeaway
Resizing and compressing images is one of those chores that feels tedious by hand but is trivial once automated. With about twenty lines of Python and the free Pillow library, you get a repeatable workflow that keeps your website fast, your emails light, and your phone storage from filling up — and it works the same on Windows, Mac, and Linux. Save the script somewhere handy; you will reach for it more often than you think.
📘 Know Someone Who Finds Tech Confusing?
Tech Made Simple for Seniors is our plain-English ebook that explains smartphones, the internet, and everyday tech with zero jargon — perfect for parents and grandparents.
Get the ebook here — use code LAUNCH at checkout and get it for $12 (reg. $19).

Comments
Post a Comment