Fri Jun 26 2026 20:00:00 GMT-0400 (北美东部夏令时间)
Kompres Gambar di Python dengan Pillow, WebP, dan mozjpeg
Kompres gambar JPEG, PNG, dan WebP di Python menggunakan Pillow, cwebp, dan mozjpeg. Fitur mencakup pengaturan kualitas, loop ukuran target, dan skrip batch yang sangat cepat.

Terakhir diperbarui: June 27, 2026
Anda memiliki folder JPEG berukuran kamera, langkah build yang mengirimkannya ke pengguna, dan anggaran berat halaman yang terus membengkak. Mengompres file-file tersebut secara manual di editor gambar tidak skalabel. Panduan ini menunjukkan Python persis yang Anda butuhkan untuk mengecilkan file JPEG, PNG, dan WebP sesuai jadwal, dalam pekerjaan CI, atau di dalam upload handler.
Jawaban cepat: bagaimana cara mengompres gambar di Python?
Buka gambar dengan Pillow, lalu simpan dengan flag format yang tepat. Untuk foto, simpan sebagai JPEG dengan quality=80, optimize=True, dan progressive=True. Untuk file modern terkecil, simpan sebagai WebP dengan quality=80, method=6. Untuk grafik datar dan tangkapan layar, pertahankan PNG dan berikan 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)
Fungsi empat baris itu sudah memotong sebagian besar JPEG ponsel dan DSLR sebesar 40 hingga 70 persen. Sisa dari panduan ini menambahkan target ukuran, WebP, mozjpeg, dan batch runner sehingga Anda dapat mengarahkannya ke sebuah direktori dan meninggalkannya bekerja.
Apa yang Anda butuhkan sebelum memulai?
Anda membutuhkan Python 3.9 atau lebih baru dan Pillow, fork yang dikelola dari PIL. Pillow menangani JPEG, PNG, dan WebP secara bawaan pada setiap platform umum.
pip install Pillow
Untuk output terkecil, Anda juga akan menginginkan dua encoder baris perintah yang dapat dipanggil oleh Python: cwebp dari libwebp dan cjpeg dari mozjpeg.
brew install webp mozjpeg # macOS; Linux: apt install webp, build mozjpeg
Periksa fungsi setiap bagian sebelum Anda menulis kode:
- Pillow membaca dan menulis setiap format serta melakukan resizing.
- cwebp menghasilkan file WebP paling ketat dan mengekspos lebih banyak penyesuaian daripada Pillow.
- mozjpeg meng-encode ulang JPEG yang lebih kecil dari standar libjpeg yang digunakan Pillow.
- Helper pelaporan agar setiap eksekusi mencetak berapa banyak byte yang Anda hemat.
Berikut adalah helper yang digunakan di seluruh panduan ini:
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}% lebih kecil)")
Jika Anda hanya membutuhkan kompresi sekali pakai dan tidak ingin menginstal apa pun, kompresor gambar berbasis browser melakukan pekerjaan yang sama untuk sejumlah file.
Bagaimana cara mengompres JPEG dengan Pillow?
Tiga flag yang penting untuk JPEG adalah quality, optimize, dan progressive. quality mengontrol berapa banyak detail yang dibuang oleh encoder. optimize=True menjalankan lintasan kedua untuk membangun tabel Huffman yang lebih kecil. progressive=True menyusun ulang file sehingga dicetak dari atas ke bawah pada resolusi rendah terlebih dahulu, yang terasa lebih cepat di koneksi lambat dan biasanya mengecilkan file sedikit lebih banyak.

