Fri Jun 26 2026 20:00:00 GMT-0400 (北美东部夏令时间)
Comprimere Immagini in Python con Pillow, WebP e mozjpeg
Comprimi immagini JPEG, PNG e WebP in Python usando Pillow, cwebp e mozjpeg, con impostazioni di qualità, cicli di dimensione target e uno script batch veloce.

Ultimo aggiornamento: June 27, 2026
Hai una cartella di JPEG dimensionati per fotocamere, un passaggio di build che li invia agli utenti e un budget di peso della pagina che continua a esplodere. Comprimere questi file manualmente in un editor di immagini non è scalabile. Questa guida mostra esattamente il Python di cui hai bisogno per ridurre i file JPEG, PNG e WebP su un programma, in un job CI o all'interno di un gestore di upload.
Risposta rapida: come si comprimono le immagini con Python?
Apri l'immagine con Pillow e poi salvala con i giusti flag di formato. Per le foto, salva come JPEG con quality=80, optimize=True e progressive=True. Per i file moderni più piccoli, salva come WebP con quality=80, method=6. Per grafiche piatte e screenshot, mantieni PNG e passa optimize=True.
from PIL import Image
def compress_jpeg(src, dst, quality=80):
img = Image.open(src)
if img.mode in ("RGBA", "P"):
img = img.convert("RGB")
img.save(dst, "JPEG", quality=quality, optimize=True, progressive=True)
Quella funzione di quattro righe riduce già la maggior parte dei JPEG provenienti da telefoni e DSLR dal 40 al 70 percento. Il resto di questa guida aggiunge obiettivi di dimensione, WebP, mozjpeg e un runner batch in modo che tu possa puntarlo a una directory e allontanarti.
Cosa ti serve prima di iniziare?
Hai bisogno di Python 3.9 o successivo e Pillow, la forca mantenuta di PIL. Pillow gestisce JPEG, PNG e WebP direttamente su ogni piattaforma comune.
pip install Pillow
Per l'output più piccolo vorrai anche due encoder da riga di comando che Python può chiamare: cwebp da libwebp e cjpeg da mozjpeg.
brew install webp mozjpeg # macOS; Linux: apt install webp, build mozjpeg
Controlla lo scopo di ogni componente prima di scrivere codice:
- Pillow legge e scrive ogni formato ed esegue il ridimensionamento.
- cwebp produce i file WebP più compatti e espone maggiori opzioni di tuning rispetto a Pillow.
- mozjpeg ricodifica JPEG più piccoli dello standard libjpeg utilizzato da Pillow.
- Un helper di reporting in modo che ogni esecuzione stampi quanti byte sono stati risparmiati.
Ecco l'helper utilizzato in tutta questa guida:
import os
def report(src, dst):
before, after = os.path.getsize(src), os.path.getsize(dst)
saved = (1 - after / before) * 100
print(f"{before/1024:.0f} KB -> {after/1024:.0f} KB ({saved:.0f}% più piccolo)")
Se hai solo bisogno di una compressione occasionale e non vuoi installare nulla, il compressore di immagini basato su browser fa lo stesso lavoro per un piccolo numero di file.
Come comprimere un JPEG con Pillow?
I tre flag che contano per JPEG sono quality, optimize e progressive. quality controlla quanta attenzione l'encoder scarta. optimize=True esegue un secondo passaggio per costruire una tabella Huffman più piccola. progressive=True riordina il file in modo che venga dipinto dall'alto verso il basso a bassa risoluzione prima, cosa che sembra più veloce su connessioni lente e di solito riduce il file un po' di più.

