Gambar seperti kotak - apa yang ada di dalamnya? Laporkan dalam Yandex

Gambar dan video adalah "kotak hitam", di dalamnya ada banyak hal yang menarik dan tidak bisa dipahami. Tetapi Anda dapat melihat ke dalam beberapa format, mengubah segalanya di sana dan melihat apa yang terjadi.

Polina Gurtovaya dari perusahaan Evil Mars berbicara di konferensi  Frontend kami pada bulan Februari. Dengan bantuan percobaan, Polina menemukan cara mengubah gambar sederhana menjadi "gambar efektif" dengan metrik. Alat yang dapat melakukan ini untuk kita, Polina memeriksa lebih dekat ke akhir laporan. Hasilnya adalah perjalanan besar ke dalam dan prinsip-prinsip operasi berbagai format: dari PNG dan JPEG ke AV1 dan eksotis.


- Halo semuanya. Nama saya Polina, saya yang terdepan di perusahaan "Evil Martians".

Mungkin Anda mengenal orang Mars dari banyak sumber terbuka kami. Saya akan bercerita sedikit tentangnya nanti. Dan mungkin saya harus mengatakan bahwa kami masih mengembangkan produk, dan tidak hanya menggergaji open source.



Bahan-bahan untuk laporan akan tersedia untuk Anda melalui tautan indah di repositori di GitHub.



Mari kita bicara sedikit tentang pengoptimalan. Ketika kita berurusan dengan mereka, masalahnya adalah mereka bekerja dengan baik jika kita mengerti apa yang kita lakukan. Jika kita tidak mengerti, ternyata hasilnya buruk. Ketika datang ke optimasi gambar, sayangnya, semuanya di sini benar-benar tidak keren. Kami mungkin tidak mengoptimalkan gambar sama sekali, dan kemudian akan ada monster dua meter pada prod, semuanya sedih dan sedih.

Jika kita mengoptimalkan, lalu apa yang kita lakukan? Kami berpikir: di sini kami memiliki gambar, ini adalah semacam kotak hitam misterius, dan program pengoptimal melakukan sesuatu dengan gambar ini, semacam perdukunan hitam. Kualitas optimasi yang kami dapatkan agak meragukan.



Mari kita lihat sebuah contoh. Saya punya kucing dalam format PNG. Saya pikir kita perlu mengoptimalkannya. Apa yang saya lakukan? Saya membuat versi WebP dan dengan hati-hati memasukkan kedua gambar ke dalam tag <picture>. Apakah Anda pikir saya baik-baik saja di sini atau tidak? Mengapa hanya ada sedikit tangan? Saya melakukannya dengan sangat baik!

Saya melakukan semuanya dengan benar, tetapi versi WebP ternyata dua kilobyte lebih dari yang asli. Ini agak bukan yang saya inginkan.




Optimasi lain, percobaan nomor 2. Saya punya wadah kecil di halaman dan kucing besar besar. Saya ingin memasukkan kucing besar ke dalam wadah kecil. Apa yang saya lakukan? Saya melakukan pengubahan ukuran karena bodoh mengendarai byte melalui jaringan jika ukuran kontainer saya kecil. Tentu saja, saya memperhitungkan rasio piksel perangkat pada perangkat saya. Apakah Anda pikir saya baik-baik saja di sini atau tidak? Saya selesai! Dan lihat apa yang saya lakukan.

Saya menggunakan perpustakaan libvips. Dia sangat keren dan populer, dan dari kucing kecilku yang besar tapi bahagia, aku punya kucing kecil dan sangat berat. Segel meningkat 2,5 kali (dalam byte) selama pengubahan ukuran (dalam piksel) ke bawah. Keren ya



Secara umum, agar hal ini tidak terjadi pada kami, bahwa kami memahami cara mengoptimalkan gambar kami untuk tugas kami, dan, secara umum, sehingga kami setidaknya memahami apa yang terjadi, mari kita melihat ke dalam kotak dan memahami apa yang ada di dalamnya.



Mari kita mulai dengan melihat format yang menarik seperti PNG. Di sekitar setiap situs, sebuah peengshechka kecil disembunyikan di suatu tempat. Kali ini. Karena itu, mereka harus dipahami. Kedua: PNG - format kompresi lossless. Ini berarti kami menjamin kecocokan sempurna dengan yang asli dalam piksel, tetapi pada saat yang sama, sayangnya, secara alami kami dibatasi, kami tidak dapat mengkompres kurang dari seberapa banyak.



Peengeshka terlipat ke dalam wadah, seperti format gambar apa pun. Salah satu hal pertama yang perlu kita sampaikan kepada program jika membacanya adalah apa yang ada di dalamnya. Jika Anda menganggap bahwa decoder Anda menentukan gambar dengan ekstensi, ini tidak benar.

Pengashka melaporkan bahwa itu adalah PNG, delapan byte pertama dalam wadahnya. Dikatakan "PNG". Selanjutnya - lagi, ini adalah karakteristik dari wadah apa pun - Anda memiliki beberapa tata letak bongkahan. Artinya, info tersebut dikemas dalam potongan, mereka entah bagaimana diatur. Bagaimana - mendefinisikan wadah. Di PNG, terlihat seperti ini: Anda memiliki empat byte yang bertanggung jawab untuk panjang, dan empat byte yang bertanggung jawab untuk tipe chunk. Jenis apa - kita akan bicara sedikit kemudian. 