Pilih nilai kualitas berdasarkan tempat gambar digunakan, bukan satu angka global:
| Nilai Kualitas | Penggunaan Umum | Yang diharapkan |
|---|---|---|
| 90-95 | Gambar hero, bukti cetak | Mendekati asli, file yang terlihat lebih besar |
| 75-85 | Sebagian besar foto web | Default aman, penghematan besar |
| 60-70 | Thumbnail dan pratinjau | Kelembutan yang terlihat pada detail halus |
| Di bawah 50 | Hindari untuk foto | Artefak kotak di sekitar tepi |
Satu jebakan yang menjebak hampir semua orang: JPEG tidak memiliki alpha channel. Jika Anda membuka tangkapan layar PNG dengan transparansi dan menyimpannya langsung ke JPEG, Pillow akan menampilkan cannot write mode RGBA as JPEG. Panggilan convert("RGB") dalam fungsi sebelumnya meratakan transparansi ke latar belakang solid terlebih dahulu, itulah sebabnya ia dijalankan sebelum setiap penyimpanan JPEG.
Mengompres PNG dan mengonversi ke WebP
PNG adalah lossless, jadi Anda tidak bisa menukar kualitas dengan ukuran seperti yang Anda lakukan dengan JPEG. Yang dapat Anda lakukan adalah menjalankan pengoptimal Pillow dan, untuk apa pun yang benar-benar foto, mengganti formatnya sepenuhnya.
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 memberi tahu encoder WebP untuk menghabiskan lebih banyak waktu mencari file yang lebih kecil. Ini lebih lambat per gambar tetapi sepadan dalam langkah build. Untuk foto yang awalnya berukuran 2 MB PNG, WebP pada kualitas 80 secara rutin berada di bawah 200 KB sambil terlihat identik pada ukuran tampilan normal. Pengukuran Google sendiri menempatkan WebP sekitar 25 hingga 35 persen lebih kecil dari JPEG sebanding, menurut dokumentasi WebP.
Gunakan tabel ini untuk memilih format alih-alih menebak:
| Konten Sumber | Format Terbaik | Mengapa |
|---|---|---|
| Foto | WebP atau JPEG | Gradien halus terkompresi dengan baik secara lossy |
| Logo, ikon, UI datar | PNG atau WebP lossless | Tepi tajam tetap renyah |
| Tangkapan layar dengan teks | PNG atau WebP lossless | Menghindari teks buram dari proses lossy |
| Gambar yang membutuhkan transparansi | WebP atau PNG | JPEG tidak dapat menyimpan alpha channel |
Jika Anda masih memutuskan antara format untuk seluruh situs, rincian di WebP vs JPEG vs PNG mencakup dukungan browser dan pertukaran dalam lebih banyak kedalaman.
Mencapai ukuran file target dalam perulangan
"Buat kurang dari 200 KB" adalah persyaratan umum dari alat email, marketplace, dan batas unggahan CMS. Anda tidak dapat memilih angka kualitas yang mencapai target byte pada percobaan pertama, karena kualitas yang sama menghasilkan ukuran yang sangat berbeda untuk foto sibuk versus foto datar. Lakukan perulangan menurun dari kualitas tinggi sampai Anda berada di bawah batas:
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
Argumen floor menghentikan perulangan sebelum kualitas turun ke wilayah buram. Jika sebuah gambar tidak dapat mencapai target di atas batas, fungsi ini tetap kembali sehingga Anda dapat mencatatnya dan mengubah ukuran gambar alih-alih mengompres lebih keras. Untuk anggaran byte tetap seperti 100 KB atau 50 KB, perulangan yang sama berfungsi; panduan langkah demi langkah di mengompres gambar tanpa kehilangan kualitas menjelaskan kapan resizing mengalahkan menurunkan kualitas.
Bagaimana cara mengecilkan JPEG dengan mozjpeg dan cwebp?
Pillow menyimpan JPEG dengan encoder libjpeg standar. mozjpeg adalah encoder drop-in dari Mozilla yang menghasilkan file lebih kecil pada kualitas visual yang sama, biasanya 5 hingga 15 persen lebih jauh. Karena Pillow tidak membundelnya, panggil biner cjpeg melalui subprocess. cjpeg milik mozjpeg membaca PPM dengan andal, jadi ratakan gambar dengan Pillow terlebih dahulu:
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")
Untuk WebP, memanggil cwebp secara langsung memberi Anda kenop yang tidak diekspos oleh Pillow, seperti -m 6 untuk upaya maksimum dan -sharp_yuv untuk tepi warna yang lebih bersih:
def cwebp(src, dst, quality=82):
subprocess.run(["cwebp", "-q", str(quality), "-m", "6",
"-sharp_yuv", src, "-o", dst], check=True)
Berikut adalah perbandingan opsi sehingga Anda dapat memutuskan apa yang harus diinstal:
| Alat | Terbaik untuk | Pertukaran (Trade-off) |
|---|---|---|
| Pillow | Skrip umum, setiap format | Bukan JPEG terkecil |
| mozjpeg | JPEG progresif terkecil | Biner tambahan, round-trip PPM |
| cwebp (libwebp) | Kontrol WebP paling ketat | Biner terpisah untuk diinstal |
| pillow-simd | Resizing lebih cepat pada server x86 | Lebih sulit dibangun dan dipin |
Proyek mozjpeg mendokumentasikan encoder dan benchmark-nya di repositori mozjpeg, dan daftar lengkap opsi simpan Pillow hidup di referensi format file gambar Pillow.
Bagaimana cara mengompres folder secara massal dengan cepat?
Satu gambar itu mudah. Tugas sebenarnya adalah direktori berisi ratusan gambar. Ubah ukuran apa pun yang lebih lebar dari kebutuhan tata letak Anda, lalu kompres, dan jalankan pekerjaan di seluruh thread sehingga folder 500 gambar selesai dalam hitungan detik alih-alih menit.

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)
Beberapa catatan praktis dari menjalankan ini dalam produksi:
- Ubah ukuran sebelum Anda mengompres. Menyajikan foto 6000 px ke kolom 1200 px membuang byte yang tidak dapat dipulihkan oleh pengaturan kualitas apa pun.
- Pillow melepaskan GIL selama encode, jadi thread memberikan peningkatan kecepatan nyata di sini; Anda tidak memerlukan multiprocessing untuk sebagian besar folder.
- Tulis ke direktori output terpisah sehingga eksekusi buruk tidak pernah menimpa aslinya.
- Gunakan
Image.LANCZOSuntuk downscaling; ini menjaga tepi lebih tajam daripada filter default. - Catat setiap file dengan helper
reportdan simpan yang asli sampai Anda melihat sampelnya.
Jika pekerjaan Anda berulang daripada sekali pakai, pola dalam pemrosesan gambar batch mencakup antrian, coba ulang, dan konvensi penamaan. Untuk lari tanpa kode di atas zip file, alat batch dan konverter gambar menangani perubahan format tanpa skrip.
Pendekatan mana yang harus Anda pilih?
Cocokkan metode dengan pekerjaan daripada selalu mencari alat terberat:
- Foto web dalam langkah build: Pillow WebP pada kualitas 80, atau cwebp dengan
-m 6saat Anda menginginkan persentase terakhir. - Anggaran byte ketat: perulangan
compress_to_target, jatuh kembali ke resize ketika batas tercapai. - Pipeline JPEG lama yang tidak dapat Anda ubah: re-encode output dengan mozjpeg untuk penghematan gratis.
- Tangkapan layar dan diagram: pertahankan PNG dengan
optimize=True, atau WebP lossless jika browser Anda mendukungnya.
Untuk teori di balik mengapa pengaturan ini berfungsi, panduan kompresi gambar menjelaskan lossy versus lossless dan bagaimana tabel kuantisasi memengaruhi hasilnya.
Kesalahan umum dan perbaikan
Segelintir pengecualian menyumbang sebagian besar eksekusi yang gagal:
cannot write mode RGBA as JPEG— panggilimg.convert("RGB")sebelum menyimpan ke JPEG.Image.DecompressionBombError— Pillow melindungi dari gambar besar; tingkatkan batas hanya untuk file yang Anda percayai denganImage.MAX_IMAGE_PIXELS = 200_000_000.OSError: broken data stream— file sumber terpotong; aturImageFile.LOAD_TRUNCATED_IMAGES = Trueuntuk menyelamatkannya, lalu unduh ulang jika memungkinkan.- Output lebih besar dari input — Anda menyimpan ulang JPEG yang sudah dikompresi; kompres dari aslinya, bukan ekspor sebelumnya.
- Warna terlihat pudar — sumber CMYK disimpan tanpa konversi; panggil
convert("RGB")terlebih dahulu.
from PIL import Image, ImageFile
Image.MAX_IMAGE_PIXELS = 200_000_000
ImageFile.LOAD_TRUNCATED_IMAGES = True

