Formaty obrazu: WebP

Google WebP pierwotnie opracował stratny format obrazu, który ma zastąpić format JPEG. Był on w stanie generować pliki mniejsze niż pliki graficzne o porównywalnej jakości zakodowane jako JPEG. Później w formacie wprowadzono możliwość kompresji bezstratnej, przezroczystości kanału alfa przypominającej format PNG oraz animacji przypominającej GIF-y. Wszystkie te rozwiązania można stosować razem ze stratną kompresją JPEG. WebP to niewiarygodnie uniwersalny format.

Algorytm kompresji stratnej WebP opiera się na metodzie używanej przez kodek wideo VP8 do kompresowania klatek kluczowych w filmach. Ogólnie rzecz biorąc, kodowanie jest podobne do kodowania JPEG: WebP działa na zasadzie „bloków”, a nie pojedynczych pikseli, i stosuje podobny podział luminancji i chrominancji. Bloki luma WebP mają rozmiar 16 x 16, a bloki kolorów 8 x 8, a te „makrobloki” są dodatkowo podzielone na podbloki 4 x 4.

Gdy WebP radykalnie różni się od JPEG, mamy 2 funkcje: „przewidywanie blokowe” i „adaptacyjna kwantyfikacja bloków”.

Zablokuj prognozę

Przewidywanie bloków to proces, w ramach którego przewidywana jest zawartość każdego bloku chrominancji i luminancji na podstawie wartości otaczających je bloków – w szczególności tych znajdujących się powyżej i po lewej stronie bieżącego bloku. Jak można sobie wyobrazić, algorytmy, które wykonują to zadanie, są dość złożone, ale ogólnie rzecz biorąc, „jeśli nad bieżącym blokiem jest niebieski, a jeśli niebieski jest po lewej, załóżmy, że ten blok jest niebieski”.

W rzeczywistości pliki PNG i JPEG również zapewniają takie prognozy w pewnym stopniu. WebP jest jednak wyjątkowy, ponieważ próbkuje dane otaczających bloków, a następnie próbuje wypełnić bieżący blok za pomocą kilku różnych „trybów prognozowania”, co umożliwia „rysowanie” brakującej części obrazu. Wyniki podane w każdym trybie prognozy są następnie porównywane z rzeczywistymi danymi obrazu i wybierane są najbliższe dopasowanie prognozowane.

Diagram różnych metod prognozowania bloków WebP.

Nawet najbliższe dopasowanie prognozowane nie jest oczywiście całkowicie prawidłowe, dlatego różnice między prognozowanymi a rzeczywistymi wartościami tego bloku są zakodowane w pliku. Podczas dekodowania obrazu mechanizm renderowania używa tych samych danych, aby zastosować tę samą logikę prognozującą, prowadząc do uzyskania tych samych wartości prognozowanych dla każdego bloku. Różnica między prognozą a oczekiwanym obrazem zakodowanym w pliku jest stosowana do prognoz, podobnie jak zatwierdzenie różnicowe, które jest stosowane do pliku lokalnego, a nie zupełnie nową kopię pliku.

Aby zilustrować: zamiast zagłębiać się w złożone obliczenia matematyczne w prawdziwym algorytmie prognozującym, wymyślimy kodowanie podobne do WebP z pojedynczym trybem prognozowania i użyjemy go do efektywnego przekazywania siatki liczb tak, jak robiliśmy to w starszych formatach. Nasz algorytm ma jeden tryb prognozowania, który nazywamy „trybem prognozowania jeden”. Wartość każdego bloku to suma wartości bloków znajdujących się nad nim i po jego lewej stronie, zaczynając od 1.

Załóżmy teraz, że zaczynasz od tych rzeczywistych danych obrazu:

111151111
122456389

Korzystając z modelu prognostycznego do określenia zawartości siatki 2 x 9, uzyskamy taki wynik:

111111111
123456789

Nasze dane dobrze pasują do naszego algorytmu prognozującego – prognozowane dane są zbliżone do naszych rzeczywistych danych. Oczywiście nie jest to idealne rozwiązanie – rzeczywiste dane składają się z kilku bloków różniących się od danych prognozowanych. Wysyłane przez nas kodowanie obejmuje nie tylko metodę prognozowania, ale także różnice między blokami, które powinny się różnić od wartości prognozowanych:

_ _ _ _ +4 _ _ _ _
_ _ -1 _ _ _ -4 _ _

Użyj tego samego języka, co w przypadku niektórych omówionych przez nas starszych formatów kodowania:

Siatka 2 x 9 w trybie prognozowania 1. +4 do 1 x 5, od -1 do 2 x 3, od –4 do 2 x 7.

W rezultacie powstaje niewiarygodnie wydajnie zakodowany plik.

Kwantyzacja bloków adaptacyjnych