Jika potongan memiliki panjang bukan nol, ia memiliki muatan. Selain itu, ada yang namanya checksum. Anda sedang memeriksa untuk melihat apakah ada sesuatu yang telah dikalahkan di sana. Berikutnya datang potongan berikut.



Untuk mengurai tidak hanya file PNG, tetapi hampir semua orang cukup mudah. Ambil FileReader, ini adalah API browser. Kami membaca file menggunakan FileReader. Segera setelah kami membaca, kami memotong file ini menjadi potongan-potongan. Saya tidak akan memberikan kode fungsi split to chunks di sini, tetapi Anda dapat menebak bahwa ada kombinasi rumit jika dan untuk. 




Oke, kita sudah memotongnya, kita akan lihat apa yang terjadi. Kami memiliki beberapa jenis potongan, dan mereka sangat, sangat khas dari hampir semua format. Yang pertama disebut IHDR. Ada sejumlah bongkahan yang disebut IDAT. Nama-nama ini mungkin tampak sedikit aneh bagi Anda, tetapi kami sekarang akan mencari tahu apa itu. Ketika semuanya berakhir, kita melihat bagian terakhir.



Mari kita melihat lebih dekat ke dalam bongkahan. IHDR adalah meta-chunk, dan hampir semua gambar memiliki meta-chunk. Ini disebut berbeda, itu diatur secara berbeda, tetapi kemungkinan besar adalah. Tanpa itu, dekompresor Anda - sesuatu yang menunjukkan Anda peengeshki atau non-peengeshki - tidak dapat menunjukkan apa pun kepada Anda. Apa yang ada di bongkahan ini? Sekali lagi, isinya khas untuk sebagian besar format. Ini tinggi dan lebar. Tinggi dan lebar dijahit ke file Anda, itu datang kepada Anda. Selanjutnya adalah flag panache yang khas: bitDepth, colorType dan interlacing. 



Sebelum kita berbicara tentang apa arti bendera-bendera ini dan mengapa mereka sangat, sangat penting bagi kita, mari kita lihat bagaimana kita menyimpan piksel dalam pangshes. Di peaneshs, piksel disimpan di dalam chunk yang disebut IDAT. Dalam skenario yang baik, piksel adalah sejumlah angka yang dikemas ke dalam chunk, dan chunk ini dikompres oleh algoritma kompresi Deflate. Siapa yang menggunakan algoritma kompresi Deflate? Oke, kapan terakhir kali Anda membuka ritsleting? Apakah Anda tahu bahwa Deflate adalah gzip? Jadi saya pikir - banyak yang menggunakannya.

Tetapi dalam peengeshah hal lain yang menarik muncul yang digunakan dalam sejumlah besar format, tetapi mungkin dalam semua. Alat ini disebut coding prediktif. Faktanya adalah bahwa gambar kita bukan piksel acak. Apa yang dilukis pada gambar kecil kita entah bagaimana terhubung satu sama lain. Ada beberapa area gelap, area terang, dan sebagainya.

Kami mencoba untuk mengeksploitasi fakta ini, dan alih-alih menyimpan nilai piksel dalam sel-sel biru ini, kami mencoba memprediksi piksel ini berdasarkan yang sebelumnya. Dalam PNG, prediksi ini sangat sederhana, dan dipaket dalam byte yang sangat pertama sebelum garis dengan piksel. Prediksi bisa seperti ini, misalnya, jangan memprediksi apa pun dan letakkan semuanya apa adanya. Atau, misalnya, kita dapat mengatakan ini: tetapi marilah kita hanya menyimpan perbedaan antara piksel saat ini dan yang sebelumnya.

Jika Anda memiliki warna yang sama di baris Anda, Anda akan memiliki semua nol, semuanya dikompresi dengan sempurna, ini sangat keren.



Tapi sekarang mari kita bicara tentang arti sebenarnya dari sebuah pixel. Sebuah piksel muncul di sebuah peengesh sebagai sejumlah angka. Dengan memanipulasi berapa banyak angka yang ada, Anda dapat dengan sangat, sangat ketat mengompres PNG Anda - tiga kali.

Opsi apa yang ada? Yang pertama adalah True Color dan alpha. Kami memiliki tiga saluran, tiga warna, tiga angka per warna. Ditambah saluran yang bertanggung jawab atas transparansi.

Ukuran angka ini dalam bit adalah bitDepth, bendera yang sama yang kita lihat di potongan IHDR. Semakin kecil bitDepth Anda, semakin kecil file, tetapi semakin sedikit warna yang dapat Anda berikan kepada mereka. Angka tipikal adalah 8. Berapa harganya? Menurut pendapat saya, akan ada 16 juta dengan sesuatu.

Oke, optimasi pertama yang bisa Anda lakukan adalah membuang saluran alpha di peengesh Anda. Ini akan menjadi colorType yang berbeda.

Anda dapat mengoptimalkan lebih baik dan menggunakan hanya satu, bukan empat angka. Tapi masalahnya adalah bahwa peengeshka Anda harus hitam dan putih.

