Panggilan Tengah Malam: Pangkas PDF 983MB Jadi 48MB

Dapat permintaan darurat tengah malam untuk mengecilkan PDF katalog produk 983MB supaya bisa dibuka di HP. Tool online nggak aman, Stirling PDF error, Ghostscript menghancurkan kualitas. Jadi saya bangun pipeline Python sendiri: capture tiap halaman, crop, optimasi ke resolusi mobile, lalu gabungkan ulang. Lima ronde iterasi kemudian: 983MB → 48MB. 95.1% lebih kecil. 329 halaman. Warna utuh. Teks terbaca. Selesai jam 1 pagi.

· 5 mnt baca

Tengah malam. HP bergetar.

Permintaan darurat:

"PDF ini 983MB. Harus lebih kecil. Jauh lebih kecil. Aku udah angkat tangan, buka filenya aja gabisa."

The File

983 megabyte.
Sebuah dokumen.
Yang harus dibuka di HP.
Pakai data seluler.

Tantangan diterima.

Masalahnya

PDF ini adalah katalog produk setebal 329 halaman. Isinya campuran teks, foto produk, dan gambar detail teknis. Hampir satu gigabyte halaman tanpa kompresi berarti.

Dibuka di HP? Nyaris mustahil.
Dikirim lewat WhatsApp untuk disebarluaskan? udah pasti gagal.

Percobaan yang Gagal

Langkah pertama tentu coba cara-cara standar.

PDF optimizer online? Nggak mungkin. Upload file 983MB ke website asing itu selain berisiko, kemungkinan besar juga bakal timeout di tengah jalan.

Beberapa tool yang sempat dicoba:

  • Stirling PDF, toolkit PDF self-hosted andalan saya. Ini yang pertama dicoba. Sayangnya selalu error. File segede ini bikin prosesnya mati setiap kali jalan.

  • Ghostscript, si jagoan command-line yang biasanya bisa diandalkan. Ukuran memang turun drastis, tapi kualitas ikut ambruk. Teks jadi buram, foto jadi lembek. Buat katalog produk yang harus terbaca spesifikasi dan detail gambarnya, ini nggak bisa diterima.

Di titik ini jelas satu hal: ini bukan soal main slider kompresi.

Masalahnya ada di struktur dokumennya. Dan solusinya bukan memperkecil PDF, tapi membongkarnya lalu membangun ulang dari nol.

Strateginya: Jangan Kompres PDF, Bangun Ulang Isinya

Pendekatan umum biasanya mengonversi PDF ke gambar pakai pdf2image atau Poppler. Tapi katalog ini besar bukan karena isinya ribet, melainkan karena:

  • embedded font berlapis-lapis
  • vektor kompleks
  • aset resolusi tinggi yang saling tumpang tindih

Konversi langsung cuma akan memindahkan semua beban itu ke gambar hasil output.

Yang sebenarnya saya butuhkan adalah hasil render akhir. Persis seperti yang terlihat di layar. Sudah di-flatten. Tanpa layer tersembunyi. Tanpa vektor berlebihan.

Dan siapa yang sudah melakukan semua kerja berat itu?

PDF viewer.

PDF viewer sudah menggabungkan semua layer jadi satu tampilan raster di resolusi layar. Saya tinggal menangkap hasilnya.

Maka strateginya dipecah jadi langkah sederhana:

  1. Capture tiap halaman langsung dari PDF viewer
  2. Crop hanya area konten
  3. Optimasi gambar seagresif mungkin
  4. Export sebagai aset ringan untuk layar HP

Saya bikin script Python:

  • mss untuk screenshot super cepat
  • OpenCV untuk memilih area crop sekali saja
  • keyboard untuk otomatis pindah halaman

Workflow-nya simpel: pilih area sekali, tekan Enter, lalu script akan loop semua halaman. Screenshot, crop, simpan, lanjut ke halaman berikutnya. Tekan Esc kalau sudah selesai.

329 halaman tercapture dalam hitungan menit.