Kompresja JPEG to operacja ogólna, polegająca na zastosowaniu tego samego poziomu kwantyzacji do każdego bloku na obrazie. Ten obraz ma jednolitą kompozycję, ale na pewno ma sens, ale rzeczywiste fotografie nie są bardziej jednolite od otaczającego nas świata. W praktyce oznacza to, że ustawienia kompresji JPEG nie są określane na podstawie szczegółów o wysokiej częstotliwości, gdzie kompresja JPEG jest najlepsza, ale na podstawie tych fragmentów obrazu, w których przypadku prawdopodobieństwo wystąpienia artefaktów kompresji jest największe.

Skompresowany obraz JPEG motyla monarchy

Jak widać na tym przesadnym przykładzie, skrzydła monarchy na pierwszym planie wyglądają stosunkowo ostre – w porównaniu z oryginałem w wysokiej rozdzielczości są dość ostre, ale nie da się to zauważyć bez porównania z oryginałem. Także szczegółowe kwitnienie mleczaka i liście na pierwszym planie — Ty i my możemy dostrzec ślady kompresji przy wytrenowanych oczach, ale nawet przy zastosowaniu kompresji na ponad rozsądnym poziomie elementy na pierwszym planie nadal wyglądają wyraźnie ostre. Informacje o niskiej częstotliwości w lewym górnym rogu zdjęcia – rozmyte zielone tło liści – wyglądają okropnie. Problem z jakością od razu zauważy nawet niedoświadczeni przeglądający – subtelne gradienty w tle zostaną zaokrąglone w dół do poszarpanych brył jednokolorowych.

Aby tego uniknąć, WebP stosuje adaptacyjne podejście do kwantyzacji: obraz jest podzielony na maksymalnie 4 podobne wizualnie segmenty, a parametry kompresji tych segmentów są dostrojone niezależnie. Ten sam duży rozmiar kompresji w WebP:

Skompresowany obraz WebP motyla monarchy

Rozmiar obu plików graficznych jest mniej więcej taki sam. Jakość jest mniej więcej taka sama, gdy patrzymy na skrzydła monarchy – można dostrzec kilka drobnych różnic w wyniku, jeśli przyjrzymy się z bliska, ale nie mają one znaczącej różnicy w ogólnej jakości. W WebP kwiaty mleczaka są tylko trochę ostrzejsze, chyba że będzie to zbyt mało zauważalne, chyba że porównasz je ze sobą i zastanawiasz się, czy naprawdę się różnią w jakości. Tło jest zupełnie inną historią: nie ma prawie śladu po wyraźnie widocznych artefaktach JPEG. WebP zapewnia nam ten sam rozmiar pliku, ale znacznie wyższą jakość obrazu. Podaj lub uwzględnij drobne szczegóły, których nasze systemy psychowizualne nie będą w stanie wykryć, jeśli nie porównamy ich tak dokładnie.

WebP

Elementy wewnętrzne WebP mogą być znacznie bardziej złożone niż kodowanie JPEG, ale do celów naszej codziennej pracy tak samo proste: cała złożoność kodowania WebP opiera się na jednej wartości „jakości” wyrażonej w zakresie 0–100, tak jak w przypadku formatu JPEG. Po raz kolejny nie oznacza to, że zakres jest ograniczony do jednego nadrzędnego ustawienia „jakości”. Możesz – i powinno – obrabiać szczegóły kodowania WebP, choćby wtedy, gdy chcesz lepiej zrozumieć, jak te normalnie niewidoczne ustawienia mogą wpływać na rozmiar i jakość pliku.

Google oferuje koder wiersza poleceń cwebp, który umożliwia konwertowanie lub kompresowanie poszczególnych plików lub całych katalogów obrazów:

$ cwebp -q 80 butterfly.jpg -o butterfly.webp

Saving file 'butterfly.webp'
File:   butterfly.jpg
Dimension: 1676 x 1418
Output: 208418 bytes Y-U-V-All-PSNR 41.00 43.99 44.95   41.87 dB
        (0.70 bpp)
block count:    intra4:     7644  (81.80%)
               Intra16:     1701  (18.20%)
               Skipped:       63  (0.67%)
bytes used:  header:            249  (0.1%)
              mode-partition:  36885  (17.7%)
Residuals bytes  |segment 1|segment 2|segment 3|segment 4|  total
macroblocks:     |       8%|      22%|      26%|      44%|   9345
quantizer:       |      27 |      25 |      21 |      13 |
filter level:    |       8 |       6 |      19 |      16 |

A jeśli nie chcesz korzystać z wiersza poleceń, Squoosh posłuży nam również do kodowania WebP. Daje nam możliwość porównania różnych kodowania, ustawień, poziomów jakości i różnic w rozmiarze pliku w porównaniu z kodowaniem JPEG.