Jika Anda masih menginginkan hanya satu angka, dan meninggalkan warna, maka ini juga bisa dilakukan. Apa yang terjadi di sini? Anda mengambil semua warna di dalam peengeshka Anda dan memotongnya menjadi potongan terpisah. Sebut saja palet. Lebih jauh di dalam sampel, yang bertanggung jawab atas piksel di dalam potongan IDAT, Anda hanya menyimpan indeks palet ini. Jika Anda memiliki tangkapan layar apa pun tanpa latar belakang yang rumit atau gambar, benda ini datang dengan sempurna. Dia meremas peengeshki, benar wow!

Hal penting lainnya untuk dikatakan adalah Interlacing. Apa itu Interlacing? Ini adalah saat Anda mengirimkan peengeshka Anda secara bertahap. Anda belum memiliki satu peengeshka, tetapi beberapa gambar. Setiap gambar disebut scan.



Pada saat yang sama, di dalam paengashka, Anda mengurutkan piksel sedemikian rupa sehingga beberapa piksel keluar dari gambar, satu gambar berasal dari tempat khusus. Bagian selanjutnya adalah yang lain dan seterusnya. Teknik yang tampaknya keren seperti JPEG progresif.

Tapi kelihatannya seperti ini. Saya tidak yakin apakah Anda ingin pengguna Anda melihat ini, meskipun mungkin berguna untuk tugas Anda.

Masalah kedua dan sangat serius dari Interlaced PNG adalah segera setelah Anda mengaitkan peengeshka Anda, ukuran peengeshka Anda menjadi lebih besar. Dan tidak begitu lemah lagi, di suatu tempat dalam beberapa kilobyte, peengeshka enam kilobyte Anda akan tumbuh jika Anda mematikan Interlaced. Karena itu, pikirkan baik-baik apakah Anda menginginkannya atau tidak.



Kami hanya berbicara tentang PNG, tetapi dari hal ini Anda dapat menarik kesimpulan penting dan berguna. Kesimpulan pertama: ukuran file Anda, Anda tidak akan percaya, tergantung pada apa yang ditarik di sana. Kotak hitam menyusut lebih baik daripada kucing, saya tidak akan memberikan rekomendasi apa pun di sini. Kedua, lebih penting: ukuran file Anda sangat tergantung pada encoder dan pada parameter yang Anda transfer.

Jika Anda ingin melihat bagaimana encoders yang mengerikan bekerja, gunakan yang browser. Bagaimana ini dilakukan? Ambil file PNG, gambarkan di atas kanvas, lalu klik simpan sebagai dan bandingkan apa yang terjadi dengan apa yang terjadi. Secara umum, Chrome akan meningkatkan ukuran file Anda sebanyak 2,5 kali, Firefox - sebesar 1,6.

Omong-omong, itu juga selalu tergantung pada format, yaitu, tidak hanya PNG yang harus digunakan. Mari kita pahami mengapa itu semua tergantung pada format dan opsi menarik apa yang masih kita miliki.



Untuk melakukan ini, kita akan berbicara tentang teknologi nenek moyang, tentang JPEG. Anda tentu saja tidak dapat meremehkan pentingnya JPEG. Mereka ditemukan di mana-mana. Mereka sangat keren, bagus, dan bahkan lebih lagi, segel dalam format JPEG adalah cerita yang cukup umum. Tetapi JPEG adalah hal yang agak rumit, dan itu rumit karena fakta bahwa JPEG adalah kompresi lossy. Apalagi kompresi JPEG selalu lossy. Kualitas JPEG 100% masih terkompresi dengan kerugian.

Bagaimana kita mendapatkan kompresi lossy? Sangat sederhana. Kami mengambil beberapa sumber, membuang data dari itu, dan kemudian kompres tanpa kehilangan. Yaitu, ditambah satu langkah.



Mari kita lihat bagaimana kita membuat kerugian di JPEG kita. Jadi, Anda memiliki kucing dengan ukuran 32 kali 32. Agar kami dapat mengambil langkah pertama dengan kerugian, kami perlu mengubah saluran kami. Biasanya kita berbicara tentang gambar dalam hal RGB. Tapi kami menganggap warna agak rumit. Otak kita umumnya merupakan masalah besar, meskipun sangat membantu kita untuk mengompres JPEG.

Kami memahami hitam dan putih dengan sangat baik. Bahkan jika Anda melihat lebih dekat, Anda akan melihat bahwa detail dalam gambar hitam dan putih Anda membedakan dengan lebih baik. Kami hanya meletakkan gambar hitam dan putih ini di saluran terpisah. Ini disebut Y. Sebenarnya, Y-bar. Kami tidak melakukan apa-apa dengannya, kami hanya membiarkannya apa adanya.

Ada dua saluran lagi yang bertanggung jawab untuk warna. Ini adalah CB dan CR. Dengan saluran ini kita sudah bisa bersenang-senang sedikit. Di sini dengan saluran-saluran ini kami menghasilkan prosedur yang sangat keren yang disebut Downsampling. Kami mengambil dan mengurangi resolusi saluran ini. Untuk JPEG itu khas untuk membagi dua. Faktanya, Anda mendapatkan tiga gambar - satu asli dan dua setengah lebih banyak. Hore!

Apa yang kita lakukan selanjutnya? Kami tidak memampatkan JPEG, tidak seperti seluruh file. Kami memecahnya menjadi blok dan kompres lebih lanjut, kami sudah mulai blok. Blok dalam format JPEG berukuran 8 x 8 dan lihat apa yang terjadi padanya. Mari kita lihat saja saluran Y. CB dan CR semuanya sama.



