GIF'ok Konverter Gila ke stiker animasi untuk Telegram

Alih-alih seribu kata ...


xZibit juga senang, karena di sini GIF dimasukkan ke dalam stiker untuk dimasukkan ke dalam GIF untuk KDPV!

Dan sekarang tentang detail implementasi.

Semuanya dimulai dengan diskusi di obrolan pengembang Telegram tentang fitur yang akan datang:

Bohdan Horbeshko, [04/04/19 20:21] Hmm, tetapi bot mungkin hanya akan menerima gif, dan kemudian mengonversi ... | Vitaly, [07/04/19 20:22] dari gif ke Jason? Saya akan melihat :))) | Bohdan Horbeshko, [04.07.19 20:22] Dan mengapa tidak? Ada editor model PlayCanvas di JSON. | Vitaly, [04/04/19 8:23 malam] dan bagaimana gif? ekspor piksel demi piksel? :) | Bohdan Horbeshko, [04/04/19 20:24] Tentu saja, dunia TI telah melihat dan tidak akan mentolerir distorsi semacam itu.

Seorang pria berkata - seorang pria melakukannya! Prototipe pertama dalam Bantal dan svgwrite, mem-parsing GIF menjadi piksel dan mengubahnya menjadi kotak vektor dengan preview di SVG, ditulis dalam satu hari libur.

Kesenangan mulai lebih jauh ...

JSON adalah format terbuka, kata mereka ...


Sampai sekarang, dengan format di Telegram, mereka terus menipu. Membuat dukungan untuk animasi GIF - pada kenyataannya, mereka dikonversi ke MP4-video. Membuat dukungan untuk stiker - mereka diunggah ke PNG, tetapi dikonversi ke WebP. Kali ini semuanya lebih jujur: bahwa di pintu masuk, lalu di pintu keluar.

Untuk stiker animasi, Telegram tidak menggunakan GIF, video, atau bahkan format grafik vektor yang sudah mapan seperti SVG, atau, Tuhan melarang Cthulhu! - Flash. Ini menggunakan format bermodel baru yang muncul dari bawah sayap Airbnb - Lottie. Sampai sekarang, ia memiliki beberapa ketenaran di kalangan pengembang ponsel, tetapi berkat Telegram, itu mungkin mendapatkan popularitas lebih.

Intinya, file Lottie adalah proyek Adobe After Effects berseri JSON yang memaksimalkan semua fitur program ini. Dengan tampilan, sayangnya, semuanya tidak begitu cerah . Meskipun ada banyak implementasi perpustakaan "resmi" yang siap pakai untuk rendering Lottie, hanya untuk platform yang dicakup oleh Telegram: Android, iOS, Qt dan Web - hanya sebagian dari kemampuan format yang diimplementasikan di semuanya. Telegram melangkah lebih jauh dan membatasi daftar fitur yang didukung, serta "muncul" dengan formatnya sendiri, yang berbeda dari Lottie biasa hanya dengan mengemas dalam GZip dan parameter "tgs": 1 . Kurasa aku tahu di mana Denis Popov bekerja sekarang! :-)

Dan jika semuanya cukup baik dengan dokumentasi untuk perpustakaan untuk platform yang berbeda, maka, sayangnya, tidak mungkin untuk menemukan setidaknya beberapa deskripsi dari perangkat format - hanya skema JSON di sumber web-lottie. Saya harus bermain-main dalam animasi yang ada untuk memahami konsep umum format. Ada juga perbedaan antara file nyata dan skema: khususnya, di lapisan tipe 4 , menurut skema, objek bersarang disimpan di properti "it" - namun, dalam file nyata kuncinya disebut "shapes" , dan "it" tidak berfungsi.

Nuansa format yang diklarifikasi:

  • File terdiri dari beberapa lapisan. Tidak seperti GIF, di sini setiap lapisan dapat memiliki waktu mulai dan waktu berakhir yang sewenang-wenang untuk tampilan. Berbagai transformasi dapat diterapkan pada lapisan (lebih tepatnya, perlu ): penskalaan, rotasi, perubahan transparansi, dll. Lapisan bahkan bisa tiga dimensi (dilarang untuk Telegram).
  • Lapisan terdiri dari "bentuk". Mereka memiliki banyak jenis, beberapa tidak dapat digunakan di Telegram. Dalam praktiknya, agar sebuah layer muncul, ia harus mencakup tiga bentuk: path (dalam animasi yang sudah jadi, biasanya ini tipe "sh" - kurva Bezier; konverter sejauh ini hanya menggunakan tipe "rc" - persegi panjang), fill (tipe "fl" ), dan transformasi ( ketik "tr" ).
  • Anda bahkan dapat memasukkan elemen raster, membuat layer teks, dan membangun hubungan antara parameter layer dan bentuk melalui ekspresi. Semua barang ini juga dilarang di Telegram.

Masalah pertama langsung mengikuti dari sini: redundansi . Meskipun nilai default untuk parameter transformasi baru-baru ini ditambahkan ke skema JSON, mereka tidak diimplementasikan di perpustakaan. Jadi meminta mereka secara eksplisit masih diperlukan.

Tampaknya ini bukan masalah sama sekali? Bahkan GZip sederhana melakukan pekerjaan yang baik untuk mengompresi data berulang secara terang-terangan, dan 1 MB JSON mentah secara ajaib berubah menjadi beberapa puluh kilobyte, yang diam-diam merambat ke batas yang dinyatakan 64 kB. Itu dia!

Saya mengunduh, yang artinya animasi gemuk yang ditampilkan lottie-web secara diam-diam di Telegram - dan di sini alih-alih pixel art yang indah, yang buram statis menatap saya:



Apa itu ?! Tapi ternyata ada batas yang tidak ditentukan sebesar 1 MB pada data yang terkompresi. Seorang perwakilan dari tim Telegram dengan cepat mengonfirmasikannya dan mengumumkan peningkatan batas yang akan datang menjadi 2 MB.

Bahkan jika mereka memecahkan masalah ini, stiker yang melampaui 1 MB data yang tidak terkompresi dan tidak mengandung transformasi tidak akan dapat diakses oleh pengguna Telegram versi lama. Jadi mungkin harus mematuhi batasan di masa depan.

Transparansi itu penting.


Bantal, bersama dengan OpenCV, dapat disebut standar industri untuk pemrosesan gambar dengan Python. Selain itu, ia juga diasah dengan baik untuk fitur GIF: mendukung warna yang diindeks dan memberikan akses ke palet. Ini mendukung konversi peta piksel menjadi array NumPy, yang penting untuk pemrosesan produktif. Bahkan mengumpulkan statistik tentang warna! Tapi ada juga kelemahannya:

  1. Tidak ada cara yang terdokumentasi untuk mendapatkan indeks warna transparan. Saya harus berasumsi sebagai solusi sementara bahwa warna transparan adalah yang paling umum, tetapi dalam GIF nyata ini tidak selalu terjadi.
  2. Hal yang sama dengan penundaan antar frame: Bantal hanya memberikan frame sendiri sebagai urutan gambar, tanpa informasi tentang penundaan.
  3. Terkadang frame parsial salah ditumpangkan.

Karena itu, saya harus mencari penggantinya. Modul gif2numpy bertindak seperti itu. Ini "dipertajam" untuk fitur GIF dan menyediakan akses ke semua properti teknis baik gambar dan frame individu, termasuk GCE . Dengan demikian, ia memecahkan masalah keterlambatan membaca.

Transparansi, ternyata, gif2numpy tidak mendukung sama sekali: warna segera dikonversi ke tiga saluran dengan kedalaman bit dalam byte, tanpa memperhitungkan kedalaman bit akun dan menyimpan indeks warna. Untungnya, modul ini terdiri dari satu file, jadi tidak sulit untuk memasukkannya ke dalam proyek dan memodifikasinya dengan menyimpan warna #FE00FE untuk transparansi.

Masalah kerangka parsial tidak sepele untuk dipecahkan. gif2numpy mencoba untuk overlay frame seperti pada yang sebelumnya, namun tidak memeriksa parameter overlay, itulah sebabnya hasil yang benar juga tidak selalu keluar. Agar tidak dipusingkan dengan flag, pemrosesan gambar awal menggunakan gifsicle dengan kunci --unoptimize - itu mengkonversi bingkai parsial menjadi yang penuh. Dan pada saat yang sama itu membuat mereka menggunakan palet global, yang menghilangkan kebutuhan untuk secara terpisah memproses warna transparan saat menggunakan palet bingkai Anda sendiri.

Peras aku lebih keras


Kuadratnya bagus, tetapi dengan batasan seperti itu Anda harus menunjukkan lebih banyak imajinasi, jika tidak, miniatur GIF tidak akan "merayap" ke Telegram.

Sesuatu yang mirip dengan RLE digunakan pertama kali : kotak yang berdekatan secara horizontal dengan warna yang sama digabungkan menjadi satu persegi panjang.

Selanjutnya adalah eksploitasi fitur Lottie. Karena setiap lapisan memiliki waktu mulai dan berakhir yang sewenang-wenang, Anda dapat menerapkan teknik yang telah lama digunakan oleh codec video, dan sebagian di GIF itu sendiri: kotak yang tetap di tempat yang sama untuk beberapa bingkai dapat digabung menjadi satu lapisan, di mana perubahan tampilan beberapa lainnya. Yang diimplementasikan sejauh ini hanya untuk pasangan lapisan yang berdekatan.

Rencana pengembangan


Gagasan yang dapat diterapkan di sini adalah dalam jumlah besar:

  • Kenali area satu warna dari berbagai ukuran. Anda dapat memecahnya menjadi satu set persegi panjang, yang memiliki algoritma yang baik . Disarankan juga untuk mengubahnya menjadi kontur, tetapi ini dibayangi oleh kebutuhan untuk menentukan semua titik kurva Bezier di Lottie - persegi panjang dalam beberapa kasus mungkin lebih menguntungkan.
  • Kenali gerakannya. Teknik ini, sekali lagi, telah lama digunakan dalam codec video. Jika kontur yang sama tidak berubah bentuk dari bingkai ke bingkai, tetapi hanya koordinat - alih-alih menduplikasi pada beberapa lapisan, letakkan di satu lapisan dengan transformasi.
  • Kenali "penutup" dari satu area dengan area lainnya. Contoh:

     ...... .O..O. ...... .OOOO. ...... 

    Piksel warna yang berbeda ditumpangkan pada persegi panjang satu warna. Alih-alih memecah persegi panjang ini menjadi sekelompok kecil, atau mengubahnya menjadi kontur dengan bentuk yang rumit - Anda bisa langsung menambahkannya di atas seluruh persegi panjang.
  • Vektorisasi kurva dan elips, pengakuan gradien. Ini akan merusak pesona piksel, tetapi akan meningkatkan kompresibilitas beberapa GIF berdasarkan pesanan besarnya. Gradien bahkan dalam "Koloboks" kuno, saya jamin! : D
  • Kompresi lossy. Pertama-tama, penghapusan dithering, dan bahkan dalam gambar yang terlalu halus tidak akan menghalangi moderasi warna. Gifsicle tersebut mungkin akan menangani ini.

Referensi


  • Sumber . Menakutkan di beberapa tempat.
  • Saluran tempat saya mengunggah paket GIF yang berhasil dikonversi.

Source: https://habr.com/ru/post/id460411/


All Articles