Scegli un valore di qualità basandoti sul luogo in cui viene utilizzata l'immagine, non su un singolo numero globale:
| Valore di qualità | Utilizzo tipico | Cosa aspettarsi |
|---|---|---|
| 90-95 | Immagini eroiche, prove stampa | Vicino all'originale, file notevolmente più grandi |
| 75-85 | La maggior parte delle foto web | Il default sicuro, grandi risparmi |
| 60-70 | Miniature e anteprime | Ammorbidimento visibile nei dettagli fini |
| Sotto 50 | Evitare per le foto | Artefatti a blocchi sui bordi |
Un errore comune fa inciampare quasi tutti: JPEG non ha un canale alfa. Se apri uno screenshot PNG con trasparenza e lo salvi direttamente in JPEG, Pillow solleva cannot write mode RGBA as JPEG. La chiamata convert("RGB") nella funzione precedente appiattisce la trasparenza su uno sfondo solido per prima cosa, motivo per cui viene eseguita prima di ogni salvataggio JPEG.
Comprimere PNG e convertire in WebP
PNG è lossless, quindi non puoi scambiare qualità con dimensione come fai con JPEG. Quello che puoi fare è eseguire l'ottimizzatore di Pillow e, per qualsiasi cosa sia realmente una foto, cambiare completamente formato.
def compress_png(src, dst):
Image.open(src).save(dst, "PNG", optimize=True, compress_level=9)
def to_webp(src, dst, quality=80):
img = Image.open(src)
img.save(dst, "WEBP", quality=quality, method=6)
method=6 dice all'encoder WebP di dedicare più tempo alla ricerca di un file più piccolo. È più lento per immagine ma ne vale la pena in un passaggio di build. Per una foto che è partita come PNG da 2 MB, WebP a qualità 80 atterra regolarmente sotto i 200 KB mantenendo un aspetto identico a dimensioni normali di visualizzazione. Le misurazioni di Google pongono WebP circa dal 25 al 35 percento più piccolo rispetto a JPEG comparabile, come documentato in WebP documentation.
Usa questa tabella per scegliere un formato invece di indovinare:
| Contenuto sorgente | Miglior formato | Perché |
|---|---|---|
| Fotografia | WebP o JPEG | I gradienti lisci si comprimono bene in modo lossy |
| Logo, icona, UI piatta | PNG o WebP lossless | I bordi netti rimangono nitidi |
| Screenshot con testo | PNG o WebP lossless | Evita il testo sfocato dei passaggi lossy |
| Immagine che necessita di trasparenza | WebP o PNG | JPEG non può memorizzare un canale alfa |
Se stai ancora decidendo tra formati per un intero sito, la ripartizione in WebP vs JPEG vs PNG copre il supporto del browser e i compromessi più approfonditamente.
Raggiungere una dimensione file target in un ciclo
"Rendilo inferiore a 200 KB" è un requisito comune da strumenti email, marketplace e limiti di upload CMS. Non puoi scegliere un numero di qualità che raggiunga un obiettivo di byte al primo tentativo, perché la stessa qualità produce dimensioni molto diverse per una foto complessa rispetto a una piatta. Cicla dal livello di qualità più alto fino a quando non rientri nel limite:
def compress_to_target(src, dst, target_kb=200, q=90, floor=35):
img = Image.open(src).convert("RGB")
while q >= floor:
img.save(dst, "JPEG", quality=q, optimize=True, progressive=True)
if os.path.getsize(dst) <= target_kb * 1024:
return q
q -= 5
return q
L'argomento floor interrompe il ciclo prima che la qualità scenda nel territorio della sfocatura. Se un'immagine non può raggiungere l'obiettivo sopra il limite, la funzione restituisce comunque in modo che tu possa registrarlo e ridimensionare l'immagine invece di comprimere più duramente. Per budget di byte fissi come 100 KB o 50 KB, lo stesso ciclo funziona; la guida passo passo in compress images without losing quality spiega quando il ridimensionamento batte abbassare la qualità.
Come ridurre le dimensioni dei JPEG con mozjpeg e cwebp?
Pillow salva i JPEG con lo standard encoder libjpeg. mozjpeg è un encoder plug-in da Mozilla che produce file più piccoli alla stessa qualità visiva, di solito un ulteriore 5-15 percento. Poiché Pillow non lo include, chiama il binario cjpeg tramite subprocess. cjpeg di mozjpeg legge PPM in modo affidabile, quindi appiattisci l'immagine con Pillow per prima:
import subprocess
def mozjpeg(src, dst, quality=80):
Image.open(src).convert("RGB").save("_tmp.ppm")
subprocess.run(["cjpeg", "-quality", str(quality), "-progressive",
"-optimize", "-outfile", dst, "_tmp.ppm"], check=True)
os.remove("_tmp.ppm")
Per WebP, chiamare cwebp direttamente ti dà manopole che Pillow non espone, come -m 6 per lo sforzo massimo e -sharp_yuv per bordi colore più puliti:
def cwebp(src, dst, quality=82):
subprocess.run(["cwebp", "-q", str(quality), "-m", "6",
"-sharp_yuv", src, "-o", dst], check=True)
Ecco come si confrontano le opzioni in modo che tu possa decidere cosa installare:
| Strumento | Ideale per | Compromesso |
|---|---|---|
| Pillow | Scripting generale, ogni formato | Non è il JPEG più piccolo |
| mozjpeg | Il JPEG progressivo più piccolo | Binario extra, round-trip PPM |
| cwebp (libwebp) | Controllo WebP più stretto | Binario separato da installare |
| pillow-simd | Ridimensionamento più veloce su server x86 | Più difficile da costruire e vincolare |
Il progetto mozjpeg documenta il suo encoder e i benchmark in mozjpeg repository, e l'elenco completo delle opzioni di salvataggio di Pillow si trova in Pillow image file formats reference.
Come comprimere una cartella velocemente?
Un singolo immagine è facile. Il vero compito è una directory di centinaia. Ridimensiona tutto più largo del necessario per il tuo layout, poi comprime ed esegui il lavoro attraverso i thread in modo che una cartella da 500 immagini finisca in secondi anziché minuti.