Jadi, blok bukan gambar, tetapi angka. Kita perlu membuat kerugian di JPEG. Blok ini berukuran 8 kali 8, 64 piksel, yang mana yang harus dibuang? Yang di kiri, yang di kanan, yang di tengah? Tidak jelas. Tetapi ada matematika keren yang memungkinkan kita untuk menyelesaikan masalah ini.

Matematika ini disebut - sekarang, tolong jangan gugup jika ada yang ingat masa lalu kelembagaan yang mengerikan - transformasi kosinus yang terpisah. Jadi, dengan bantuan transformasi cosinus diskrit ini, Anda dapat mengonversi angka-angka ini di blok Anda sehingga angka-angka itu penting dan tidak penting di antara mereka.

Penting: setelah konversi, nomor-nomor penting tetap berada di bagian kiri atas blok. Di kanan bawah tetap angka yang tidak penting.

Selanjutnya Anda harus membuat JPEG Anda hilang. Ini juga sangat mudah dilakukan. Trik ini disebut kuantisasi. Maaf jika Anda ingin tidur sekarang, tetapi ini penting, percayalah. Jadi, kuantisasi ini bekerja dengan cara yang agak sederhana. Anda mengambil blok Anda dan piring yang dirancang khusus. Pelat ini ditentukan oleh program encoder Anda. Angka-angka yang ternyata di blok Anda, Anda membagi dengan istilah pelat ini dengan angka dan bilangan bulat. Apa yang Anda dapatkan sebagai hasilnya?

Karena angkanya besar di bagian kanan bawah pelat, hanya akan ada nol.



Dan pada saat yang sama JPEG Anda, blok Anda akan kompres dengan sempurna. Anda akan memiliki sejumlah kecil angka yang akan Anda bypass dalam zigzag rumit seperti itu, nol semua akan hilang, dan, tepuk tangan, blok kami siap untuk kompresi. Maka kita hanya perlu mengompresnya dengan algoritma kompresi lossless. JPEG menggunakan Huffman Coding, apa pun itu.



Bagaimana dikemas dalam wadah? Wadah JPEG terlihat agak bodoh, aku takut pada mereka. Karena Anda melihat dua byte pertama dan dikatakan bahwa kemungkinan besar ini adalah JPEG. Namun sejauh ini tidak jelas.

Selanjutnya Anda perlu mencari dua potongan meta. Mengapa dua? Karena JPEG adalah seperangkat standar yang sangat besar. Apa yang kita sebut JPEG, secara standar, disebut JIFF. Ini adalah ekstensi khusus standar JPEG. Saya tidak akan melanjutkan lebih jauh - secara umum, ada dua potongan meta, percayalah padaku. Potongan meta ini berisi informasi tentang lebar dan tinggi file Anda dan versi JPEG. Bayangkan, JPEG memiliki lebih banyak versi! Dan selain itu, apakah JPEG progresif? Ini adalah bendera yang penting. Dia berbicara tentang bagaimana blok Anda akan didistribusikan lebih lanjut.

Jika JPEG tidak progresif, lalu apa yang Anda butuhkan untuk memecahkan kode blokir Anda? Kualitas JPEG, piring ini. Piring yang Anda bagikan menjadi kualitas. Tetapi JPEG memiliki dua kualitas. Kualitas pertama bertanggung jawab untuk saluran Y, yang kedua - untuk saluran CB dan CR, inilah yang menentukan warnanya. Karena kami menempatkan kualitas dalam file dan memerasnya semua dengan algoritma kompresi lossless, kami masih membutuhkan kamus Huffman Tables khusus untuk memperluas ini.

Berikutnya adalah blok Anda, dan kemudian JPEG Anda selesai.



Oke, cerita progresif. Semuanya persis sama. Pada awalnya Anda memiliki meta-chunk. Berikutnya adalah kualitas Anda dalam bentuk 64 angka, ditambah 64 angka. Dan kemudian hanya blok yang sama, tetapi hanya sedikit berbeda dengan angka yang didistribusikan. Bagian pertama dari blok, kemudian bagian lain, bagian lain dan seterusnya. Saat Anda menerima blok ini, browser menggambar perkiraan JPEG Anda, karena, pada kenyataannya, angka-angka ini adalah beberapa perkiraan file Anda.



Tentang JPEG kami selesai, Anda bisa menghembuskan napas, semuanya baik-baik saja. Mari kita bicara tentang hal yang menarik seperti JPEG 2000. Apakah ada di antara Anda dalam produksi yang menggunakan JPEG 2000? Oke, siapa yang pernah mendengar ini? Dan siapa di antara Anda yang telah membaca di Mercusuar - "gunakan format modern"?

Secara umum, JPEG 2000 adalah format menarik yang keren, yang, pertama, lebih efektif daripada JPEG. Kedua, Anda tidak akan percaya, dalam beberapa kasus ini lebih efektif daripada WebP, yang akan kita bicarakan nanti.

Dia tahu bagaimana menjadi transparan, tahu bagaimana mengompres tanpa kehilangan. Hanya format yang sempurna. Namun sayangnya, ya, itu hanya berfungsi di Safari.

