kompresja bitmap

W tym artykule chciałem opisać sposób w jaki kompresuje grafikę (czyli głównie bitmapy) w moim projekcie. Pomysł polega na odpowiednim wykorzystaniu formatów png i jpg.

1. Stosowane Formaty:

  • JPG – stratna kompresja bez przeźroczystości.
  • PNG (RGBA) – format z kompresją bezstratną i kanałem alfa
  • PNG (z paletą kolorów)  – format z tablicą kolorów (do 256 kolorów w tym kolor przeźroczysty)

2. poprawa kompresji dla PNG (RGBA)

Najprostszym sposobem na poprawienie kompresji np. serii ikon jest wrzucenie ich do jednego obrazka w formacie PNG i zapamiętanie pozycji zajmowanych przez ikony. Ponieważ format PNG stosuje kompresje wierszową najlepiej rozkładać je horyzontalnie.

Przykładowo w Gizarmie są 22 ikonki zasobów. Każda ikona zapisana jest w PNG-24, posiada przezroczystość.

gizarma-024

Ikonki bez kompresji zajmują 34 556 bajtów, po zastosowaniu metody plik obrazu i plik z koordynatami zajmują 25 987 bajtów. Kompresja poprawiła się o około 25%.

3. Kompresja stratna z kanałem alfa

Czasami może się zdarzyć, że nie zależy nam na bezstratności kompresji obrazu, ale z drugiej strony potrzeba obsługi przeźroczystości. W tym wypadku dobrze sprawdza się zapisanie obrazu w JPG i dodatkowo maski przeźroczystości w oddzielnym obrazie PNG z paletą barw (zazwyczaj nie trzeba pamiętać 256 poziomów przeźroczystości, z moich doświadczeń wynika, że już 32 poziomy dają dobre rezultaty). Maskę zapisujemy w PNG ponieważ często ma ona gwałtowne przejścia od pełnej przeźroczystości do jej braku. Format JPG mógłby sprawić, że na takich ostrych granicach pojawiły by się artefakty.

gizarma-025
przykład artefaktów na krawędzi maski przy zastosowaniu formatu JPG

Ponieważ obraz początkowo z kanałem alfa jest zapisywany do JPG, trzeba pozbyć się przeźroczystości.

  • Dla każdego punktu gdzie alfa!=1 alfa=0, żeby nie mieszać koloru tła z naszym obrazem.
  • Po drugie dobrze jest rozmyć nasz obraz na jego zewnętrznych krawędziach. Należy to zrobić ponieważ JPG miesza kolory jeżeli zmieniają się one gwałtownie, nasz obraz mógłby być zanieczyszczony tłem na krawędziach.

Przykład na podstawie obrazu domku

Na przykładzie 34 grafik domków wstępnie skompresowanych metodą z punktu 2. pokaże efektywność metody. Obraz w PNG zajmuje 328 887 bajtów, po kompresji obraz i maska zajmują 101 258 bajtów. Poziom kompresji obrazu jpg wynosi 0.5, maska posiada 32 kolory. Objętość grafiki zmniejszyła się ponad 3 krotnie przy niewielkiej stracie jakości.

Troll