from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
def batch(in_dir, out_dir, quality=80, max_width=1920):
out = Path(out_dir); out.mkdir(parents=True, exist_ok=True)
files = [p for p in Path(in_dir).iterdir()
if p.suffix.lower() in {".jpg", ".jpeg", ".png"}]
def work(p):
img = Image.open(p)
if img.width > max_width:
h = round(img.height * max_width / img.width)
img = img.resize((max_width, h), Image.LANCZOS)
img.convert("RGB").save(out / f"{p.stem}.jpg", "JPEG",
quality=quality, optimize=True, progressive=True)
with ThreadPoolExecutor() as pool:
list(pool.map(work, files))
return len(files)
Alcune note pratiche derivanti dall'esecuzione di questo in produzione:
- Ridimensiona prima di comprimere. Servire una foto da 6000 px per una colonna da 1200 px spreca byte che nessuna impostazione di qualità può recuperare.
- Pillow rilascia il GIL durante l'encoding, quindi i thread danno un vero aumento di velocità qui; non hai bisogno di multiprocessing per la maggior parte delle cartelle.
- Scrivi in una directory di output separata in modo che un fallimento non sovrascriva mai i tuoi originali.
- Usa
Image.LANCZOSper il downscaling; mantiene i bordi più nitidi del filtro predefinito. - Registra ogni file con l'helper
reporte conserva gli originali finché non hai esaminato un campione.
Se il tuo lavoro è ricorrente piuttosto che occasionale, i modelli in batch image processing coprono code, tentativi di ripristino e convenzioni di denominazione. Per un'esecuzione senza codice su uno zip di file, lo strumento batch e l'immagine converter gestiscono i cambiamenti di formato senza script.
Quale approccio dovresti scegliere?
Abbina il metodo al lavoro piuttosto che cercare sempre lo strumento più pesante:
- Foto web in un passaggio di build: Pillow WebP a qualità 80, o cwebp con
-m 6quando vuoi l'ultimo paio di percento. - Un budget di byte rigoroso: il ciclo
compress_to_target, che fa affidamento su un ridimensionamento quando viene raggiunto il limite. - Pipeline JPEG legacy che non puoi cambiare: ricodifica l'output con mozjpeg per risparmi gratuiti.
- Screenshot e diagrammi: mantieni PNG con
optimize=True, o WebP lossless se i tuoi browser lo supportano.
Per la teoria del perché queste impostazioni funzionino, image compression guide spiega lossy contro lossless e come le tabelle di quantizzazione influenzano il risultato.
Errori e correzioni comuni
Un piccolo numero di eccezioni account per la maggior parte dei fallimenti:
cannot write mode RGBA as JPEG— chiamaimg.convert("RGB")prima di salvare in JPEG.Image.DecompressionBombError— Pillow protegge contro immagini enormi; alza il limite solo per file che ti fidi conImage.MAX_IMAGE_PIXELS = 200_000_000.OSError: broken data stream— il file sorgente è troncato; impostaImageFile.LOAD_TRUNCATED_IMAGES = Trueper salvarlo, quindi riscarica quando possibile.- Output più grande dell'input — hai risalvato un JPEG già compresso; comprime dall'originale, non da un precedente export.
- I colori sembrano sbiaditi — una sorgente CMYK è stata salvata senza conversione; chiama
convert("RGB")prima.
from PIL import Image, ImageFile
Image.MAX_IMAGE_PIXELS = 200_000_000
ImageFile.LOAD_TRUNCATED_IMAGES = True

Punto chiave
Pillow gestisce il 90 percento della compressione di immagini in Python con tre flag JPEG e un salvataggio WebP. Rivolgiti a mozjpeg e cwebp quando hai bisogno dei file più piccoli possibili, racchiudi tutto nel ciclo target-size quando un budget di byte è fisso, ed esegui una cartella attraverso la funzione batch threadizzata quando il volume cresce. Conserva sempre gli originali, ridimensiona prima di comprimere e stampa i risparmi ad ogni esecuzione in modo da sapere sempre cosa sta facendo effettivamente il pipeline.
Usa gli strumenti gratuiti mentre segui la guida.
Continua a leggere

Wed Mar 18 2026 20:00:00 GMT-0400 (北美东部夏令时间)
Convertitore WebP: Come convertire immagini in WebP (con dimensioni reali)
Converti immagini JPEG e PNG in WebP per file web più piccoli. Dimensioni misurate reali, il comando cwebp, metodi con Python e browser, e una strategia di fallback JPEG/PNG.

Tue Mar 17 2026 20:00:00 GMT-0400 (北美东部夏令时间)
PNG a WebP: Come Convertire e Ridurre le Immagini PNG
Converti PNG in WebP per ottenere file web più piccoli. Scopri quando WebP lossless è superiore al lossy, confronta dimensioni reali e usa i comandi cwebp/Pillow con fallback PNG.

Tue Mar 10 2026 20:00:00 GMT-0400 (北美东部夏令时间)
Ottimizzazione SEO Immagini: Checklist pratica per il 2026
Una checklist pratica di SEO per immagini del 2026 che copre alt text, nomi dei file, formati, compressione, Core Web Vitals, structured data e misurazione.