Patut disebutkan bahwa JPEG 2000 dirancang dengan cara yang sangat rumit dan bekerja pada matematika keren yang disebut transformasi wavelet. Jika Anda tiba-tiba tertarik, google, dan kami akan melangkah lebih jauh.



Lalu tiba-tiba kita perlu berbicara tentang video. Seluruh laporan ini adalah tentang pengoptimalan gambar dan tentang gambar. Tapi video di sini sangat penting, Anda akan tahu mengapa sekarang. Ketika kita memikirkan sebuah video, kata pertama yang muncul di benak kita adalah "codec". Video perlu dikodekan, dan untuk menunjukkan videonya, kita perlu men-decode-nya. Jika kita mendekode streaming video, apa yang kita dapatkan?

Pertama-tama, kami memiliki satu set bingkai. Tapi jangan menganggap frame ini sebagai gambar di GIF. Semua salah. Frame mana yang sangat tergantung pada codec. Tetapi dalam kasus umum, Anda dapat menganggap bahwa Anda memiliki bingkai kunci. Anda bisa mengeluarkan kucing dari keyframe - dalam arti, gambar apa saja yang ada di keyframe ini. Dan ada frame tergantung. Tidak mungkin untuk mengeluarkan kucing dari frame dependen, karena frame dependen menyimpan tidak hanya informasi bukan tentang gambar, jika ada, tetapi tentang bagaimana blok dari frame sebelumnya atau sebelumnya bergerak pada ini. Oleh karena itu, Anda tidak bisa mendapatkan gambar untuk bingkai bergantung sampai Anda memecahkan kode sedikit.

Yang akan kita bicarakan sekarang adalah kompresi keyframe dan intraframe. Ini adalah bagaimana Anda memampatkan gambar di dalam bingkai kunci.

Mari kita lihat codec abstrak dalam ruang hampa dan bandingkan dengan JPEG. Sejauh ini tampaknya - mengapa melakukan ini? Semuanya akan menjadi lebih jelas, percayalah.



Sekali lagi kami mengulangi hal yang sama yang kami lakukan dengan JPEG,. Anda mengambil gambar, membuatnya terpecah menjadi saluran, lakukan Downsampling ke saluran. Kisah yang sama di sini. Kemudian Anda memecah gambar ini menjadi beberapa blok. Tetapi sudah ada fitur. Pertama-tama, ukuran blok yang Anda masuki tergantung pada codec Anda. Dan balok-balok ini bisa sangat besar. Untuk JPEG - 8 oleh 8. Untuk codec video - dapat berupa, misalnya, 128 x 128.

Lebih jauh. Jika Anda mendapatkan detail yang sangat kecil pada gambar yang ingin Anda perhatikan, Anda masih dapat membagi sedikit blok, kira-kira berukuran 4 kali 4. Bagaimana Anda memecahkan blok, algoritma partisi ini tergantung pada codec.

Dan yang terbaru - ukuran blok maksimum, sekali lagi, khusus untuk codec Anda. Encoder adalah bagian dari codec, untuk dipahami dalam terminologi. Di sini kita masih mirip dengan JPEG.



Apa yang tidak terlihat seperti JPEG adalah pengkodean prediktif. Kami membicarakannya sebagian tentang peengeshki. Kompresi intraframe-video sangat keren dan efektif hanya karena ini. Apa yang terjadi di sini?

Kami mencoba memprediksi piksel setiap blok berdasarkan yang sebelumnya. Artinya, kami tidak menyimpan piksel dalam bentuk mentah, kami memperkirakannya. Opsi prediksi banyak. Dalam satu codec, kita dapat menggunakan berbagai varian prediksi. Selain itu, untuk semua jenis codec yang rumit dari opsi ini, sebanyak 35, misalnya. Bagaimana kamu bisa melakukan ini. Mari kita lihat beberapa contoh.

Di sini Anda memiliki blok. Anda berkata: Saya ingin memprediksi piksel di sana. Anda melihat ke kiri, Anda melihat ke atas dan mengingat apa yang tersisa dan di atas. Selanjutnya, Anda mengambil semua nilai piksel yang Anda temukan, rata-rata dan mengisinya dengan blok, dan berkata: Saya memperkirakan. Jika Anda menebak dengan benar, dan omong-omong, pada gambar kecil di mana ada panah biru, Anda menebak dengan benar, maka Anda hebat, Anda tidak perlu melakukan hal lain. Tapi, jika Anda belum menebak, maka Anda perlu menyimpan perbedaan antara apa yang sebenarnya dan apa yang Anda prediksi. Perbedaan ini memampatkan banyak, jauh lebih baik daripada nilai piksel murni.



Maka semuanya persis sama seperti di JPEG. Anda akan mengubah blok yang dihasilkan. Tetapi kekhasan semua jenis codec yang berbeda adalah bahwa Anda tidak dapat menggunakan DCT (discrete cosine transform), tetapi sesuatu yang lain. Apa yang digunakan tergantung pada codec.



Kemudian lagi piring yang sama, tetapi tidak seperti JPEG Anda dapat menggunakan lebih dari satu piring untuk seluruh file Anda, dan Anda dapat menggunakan beberapa piring yang berbeda untuk blok yang berbeda. Bayangkan - Anda memiliki seseorang, misalnya, melawan langit. Mungkin, karena langit berwarna biru, Anda tidak memerlukan kualitas khusus di sana, Anda dapat menggunakan satu kualitas untuk langit, satu piring. Dan untuk orang yang memiliki tekstur, pakaian, gunakan kualitas yang berbeda, dan ternyata keren dan efektif.



