· 5 min read

Miten animoidut GIF:t todella toimivat Canvas Frameista LZW Compressioniin

GIF-muoto on 39 vuotta vanha ja edelleen kaikkialla. Tässä mitä tapahtuu napsauttamalla "Export" ja saada tiedoston ... kehys kaappaus, värin kvantitalisaatio, LZW pakkaus, ja miksi GIF on 4MB.

Miksi GIF on yhä olemassa

CompuServe loi grafiikan vaihtomuodon vuonna 1987 [CompuServe, 1987]. Se tukee animaatiota, avoimuutta ja häviötöntä pakkausta. Se on rajoitettu 256 väriä per runko. Siinä ei ole ääntä. Se tuottaa suuria tiedostoja. Se olisi pitänyt korvata kaikilla teknisillä toimenpiteillä vuosikymmeniä sitten.

Ja silti: Discord, Slack, iMessage, Twitter, Reddit, ja sähköposti kaikki tukea GIFs natiivisti. GIPHY palvelee yli 10 miljardia GIF:ää päivässä [GIPHY, 2020]. Muoto pysyy koska se toimii kaikkialla, ei tarvitse koodekkia, ja pelaa automaattisesti. Mikään muu muoto ei ole tämä yhdistelmä yleistä tukea ja nollarajoitus toisto.

Tieto siitä, miten GIF:t toimivat, on hyödyllistä trivian lisäksi se selittää, miksi viety GIF on 4MB, miksi kaltevuudet näyttävät banded, ja mitä voit tehdä sille.

Vaihe 1: Runkokaappaus

Animoitu GIF on sarja kuvia (kehyksiä) näytetään järjestyksessä viive välillä. Luoda yksi kangas animaatio, sinun täytyy kaapata kangas tila säännöllisin väliajoin.

Selaimessa tämä tarkoittaa pikselitietojen lukemista HTML <canvas>-elementistä jokaisena kuva-aikana tyypillisesti canvas.toDataURL():n tai ctx.getImageData():n kautta. Animaatio edistyy kohdeaikaan, kangas renderoidaan ja pikselit otetaan talteen. Tärkein rajoite: sinun täytyy odottaa selaimen maalikiertoa (requestAnimationFrame) ennen pikseleiden lukemista, muuten kaappaat himmeän puskurin.

Tyypillinen GIF 15 FPS 3 sekunnin ajan vaatii 45 kuvakaappausta. At 1080×1080 resoluutio, jokainen kehys on noin 4,7 miljoonaa pikseliä.

Vaihe 2: Värikartoitus

GIF tukee enintään 256 väriä per runko, tallennetaan väritaulukko (paletti). Tyypillinen kangaskehys on tuhansia eri värejä. GIF-koodauksen vaikein osa on pelkistys 256:een ilman näkyvää hajoamista.

Normaali lähestymistapa on mediaani leikkausalgoritmi [Heckbert, 1982]: lajittele kaikki pikselit punertavimman kanavan mukaan, jaa lista mediaanissa, toista vihreä ja sininen, rekursiivisesti jakaen väritilan 256 alueeseen. Kunkin alueen keskiarvosta tulee paletti. Tämä on mitä gif.js kirjasto PinePaper käyttää .. toteuttaa Web Workers for rinnakkaisuus [Rubaxa, gif.js].

Värin kvantifiointi on syy GIFs käsitellä litteä väri grafiikkaa hyvin, mutta kamppaile valokuvia ja kaltevuuksia. 1080 pikselin kaltevuus saattaa käyttää 500+-eri värejä. Puristaminen 256 tuottaa näkyvän siteen erilliset vaiheet, joissa kaltevuuden on oltava tasainen.

Mitä voit tehdä asialle: Käytä vähemmän värejä suunnittelussa. Litteät muodot, kiinteä täytettä, ja teksti määrällinen hyvin. Sileät gradientit ja valokuvatekstuurit eivät. Jos GIF on bändi, yksinkertaistaa palettia, ei päätöslauselmaa.

Vaihe 3: LZW-pakkaus

Kunkin ruudun pikseliindeksit (viittaukset 256-väripalettiin) pakataan käyttäen Lempel-Ziv-Welch (LZW) -kompressiota [Velch, 1984]. LZW rakentaa sanakirjan toistuvia tavusekvenssejä, kun se skannaa tiedot. Kun se kohtaa sekvenssi se on nähnyt ennenkin, se tuottaa sanakirja indeksi sijaan raaka tavuja.