Kesimpulan utama
Pillow menangani 90 persen kompresi gambar di Python dengan tiga flag JPEG dan penyimpanan WebP. Cari mozjpeg dan cwebp saat Anda membutuhkan file sekecil mungkin, bungkus semuanya dalam perulangan ukuran target ketika anggaran byte tetap, dan jalankan folder melalui fungsi batch ber-thread ketika volumenya bertambah. Simpan aslinya, ubah ukuran sebelum Anda mengompres, dan cetak penghematan pada setiap eksekusi sehingga Anda selalu tahu apa yang sebenarnya dilakukan pipeline.
Gunakan alat gratis sambil mengikuti panduan.
Lanjutkan membaca

Wed Mar 18 2026 20:00:00 GMT-0400 (北美东部夏令时间)
WebP Converter: Cara Mengubah Gambar ke WebP (Dengan Ukuran Asli)
Ubah gambar JPEG dan PNG menjadi WebP untuk file web yang lebih kecil. Kami membahas ukuran terukur nyata, perintah cwebp, metode Python dan peramban (browser), serta strategi fallback JPEG/PNG.

Tue Mar 17 2026 20:00:00 GMT-0400 (北美东部夏令时间)
PNG ke WebP: Cara Mengubah dan Mengecilkan Gambar PNG
Ubah PNG ke WebP untuk file web yang lebih kecil. Kami membahas kapan WebP lossless unggul dan kapan lossy efektif, ukuran terukur nyata, serta perintah cwebp dan Pillow dengan fallback PNG.

Tue Mar 10 2026 20:00:00 GMT-0400 (北美东部夏令时间)
Optimasi SEO Gambar: Daftar Periksa Praktis 2026
Daftar periksa SEO gambar praktis untuk 2026: alt text, nama file, format, kompresi, Core Web Vitals, structured data, dan pengukuran.