Yang terbaru adalah apa yang tidak dimiliki JPEG, dan apa yang JPEG sangat, sangat kurang. Ini adalah penggunaan filter. Ketika kita semua menuai, kita mendapatkan artefak jahat setelah kompresi. Jika Anda pernah mengompres JPEG ke kualitas rendah, Anda harus melihat bagaimana JPEG berantakan hanya menjadi mimpi buruk yang mengerikan. Secara umum, untuk menyingkirkan artefak ini, codec video menggunakan hal khusus. Mereka menerapkan filter, dan tepi blok ini halus. Teknologi para leluhur, yang memungkinkan kami untuk melakukan hal yang sama dengan JPEG, begitu hebatnya. Anda mengambil JPEG Anda, kompres sangat, sangat keras, lalu tekuk seperti ini sehingga tidak ada yang terlihat. Secara umum, ini hampir sama, tetapi sudah dilakukan di tingkat codec. Bagus.



Tentu saja, ketika kami mencoba dan ini semua dilakukan, kami sekarang perlu mengompres blok yang diterima tanpa kehilangan. Kami diperas, dilakukan dengan baik. Algoritma kompresi mirip dengan JPEG, tetapi masih berbeda. Di sini harus dipahami bahwa kompresi lossless dibatasi oleh batas alami. Kami benar-benar ingin mendekatinya, dan cara terbaik untuk mendekatinya adalah jika kami menggunakan algoritme yang disebut pengodean Aritmatika. Dan ada juga berbagai macam variasi. Ini lagi tergantung pada encoder, tapi mari kita asumsikan bahwa ada kompresi lossless dan kira-kira.



Saya sudah lama ingin memanggil codec abstrak ini dalam ruang hampa dengan nama yang tepat. Wisata sejarah kecil. Apa yang terjadi dalam 20 tahun? Saya hanya berbicara tentang codec video yang setidaknya didukung entah bagaimana di web. H.264 adalah codec yang mendukung segalanya dan semua orang. Ini adalah solusi default untuk seluruh video. Setelah jangka waktu tertentu, setelah beberapa tahun, codec video VP8 muncul.

Di sini perang liar dimulai, holivar tentang topik mana dari codec ini yang lebih baik. Saya mencari Google untuk waktu yang sangat lama - tidak ada jawaban. Artikel ilmiah yang hebat telah ditulis tentang ini, tetapi rata-rata, jika saya mengatakan hal yang sama sekarang, tomat akan terbang ke saya. Tapi, oke, semuanya sama. Rata-rata Lalu mengapa kita membutuhkan sedetik?

Yang kedua diperlukan karena gratis. Jika Anda menggunakan H.264, Anda perlu membawa uang MPEG dalam beberapa keadaan. Untuk VP8 Anda tidak perlu membawa uang. Ini baik. Jadi, VP8 keyframe - ini adalah WebP. Memang, mengapa kita harus menciptakan format gambar baru? Kami mengambil keyframe, kami berusaha sangat keras, kami meremasnya semua. Kami menyebutnya semua format gambar baru, dan voila!

Apa yang terjadi selanjutnya? Kemudian setelah beberapa tahun, dua codec video keren, dari MPEG dan dari Google, muncul hampir bersamaan. Dari Google - VP9, ​​dari MPEG - H.265. Di sebelah H.265 ada standar gambar baru yang disebut HEIF. Itu tidak didukung oleh browser, tidak sama sekali. Tetapi didukung oleh perangkat Apple Anda. Standar HEIF sangat menarik, karena itu hanyalah abstraksi dari ide ini. Dalam wadah HEIF, Anda bisa menjejalkan keyframe dari hampir semua codec. Artinya, VP8 bukan format modern. Tapi HEIF modern.

Apa yang terjadi selanjutnya? Sekarang di organisasi yang sangat besar, yang meliputi Mozilla dan Google, sebuah codec video yang disebut AV1 sedang digergaji. Organisasi itu disebut Alliance for Open Media. Kualitas AV1-video berkali-kali lebih tinggi dari semua yang sebelumnya. Dia bebas, dia bebas royalti, dia sangat keren. Kami memiliki wadah HEIF yang bagus. Yang tersisa bagi kami adalah memasukkan AV1 keyframe ke dalamnya. Dan itu dilakukan. Format baru untuk mendorong bingkai kunci AV1 ke wadah HEIF disebut AVIF. Inilah yang menanti kita di masa depan. Mungkin suatu hari nanti kita akan menggunakannya secara asli.

Tapi kita bisa menggunakannya sekarang. Kami hanya meletakkan satu frame dari video di halaman dan berkata: voila, Anda punya gambar.



Bagaimana ini dilakukan di webp? WebP, seperti yang saya katakan, adalah keyframe VP8 yang dikemas dalam wadah yang disebut riff. Ada header seperti itu di wadah riff. Di sana, jangan percaya, ada tertulis bahwa ini adalah WebP. Siapa yang akan meragukannya. PNG mengatakan itu adalah PNG WebP, dan itu dia.

