«Komprimer dette bildet» er fire adskilte operasjoner som deler én knapp. Vet du hvilken av dem som koster deg kvalitet, blir innstillingene langt mindre mystiske.
Steg én: dekoding
Den komprimerte filen gjøres om til et rutenett av piksler igjen. Nettlesere gjør dette i maskinkode, med maskinvareakselerasjon der plattformen tilbyr det, og de håndterer JPEG, PNG, WebP og AVIF — pluss HEIC på Apple-plattformer, fordi operativsystemet allerede leverer den dekoderen.
Dekoding er tapsfri sett i forhold til filen: du får nøyaktig de pikslene filen beskriver. Tapet har allerede skjedd, den gangen det som lagde filen, kodet den.
Steg to: orientering
Mobilkameraer lagrer sensorens rå orientering pluss en egen EXIF-merkelapp som sier hvordan bildet skal roteres. Programvare som overser den merkelappen, gir bilder som ligger på siden. Å bruke den betyr å rotere selve pikselrutenettet før noe annet rører det — og etterpå trengs ikke merkelappen lenger, noe som er en del av grunnen til at omkoding fjerner metadata.
Steg tre: resampling
Kan ikke målstørrelsen nås ved full oppløsning, skaleres bildet ned. Det er her mye av den opplevde kvaliteten stille vinnes eller tapes. Et billig boksfilter tar gjennomsnittet av nabopiksler og gjør alt mykere; et Lanczos-filter vekter et bredere nabolag og holder kantene skarpe.
Resampling er reelt destruktivt — pikslene som forsvinner, kommer ikke tilbake — men det er ofte den minst destruktive veien til et lite mål, fordi det fjerner detaljer koderen ellers ville brukt hele budsjettet sitt på å mislykkes med å beskrive.
Steg fire: koding
Den tapsbaserte delen. JPEG konverterer til en representasjon av lysstyrke pluss farge, kaster bort noe av fargeoppløsningen (øyet merker det knapt), deler bildet i blokker på 8×8, transformerer hver av dem til frekvenskomponenter, og kvantiserer så — runder bort de høyfrekvente detaljene. Kvalitetsparameteren er grovheten i den avrundingen. Alt etter den er tapsfri entropikoding, og det er derfor en optimalisert Huffman-tabell eller en progressiv skanning sparer byte gratis.
Her kommer WebAssembly inn
Nettleserens innebygde koder er en svart boks: du kan be om et kvalitetstall, og ingenting annet. Ingen optimaliserte entropitabeller, ingen valg mellom baseline og progressiv, ingen kontroll over resamplingsfilteret, og ingen måte å vite hvor mange byte en innstilling gir uten å prøve.
En kodek kompilert til WebAssembly gir alt dette tilbake, mot de bytene du bruker på å laste den ned. ToolZool kjører hele pipelinen på den måten — dekoding, orientering, resampling og koding er alt sammen Rust kompilert til WebAssembly, i en bakgrunnsprosess — framfor å overlate dekodingen til nettleseren. Tre grunner, alle praktiske:
- Søket krever mange kodinger. Å treffe en eksakt størrelse betyr å kode det samme bildet fem eller seks ganger. At vi eier koderen, er det som gjør dette billig og repeterbart.
- En dekoder må kunne si nei. En fil som oppgir 60 000 × 60 000 piksler, må avvises før den allokerer minne, og en avkortet fil må feile framfor å returnere et halvt bilde. Nettleserens dekoder tar sine egne avgjørelser der; vår oppgir grensene og håndhever dem.
- Samme inndata må gi samme utdata. Nettleserdekodere er forskjellige både i fargehåndtering og i hvordan de behandler ødelagte filer. En pipeline som eier begge ender, gir de samme bytene på hver enhet, og det er det som gjør resultatet mulig å etterprøve.
Kostnaden er ærlig: den motoren er en nedlasting. Den hentes først når du har valgt en fil, så det å lese en side som denne betaler aldri for den.
Hvorfor søket betyr mer enn kodeken
Gitt en målstørrelse er forskjellen mellom en god koder og en glimrende noen få prosent. Forskjellen mellom å gjette på en kvalitetsglider og å søke etter det riktige nivået er langt større, for en gjetning som lander på 60 % av det du hadde til rådighet, kastet bort en tredjedel av kvaliteten du hadde krav på. Det er hele tanken bak å komprimere til en eksakt størrelse, og å treffe en grense på 50 KB viser hva søket gir deg i den vanskeligste enden av skalaen.

