Format gambar: GIF

Meskipun tidak terlalu berguna di web modern, GIF (Graphics Interchange Format) memberikan pengantar yang kuat tentang konsep inti encoding gambar.

GIF dapat dianggap sebagai wrapper untuk data gambar. Class ini memiliki area pandang, yang disebut "layar logis", tempat setiap frame data gambar digambar—mirip seperti lapisan di dokumen Photoshop. Begitulah cara GIF mendukung animasi yang menyerupai flipbook: satu frame digambar ke layar logis, lalu diganti dengan animasi lain, lalu frame lainnya. Tentu saja, perbedaan ini tidak penting saat kita menangani GIF statis, yang terdiri dari satu {i>frame<i} yang digambar ke layar logis.

GIF menggunakan metode kompresi data lossless—varian dari algoritma "Lempel–Ziv–Welch", jika Anda ingin tahu. Detail yang lebih detail tentang cara kerja algoritme ini lebih dari yang kita bahas di sini, tetapi pada dasarnya: cara kerjanya sedikit seperti "Mengakali" JavaScript, dengan string karakter berulang di seluruh file disimpan ke semacam kamus internal, sehingga dapat direferensikan, bukan diulang setiap kali muncul.

Visualisasi referensi gif menggunakan petak empat kali empat.

Memang, algoritmanya tidak sesederhana paint-by-number. Alat ini menelusuri tabel kode warna yang dihasilkan lagi untuk menemukan urutan warna piksel berulang dan membuat tabel kedua berisi kode yang dapat dirujuk. Data gambar akan hilang, tetapi—cukup diurutkan dan diatur ulang sedemikian rupa sehingga dapat dibaca tanpa mengubahnya secara mendasar.

Meskipun secara teknis menggunakan kompresi lossless, GIF memiliki keterbatasan utama yang berdampak buruk pada kualitas gambar: menyimpan gambar sebagai GIF akan selalu menghasilkan fidelitas yang berkurang, kecuali jika gambar sudah menggunakan 256 warna atau kurang.

Setiap bingkai yang digambar ke layar logis GIF hanya dapat berisi maksimal 256 warna. GIF juga mendukung "transparansi indeks", dengan piksel transparan akan mereferensikan indeks "warna" transparan dalam tabel warna.

Praktik mengurangi rentang nilai menjadi kumpulan nilai output yang lebih kecil dan mendekati disebut kuantisasi, istilah yang akan banyak Anda temui saat mempelajari encoding gambar. Hasil kuantisasi palet ini biasanya sudah jelas:

Contoh GIF statis

Untuk lebih memahami proses ini, pikirkan kembali ke petak gambar raster yang dapat Anda buat kembali dari deskripsi saya.

Tiga kotak biru horizontal diikuti oleh satu kotak merah

Kali ini, tambahkan detail sedikit ke gambar asli tersebut: beberapa piksel lagi, salah satunya adalah warna biru yang sedikit lebih gelap:

Kotak horizontal biru ke merah dalam konfigurasi dua kali empat, dengan satu kotak biru diarsir lebih gelap dari yang lain.

Tidak ada kompresi—dapat dikatakan—Anda dapat menggambarkan petak ini sebagai:

Baris satu, kolom satu adalah #0000FF. Baris satu, kolom dua adalah #0000FF. Baris satu, kolom tiga adalah #0000FF. Baris satu, kolom empat adalah #FF0000. Baris dua, kolom satu adalah #0000FF. Baris dua, kolom dua adalah #000085. Baris dua, kolom tiga adalah #0000FF. Baris dua, kolom empat adalah #FF0000.

Menggunakan sesuatu yang mirip dengan kompresi data lossless dan pengindeksan warna GIF, Anda mungkin menggambarkannya sebagai:

A: #0000FF, B: #FF0000, C: #000085. Baris satu, kolom satu sampai tiga adalah A. Baris satu, kolom empat adalah B. Baris dua, kolom satu adalah A. Baris dua, kolom dua adalah C. Baris dua, kolom tiga adalah A. Baris dua, kolom empat adalah B.

Kode ini berhasil meringkas deskripsi piksel demi piksel di beberapa tempat (“kolom satu sampai tiga adalah...”), dan menyimpan beberapa karakter dengan menentukan warna berulang dalam kamus, semacamnya, di awal. Tidak ada perubahan pada fidelitas visual. Informasi telah dikompresi tanpa kehilangan data.

Kotak horizontal berwarna biru ke merah, dengan satu piksel gelap berukuran 2x2.

Namun, seperti yang dapat Anda lihat, satu piksel biru tua memiliki dampak yang besar terhadap ukuran encoding. Jika saya membatasi diri saya pada palet warna terkuantifikasi, itu bisa dikurangi lebih jauh:

A: #0000FF, B: #FF0000. Baris satu, kolom satu sampai tiga adalah A. Baris satu, kolom empat adalah B. Baris dua, kolom satu sampai tiga adalah A. Baris dua, kolom empat adalah B.

Hasil akhir yang tidak diinginkan dari byte yang disimpan tersebut adalah Anda kehilangan kesempurnaan piksel.

Kotak horizontal berwarna biru ke merah secara seragam.

Tentu saja, Anda, sebagai mesin rendering, tidak tahu hal itu—detail piksel biru yang lebih gelap tertinggal dari cara saya mengenkode gambar sumber. Anda telah merender gambar persis seperti yang saya enkode, berdasarkan pemahaman bersama tentang warna yang kita miliki.

Sekarang, dalam contoh yang berlebihan ini, mengurangi tiga warna menjadi dua membuat perbedaan yang jelas dalam kualitas. Di gambar yang lebih besar dan lebih mendetail, efeknya mungkin tidak terlalu terlihat, tetapi masih akan terlihat.

Saat dienkode sebagai GIF, gradien halus seperti bayangan menjadi berbintik-bintik, dengan piksel individual yang menonjol dari sekelilingnya:

Bunga merah muda dengan latar belakang hijau.

Dalam praktiknya, kombinasi kompresi lossless dan kuantisasi palet berarti bahwa GIF tidak terlalu berguna dalam pengembangan web modern. Kompresi lossless tidak cukup untuk mengurangi ukuran file, dan pengurangan palet berarti pengurangan kualitas yang jelas.

Pada akhirnya, GIF hanyalah format yang efisien untuk mengenkode gambar sederhana yang sudah menggunakan palet warna terbatas, tepi keras bukan anti-aliasing, dan warna solid bukan gradien—semua kasus penggunaan yang jauh lebih baik dilayani oleh format lain. PNG yang lebih kecil dan lebih unggulan sering kali menjadi pilihan yang lebih baik untuk gambar raster, meskipun keduanya jauh lebih rendah daripada SVG dalam hal ukuran file dan fidelitas visual untuk kasus penggunaan seperti ikon atau seni garis, dengan vektor yang menonjol. Kasus penggunaan modern yang paling umum dilihat untuk GIF adalah animasi, tetapi ada format video yang jauh lebih efisien—dan mudah diakses—modern untuk memenuhi tujuan tersebut.