Tetapi WebP memiliki fitur yang menarik: VP8 keyframe dapat terletak di dalamnya, dan inilah yang biasanya disebut WebP. Tapi keyframe VP8 mungkin tidak. Secara umum, WebP mendukung kompresi lossless. WebP lossless adalah format yang sama sekali berbeda yang tidak ada hubungannya dengan VP8, kompresi lossy, dll. Oleh karena itu, ketika seseorang memberitahu Anda bahwa WebP lebih efektif daripada yang lain, pertanyaan pertama yang diajukan adalah apa WebP sesuatu? Karena jika kita berbicara tentang kompresi lossless, maka ada lorong alami yang dapat kita perjuangkan. Perbedaan-perbedaan ini, "60% lebih efektif daripada ...", lebih mungkin bukan tanpa kerugian, tetapi WebP dengan kerugian.

Oke, cukup teori, muak, mari kita lihat sesuatu. Diklik




Mari kita mulai dengan ini. Kami mengambil foto yang diambil oleh kamera profesional. Gunting sepotong 1000 kali 1000 piksel darinya. Ini, kebetulan, terlihat sangat keren di proyektor. Kami mulai mempertimbangkan detail kecil. Pada saat yang sama, kami mengompres bagian ini sehingga kami mendapatkan tepat 15 kilobyte. Dapat diklik Lihat apa yang terjadi. JPEG langsung terhambat. Memang, kualitas rendah, kami harapkan ini. Seperti inilah tampilan WebP. Itu juga jatuh ke blok, tetapi blok ini tidak begitu jelas terlihat. Saat Anda menggunakan encoder WebP dan mengendalikannya dengan tangan Anda, Anda dapat mengontrol kekuatan filter yang digunakan di WebP. Dan jika Anda melepaskan filter ini lebih keras, maka Anda dapat menyingkirkan sejumlah besar artefak blok. Oleh karena itu, murni secara teoritis, blok ini juga dapat dihilangkan.








Dan di sini adalah AV1. Mari kita kagumi dengan tenang. Lihat betapa kerennya dia. AV1 didukung di Firefox, di Chrome, sehingga Anda dapat menggunakan video AV1 alih-alih gambar jika Anda tiba-tiba menginginkannya. Dapat diklik Ada spoiler, sia-sia saya menambahkannya. Situasi ketika PNG mengalahkan WebP. Ya, PNG dalam hal ini lebih efektif daripada WebP. Ini karena saya menggunakan WebP lossy. Dapat diklik Apa yang saya lakukan dengan peengeshka? Saya membuat mode warna yang diindeks, yaitu, saya memotong palet, menurut pendapat saya, menjadi 16 warna. Ini cukup efektif untuk gambar hitam putih. Ternyata baik, itu dikontrak sangat banyak. Untuk kualitas WebP lossy kami mendapat ukuran yang lebih besar. Namun, untuk lossless, ini diharapkan, lebih efisien daripada peengeshka. Kami mendapat kemenangan.











Saya meringkas. Pangsh tersembunyi yang sangat keren dapat mengalahkan format kompresi lossy dan tidak mengalahkan WebP lossless. Sedih, sedih. Dapat diklik Mungkin Anda tersiksa oleh pertanyaan: mengapa Anda melakukan ini, apakah kita tahu apa itu SVG? Dan saya tahu, tetapi untuk beberapa ukuran, PNG lebih efisien. Gambar ini ternyata lebih efektif daripada SVG untuk ukuran seperti 200 hingga 200. Kemudian SVG, tentu saja, menang. Dapat Diklik Sekarang mari kita lihat Mike. Ini Mike. Dimensinya adalah 3000 oleh 3000 piksel. JPEG vs WebP. Jelas di sini bahwa JPEG menang. Tetapi dalam hal ini, saya mendapat kemenangan sekitar enam persen untuk kualitas visual yang hampir sama. Ini adalah fitur foto dan bagaimana saya mempersiapkan foto ini. Anda kemudian dapat bertanya kepada saya bagaimana saya melakukannya.












Dapat diklik.

Namun, semuanya sangat tergantung pada parameter encoder. Jika Anda berusaha sangat keras dan membuka parameter encoder dengan cara khusus, maka JPEG akan mulai mengalahkan WebP dalam ukuran untuk kualitas visual yang sama. Saya ingin menyimpulkan bahwa kucing menyusut lebih baik dari JPEG, tetapi tidak. Ini hanya sebuah contoh bagaimana Anda bisa melepaskannya dengan cara yang Anda suka jika Anda mau. Dapat diklik Ini adalah kualitas yang sangat rendah. JPEG jatuh ke blok. Ini sangat jelas di proyektor - hidung membiru pada anjing, menjadi persegi. WebP tidak begitu sakit. Semuanya tampak keren dan bagus, tetapi masalahnya adalah untuk kualitas WebP yang sangat, sangat rendah, kira-kira dua, atau mungkin tiga kali ukuran file daripada JPEG. Jadi di sini Anda juga perlu memikirkan kualitas apa yang Anda inginkan. Diklik