Tämä tarkoittaa, että GIF pakkaus on tehokkain, kun on suuria alueita toistuvan värin kiinteä tausta, litteät muodot, teksti yhtenäisellä pinnalla. Monimutkaiset tekstuurit pikselitason variaatiolla tuottavat huonoja pakkaussuhteita, koska LZW-sanakirja löytää vain muutamia toistuvia sekvenssejä.

  • 1080×1080 GIF valkoinen teksti mustalla taustalla saattaa pakata 200KB. Saman resoluution GIF monimutkainen valokuva voi olla 8MB. Tiedoston koko riippuu enemmän visuaalinen monimutkaisuus kuin päätöslauselma tai kehyslaskenta.

Vaihe 4: Runkojen käsittely ja optimointi

GIF-kehykset voivat määritellä käsittelymenetelmän: poistetaanko kangas ennen seuraavan ruudun piirtämistä, jätetään edellinen kehys näkyville tai palautetaan taustalle. Älykkäät GIF-koodaajat käyttävätframe-eroa** koodaus vain pikseleitä, jotka muuttuivat kehysten välillä, ei koko kehystä.

Jos animaatiossasi on staattinen tausta, jossa on pieni liikkuva elementti, optimoitu GIF koodaa taustan kerran ja päivittää vain alueen, johon elementti siirtyi. Tämä vähentää huomattavasti tiedoston kokoa. PinePaper:n koodain käyttää gif.js, joka soveltaa tätä optimointia automaattisesti.

Numerot

Tyypillinen PinePaper animaatio (1080×1080, 15 FPS, 3 sekuntia, tumma tausta animoitu teksti):

Osa Koko
Raakakarmit (45 × 4,7M pikseliä × 3 tavua) ~634 MB
Kvantitoinnin jälkeen (256 väriä, 1 tavu/pikseli) ~211 MB
Kun LZW pakkaus ~2-4 MB
Kehyserojen kanssa ~1-2 MB

Puristussuhde raaka lopullinen on noin 300:1 600:1. Suurin osa tästä tulee värin kvantitaation (3:1) ja LZW (50:1-100:1).

Klikkaa läpi neljä vaihetta. Baari on vedetty vasten raaka kokoa yksi lineaarinen asteikko, joten viimeiset kaksi vaihetta se on hiusraja ei ole renderöinti vika, siltä näyttää 300:1.

Interactive demo — open in editor pp:PinePaper

Milloin käyttää GIF vs. muut muodot

Muoto Paras Rajoitus
GIF Yleinen tuki, automaattisoitto, viestintäsovellukset 256 väriä, suuria tiedostoja, ei ääntä
WebM (VP9) Paras laatu, pienin tiedostoja, web Rajoitettu tuki Safari, iMessage
MP4 (H.264) Sosiaalinen media, videosoittimet Vaaditaan koodekkia, ei avoimuutta
APNG Täysi väri-animaatio läpinäkyvyydellä Rajoitettu tuki vanhoissa selaimissa

GIF on oikea valinta, kun tarvitset universaalin yhteensopivuuden ja automaattisen pelaamisen. Laadun tai tiedoston koko, WebM tai MP4 ovat parempia.

Kokeile sitä

Avaa PinePaper Studio, luo design ja vie GIF. Tarkkaile kuinka tiedoston koko muuttuu:

  • Lisää kehyslukua (lisää kehyksiä = suurempi tiedosto, suhteellisesti)
  • Lisää gradientit (huono kvantitalisaatio = suurempi tiedosto)
  • Käytä kiinteitä värejä (hyvä kvantitalisaatio = pienempi tiedosto)
  • Lisää kankaan kokoa (lisää pikseleitä per runko = suurempi tiedosto)

Jokainen muutos on puristusputken mittaus. Et tee vain GIF:ää huomaat, miten informaatioteoria pätee suunnitteluun.

Lähteet

  • CompuServe (1987). Graphics Interchange Format Specification, Version 87a.
  • GIPHY (2020). GIPHYn vuosikertomus: 10 miljardia päivittäistä palvelua.
  • Heckbert, P. (1982). Värikuvan kvantitalisaatio kehyspuskurinäytölle. * Computer Graphics (SIGGRAPH) *, 16(3), 297-307.
  • Rubaxa. gif.js JavaScript GIF-koodain käyttäen Web Workers. github.com/jnordberg/gif.js.
  • Welch, T.A. (1984). Tekniikka korkean suorituskyvyn data pakkaus. IEEE-tietokone, 17(6), 8-19.

PinePaper:n GIF-vienti on ilmainen ei vesileimaa, ei ilmoittautumista. Avaa mäntypaperi.studio/editor ja vie ensimmäinen animaatio.

Ready to create?

Start making animated GIFs, videos, and graphics — free, no signup.

Open PinePaper Editor