Hasil mentahnya?
300.29 MB dalam bentuk PNG.

Masih terlalu besar. Saatnya perang kompresi.

Ronde 1: Pendekatan Aman

"Jangan sampai rusak."

Mulai dari pendekatan konservatif. Fokus jaga kualitas.

Strateginya:

  • Coba WebP lossy, WebP lossless, dan PNG teroptimasi
  • Simpan format dengan ukuran paling kecil untuk tiap gambar
  • Tidak ada resize

Setting utama:

  • WebP quality 88
  • Resolusi asli
  • Auto-pick format terbaik per halaman

Hasilnya:
Hasil 1

Total:  300.29 MB → 68.13 MB  (77.3% lebih kecil)

68MB. Lumayan. Tapi masih berat buat HP.
Dan prosesnya lambat, hampir 10 menit karena masih single-thread.

Ronde 2: Mulai Agresif

"HP nggak butuh halaman 4K."

Sekarang mulai realistis. Tambahkan downscale dan paralelisme.

  • WebP quality 55
  • Maksimal 1440px di sisi terpanjang
  • Sedikit sharpen supaya teks tetap jelas
  • 8 thread paralel

Hasil:
Hasil 2

Total:  300.29 MB → 43.57 MB  (85.5% lebih kecil)
Time:   16.6s (19.8 gambar/detik)

43MB. Sudah jauh lebih masuk akal. Tapi rasanya masih bisa diperas.

Ronde 3: Peras Maksimal

"Seberapa kecil bisa?"

Saatnya buka semua jurus.

  • WebP quality 35
  • Maksimal 1080px
  • Gaussian blur ringan (radius 0.5) untuk meredam noise sebelum kompresi
  • Color quantization ke 256 warna
  • 14 thread

Hasilnya:
Hasil 3

Total:  300.29 MB → 15.22 MB  (94.9% lebih kecil)
Time:   10.4s (31.5 gambar/detik)

15MB. Gila kecilnya.
Tapi ada harga yang harus dibayar. Warna jadi pudar. Foto produk kehilangan karakter. Buat katalog, ini masalah.

Ronde 4: Warna Penuh, Ukuran Sama

"Balikin warnanya. Buang quantization."

Ternyata quantization yang paling merusak visual, tapi kontribusinya ke ukuran file hampir nol.

Maka setting-nya:

  • WebP quality 35
  • Maksimal 1080px
  • Gaussian blur ringan
  • Warna penuh, tanpa quantization

Hasil:
Hasil 4

Total:  300.29 MB → 15.16 MB  (95.0% lebih kecil)
Time:   5.6s (59.2 gambar/detik)

15.16MB.
Ukurannya hampir sama, tapi warna kembali hidup.

Masalahnya tinggal satu: teks kecil masih sedikit buram.

Ronde 5: Titik Manis

"Naikkan detail teks, dikit aja."

Final tweak.

  • WebP quality 45
  • Maksimal 1080px
  • Ganti Gaussian blur dengan UnsharpMask
  • 14 thread

Hasil akhir:
Hasil 5

Total:  300.29 MB → 25.64 MB  (91.5% lebih kecil)
Time:   6.2s (52.6 gambar/detik)

25.64MB.
Teks tajam. Foto tetap natural. Nyaman dibaca di HP.

Satu masalah tersisa.

Mereka minta PDF, bukan folder gambar.

Langkah Terakhir: Balik Jadi PDF

"Gambarnya sudah oke. Bisa dijadiin PDF lagi?"

Bisa.

Script terakhir:

  • Load 329 gambar WebP hasil optimasi
  • Naikkan brightness 15 persen karena di layar HP hasilnya agak gelap
  • Natural numeric sort supaya halaman 2 tidak nyasar ke belakang halaman 19
  • Gabungkan jadi satu PDF

Run pertama:

D:\katalog program\python>python images_to_pdf.py
Loading 329 image(s) from 'optimized5/'...
Done! Saved 'output.pdf' 47.74 MB, 329 page(s).

Sedikit tweak di curve brightness, jalankan ulang:

D:\katalog program\python>python images_to_pdf.py
Loading 329 image(s) from 'optimized5/'...
Done! Saved 'output.pdf' 46.94 MB, 329 page(s).

46.94MB.

PDF utuh.
329 halaman.
Warna penuh.
Teks terbaca jelas.
Siap dibuka di HP.

Skor Akhir

Tahap Ukuran Pengurangan
PDF asli 983 MB -
Capture mentah (PNG) 300.29 MB 69.4%
Ronde 1, aman 68.13 MB 93.1%
Ronde 2, downscale 43.57 MB 95.6%
Ronde 3, maksimal 15.22 MB 98.5%
Ronde 4, warna penuh 15.16 MB 98.5%
Ronde 5, titik manis 25.64 MB 97.4%
PDF final ~48 MB 95.1%

Dari 983MB ke 48MB. Potong 95.1%.

Result

Perbandingan langsung. Asli di kiri, hasil optimasi di kanan:

Original vs Optimized berdampingan

Kelihatan bedanya.
Dan ingat, itu 95 persen lebih kecil.

Ukuran PDF memang sedikit lebih besar dari folder WebP mentah karena PDF punya kompresi internal sendiri untuk gambar embedded. Tapi 48MB untuk katalog 329 halaman itu langsung kebuka di HP manapun, tanpa mikir.

Seluruh pipeline, dari capture, 5 ronde tuning, koreksi brightness, sampai assembly PDF, selesai kurang dari 10 detik dengan 14 thread.

Yang Saya Pelajari

  1. Jangan melawan formatnya. Kalau PDF sudah kebablasan, bongkar isinya dan bangun ulang.
  2. WebP itu monster. Quality 45 masih kelihatan lebih bagus dari JPEG quality 80 dengan ukuran jauh lebih kecil.
  3. Downscaling menang paling besar. Turunin resolusi ke 1080px lebih berdampak daripada main slider quality.
  4. Color quantization overrated. Untuk konten foto, pengaruh ke ukuran kecil tapi merusak visual.
  5. UnsharpMask jauh lebih pintar. Bisa tajamin teks tanpa bikin foto jadi kasar.
  6. Threading itu kecepatan gratis. Semua gambar independen. Dari satu menit jadi hitungan detik.
  7. Natural sort itu wajib. page_2 harus sebelum page_10. Jangan percaya sort alfabet.
  8. Brightness penting di akhir. Sedikit boost bikin halaman kelihatan bersih di layar HP.

Tools yang Dipakai

Semua Python. Lokal. Tanpa cloud.

  • mss untuk screenshot multi-monitor
  • Pillow untuk crop, resize, sharpen, brightness, dan PDF assembly
  • OpenCV buat seleksi area interaktif
  • keyboard buat hotkey dan auto page flip
  • ThreadPoolExecutor buat paralelisme

Tanpa API berbayar. Tanpa upload ke mana-mana. Cuma Python dan deadline tengah malam.

Selanjutnya: Bawa ke Browser

Script Python ini powerful, tapi jelas bukan buat semua orang. Langkah berikutnya adalah membawa pipeline ini ke browser.

Visinya:

  • Tool berbasis WebAssembly dan PDF.js
  • Semua proses lokal di browser, file tidak pernah keluar
  • Drag and drop, tanpa setup
  • Tanpa Python, tanpa terminal
  • Kalau browser bisa jalan, file segede apa pun bisa dikecilkan

Jam 1 pagi, HP bergetar lagi:

"Udah diterima. Jauh banget di luar ekspektasi. Makasih banyak."

983MB ke 48MB.
Enam script Python.
Satu tengah malam.

Worth it.

Muktiadi Akhmad Januar

Muktiadi Akhmad Januar

IT Architect · Digital Transformation · Human-First

Menghubungkan visi bisnis dengan eksekusi teknis — mulai dari enterprise architecture, data strategy, hingga embedded systems.

Suka artikel ini?

Jika bermanfaat, bagikan ke rekan dan kolega Anda.