Ini adalah perbandingan paling jujur. Jadi Anda harus membandingkan, karena H.264 dan WebP serupa. Menurut Anda siapa yang menang di sini? H.264. Tapi jujur ​​saja, eksperimen itu tidak sepenuhnya bersih. Dalam cara yang baik, baik di WebP dan di H.264, bingkai video kira-kira tidak ambigu. Dapat diklik Tetapi dengan AV1, semuanya benar-benar jelas. Tiga puluh persen menang dengan kualitas visual yang sama. Hore! Dapat diklik Sangat penting untuk memahami gambar seperti apa yang Anda masukkan dan bagaimana format ini atau itu merespons kualitas gambar. Di sini anjing dalam format WebP memiliki berat 79 kilobyte dengan kualitas sekitar 75% berbanding 56 kilobyte dalam JPEG. Mengapa ini terjadi?











Karena bukan codec video tunggal, tidak ada satu format pun yang dapat memadatkan kebisingan dengan benar. Jika gambar Anda memiliki banyak distorsi yang tajam, titik-titik dan sesuatu yang lain, maka kemungkinan besar Anda akan memiliki masalah dengan kompresi. Jika Anda dapat mengambil gambar lain dan menghapus suara ini, hapuslah.

Jadi, gambar adalah hal yang rumit. Bisakah mereka memperlambat antarmuka Anda? Pertanyaan penting dan bagus.



Jawab: kemungkinan besar tidak. Kenapa itu terjadi? Karena ketika gambar diterjemahkan, itu terjadi dalam aliran yang terpisah. Tetapi ada pengecualian - jika Anda menggambar sesuatu di atas kanvas, Anda harus ingat bahwa penguraian gambar akan terjadi di aliran utama dan tombol-tombol mungkin tidak ditekan pada saat itu.



Jika Anda benar-benar ingin membuat kesepakatan, buka Chrome, cari utas rasterisasi terkait dan acara Decode Gambar, Anda akan menemukannya.



Jika Anda sangat, sangat ingin tahu, Anda dapat pergi ke tab tracing dan melihat di sana dengan detail apa yang terjadi ketika mendekode gambar.

Alat optimisasi


Yang paling penting adalah alat optimasi. Kita sekarang tahu apa yang kita inginkan. Masih memahami bagaimana kita melakukan ini.



Alat pengoptimalan gambar yang paling penting adalah perancang, tidak peduli seberapa aneh kedengarannya. Hanya orang yang luar biasa ini yang tahu masalah apa yang ingin Anda selesaikan dengannya. Kami tidak menambahkan gambar ke halaman untuk mengoptimalkannya, tetapi untuk mengesankan pengguna. Untuk menjaga keseimbangan antara tingkat optimasi dan pengalaman pengguna, gunakan desainer yang banyak membantu.


Tautan dari slide Alat

kedua adalah open source Mars kami, yang saya janjikan untuk dibicarakan. Hal ini disebut imgproxy dan menyelesaikan semua masalah kita secara umum. Pada proyek saya, saya hanya menggunakan imgproxy, hal ini dapat melakukan hampir semua yang saya inginkan.



Bagaimana itu bekerja? Apakah Anda punya keinginan untuk foto itu. Anda ingin gambar dengan ukuran tertentu dengan optimasi tertentu. Dan di suatu tempat yang jauh Anda memiliki gambar resolusi apa pun - mungkin di komputer lokal, atau di suatu tempat di pengguna atau secara umum di mana saja. Anda hanya perlu membuat url khusus dan meminta imgproxy untuk mengubah ukuran gambar Anda. Ini adalah layanan seperti itu, bisa di cloud atau di tempat lain. Artinya, Anda memiliki kucing besar, Anda mengirim URL khusus ke imgproxy. Dia melakukan semua yang Anda inginkan dengan cepat.



Jika itu tidak terdengar jelas, mari kita lihat seperti apa permintaan untuk imgproxy. Pertama, Anda perlu tahu di mana imgproxy berada. Kedua, jika Anda tidak ingin tersedot secara agresif, maka URL yang Anda minta akan baik untuk ditandatangani secara digital. Anda tidak dapat melakukan ini, ini hanya langkah perlindungan tambahan.

Selanjutnya, jika Anda ingin mengubah ukuran, maka langsung di url, lewati parameter ukuran. Jika Anda ingin mengoptimalkan - hal yang sama. Anda hanya perlu mentransfer alamat asli gambar Anda.



Jika Anda menginginkan pengoptimalan manual, ada banyak alat. Saya tidak akan menjelaskan semuanya sekarang. Bahan - bahan untuk laporan, yang akan saya kirimkan kepada Anda, memiliki segalanya.



Inilah yang paling keren dan bermanfaat. Ini semua gambar tidak begitu rumit. Saya pikir saya berhasil menyampaikan ini kepada Anda. Jika Anda tertarik, ambil bahasa pemrograman favorit Anda - mungkin JavaScript, meskipun jauh dari kenyataan - dan mulailah memilah semuanya.

Jika Anda ingin melakukan ini di browser, silakan. Anda mungkin membutuhkan pengikatan yang kemungkinan besar ditulis dalam plus atau dalam C. Tapi apa yang mencegah Anda untuk mengkompilasi semua ini di WebAssembly? Ada aplikasi keren bernama Squoosh. Itu persis seperti itu. Anda juga bisa, coba, itu akan keren. Saya sangat suka.

Terima kasih atas perhatiannya. Bahan untuk laporan - dengan referensi .

All Articles