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.

Kompres Gambar di Python dengan Pillow, WebP, dan mozjpeg

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.

Laptop di meja kayu menunjukkan kode sumber yang terbuka dalam editor

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.

Pengembang di stasiun kerja multi-monitor menjalankan kode sambil mengenakan headphone

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:

  1. Ubah ukuran sebelum Anda mengompres. Menyajikan foto 6000 px ke kolom 1200 px membuang byte yang tidak dapat dipulihkan oleh pengaturan kualitas apa pun.
  2. Pillow melepaskan GIL selama encode, jadi thread memberikan peningkatan kecepatan nyata di sini; Anda tidak memerlukan multiprocessing untuk sebagian besar folder.
  3. Tulis ke direktori output terpisah sehingga eksekusi buruk tidak pernah menimpa aslinya.
  4. Gunakan Image.LANCZOS untuk downscaling; ini menjaga tepi lebih tajam daripada filter default.
  5. Catat setiap file dengan helper report dan 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 6 saat 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 — panggil img.convert("RGB") sebelum menyimpan ke JPEG.
  • Image.DecompressionBombError — Pillow melindungi dari gambar besar; tingkatkan batas hanya untuk file yang Anda percayai dengan Image.MAX_IMAGE_PIXELS = 200_000_000.
  • OSError: broken data stream — file sumber terpotong; atur ImageFile.LOAD_TRUNCATED_IMAGES = True untuk 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

Gambar close-up detail dari python yang beristirahat di permukaan berlubang.

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.

Gambar sampul untuk PNG ke WebP: Cara Mengubah dan Mengecilkan Gambar 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.

Gambar sampul untuk Optimasi SEO Gambar: Daftar Periksa Praktis 2026

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.