Optymalizacja plików graficznych JPG i PNG na strony WWW i nie tylko

Jak dobrze zoptymalizować pliki graficzne, aby nie straciły na jakości, a jednocześnie zajmowały mniej miejsca? Należy użyć nowoczesnych narzędzi optymalizacji. Tu się dowiesz jakie są nowinki w kwestii optymalizacji plików JPG i PNG, czyli algorytmy Guetzli oraz Zopfli.

Przykład zbyt mocnej kompresji JPG

Spis treści

  1. Co daje optymalizacja plików graficznych
  2. Optymalizacja plików JPG
  3. Optymalizacja plików PNG

Co daje optymalizacja plików graficznych

W dzisiejszych czasach dyski są tanie, więc oszczędzenie kilku kilobajtów/megabajtów na wielkości pliku, który trzymasz na dysku w sumie nic nie daje. Łącza internetowe są szybkie – na komputerze z łączem 20Mbps różnicy dużej też nie zauważysz. Jakie są zatem największe zalety małych rozmiarów plików graficznych? Nie każdy ma szybkie łącze – są miejsca, gdzie 5Mbps to szczyt możliwości (również możliwości cenowej przeciętnego użytkownika). Na komórkach najczęściej mamy ograniczenia na pakietach internetowych – tu też różnica może być odczuwalna. Z drugiej strony – jeśli masz własną stronę postawioną na hostingu z miesięcznym limitem transferu, to zwykle pliki graficzne zjadają najwięcej tego transferu. Jeśli pliki graficzne zostaną dobrze zoptymalizowane pod kątem wielkości i zarazem jakości (aby nie straciły na jakości zbyt wiele) to możesz jedynie zyskać, nic nie tracąc.

Optymalizacja plików JPG

Do optymalizacji plików JPG istnieje wiele różnych programów (posiadających interfejsy graficzne oraz konsolowych), jednak wersją kompresującą (chyba) najbardziej, przy jednoczesnym zachowaniu bardzo dobrej jakości jest Guetzli dostarczone przez Google. Autorzy podają, że pliki wynikowe są od 20% do 30% mniejsze od tych wygenerowanych przez libjpeg.

Kompilowanie binarki

Zgodnie z informacjami podanymi na stronie z kodem źródłowym Guetzli, do poprawnego działania potrzebny jest pakiet libpng (instalacja przez apt-get install libpng-dev lub zgodnie z zaleceniami na stronie biblioteki). Następnie należy pobrać źródła i skompilować:

leniwy@leniwy:~/optymalizacja$ git clone https://github.com/google/guetzli.git
Cloning into 'guetzli'...
remote: Counting objects: 634, done.
remote: Total 634 (delta 0), reused 0 (delta 0), pack-reused 634
Receiving objects: 100% (634/634), 421.56 KiB | 463.00 KiB/s, done.
Resolving deltas: 100% (388/388), done.
Checking connectivity... done.
leniwy@leniwy:~/optymalizacja$ cd guetzli/
leniwy@leniwy:~/optymalizacja/guetzli$ make
[…]
leniwy@leniwy:~/optymalizacja/guetzli$ bin/Release/guetzli
Guetzli JPEG compressor. Usage:
[…]

Jeśli wszystko poszło dobrze, plik binarny znajduje się w miejscu bin/Release/guetzli.

Kompresowanie plików JPG

Możesz przystąpić do zmniejszania plików JPG. Zakładając, że źródła i binarka znajdują się w tym miejscu co w moim przypadku, wystarczy przejść do katalogu z plikiem jpg i wykonać polecenie:

leniwy@leniwy:~/pliki$ ~/optymalizacja/guetzli/bin/Release/guetzli --quality 90 plik.jpg plik_zoptymalizowany.jpg

Parametr quality to nic innego, jak poziom kompresji. Domyślny poziom to 95 (im niższa wartość, tym mniejszy rozmiar pliku i jednocześnie gorsza jego jakość), jednak zwykle wystarcza niższy poziom. Polecam spróbować użyć wartości 90 i sprawdzić, czy różnica będzie zauważalna.

Jeśli nie chcesz podawać pełnej ścieżki do pliku guetzli, wystarczy ustawić alias.

leniwy@leniwy:~/pliki$ alias guetzli=~/optymalizacja/guetzli/bin/Release/guetzli

Aby zoptymalizować wszystkie pliki jpg w bieżącym katalogu, możesz użyć polecenia:

leniwy@leniwy:~/pliki$ for plik in `ls -1 *.jpg`; do guetzli --quality 90 $plik `basename $plik .jpg`_zoptymalizowany.jpg; done

W ten sposób wszystkie pliki w katalogu ~/pliki z rozszerzeniem .jpg zostaną zoptymalizowane przez guetzli i zapisane pod nazwą z suffiksem _zoptymalizowany. W ten sposób łatwo porównasz wersje przed i po optymalizacji w dowolnej przeglądarce plików graficznych. Jeśli któryś wynik nie będzie zadowalający, możesz dostosować poziom kompresji.

Oszczędności na rozmiarze

W moim przypadku, przy ustawieniu poziomu jakości/kompresji na 95, maksymalny zysk jaki udało mi się uzyskać bez zauważalnej straty na jakości to nieco ponad 25%. Przy poziomie jakości/kompresji ustawionym na 90, plik wynikowy jest o ponad 40% mniejszy. Strata na jakości jest minimalna – jak porównuję obydwa pliki to drobne różnice widać, jednak jak nie mam porównania z oryginałem, to w całości wygląda w porządku.

Optymalizacja plików PNG

Podobnie jak w przypadku plików JPG, dla plików PNG istnieje również wiele różnych programów do optymalizacji. Jednak podobnie jak w przypadku plików JPG, do optymalizacji plików PNG również polecam rozwiązanie od Google, czyli algorytm Zopfli.

Kompilowanie binarki

Tak jak poprzednio, najlepiej ściągnąć aktualne źródła z repozytorium oraz wywołać polecenie make:

leniwy@leniwy:~/optymalizacja$ git clone https://github.com/google/zopfli.git
Cloning into 'zopfli'...
remote: Counting objects: 518, done.
remote: Total 518 (delta 0), reused 0 (delta 0), pack-reused 518
Receiving objects: 100% (518/518), 429.77 KiB | 375.00 KiB/s, done.
Resolving deltas: 100% (286/286), done.
Checking connectivity... done.
leniwy@leniwy:~/optymalizacja$ cd zopfli/
leniwy@leniwy:~/optymalizacja/zopfli$ make zopflipng
[…]
leniwy@leniwy:~/optymalizacja/zopfli$ ./zopflipng
ZopfliPNG, a Portable Network Graphics (PNG) image optimizer.
[…]

Jeśli wszystko poszło poprawnie, plik binarny znajduje się w katalogu bieżącym. Aby ułatwić jego użycie, proponuję tak jak wcześniej zrobić alias

leniwy@leniwy:~/optymalizacja/zopfli$ alias zopflipng=~/optymalizacja/zopfli/zopflipng

Kompresowanie plików PNG

Możesz teraz przystąpić do kompresowania plików PNG. Przykład użycia:

leniwy@leniwy:~/pliki$ zopflipng plik.png plik_zoptymalizowany.png
Optimizing plik.png
Input size: 34177 (33K)
Result size: 30838 (30K). Percentage of original: 90.230%
Result is smaller

Aby zoptymalizować wszystkie pliki png w bieżącym katalogu, można tak jak wcześniej użyć polecenia

leniwy@leniwy:~/pliki$ for plik in `ls -1 *.png`; do zopflipng $plik `basename $plik .png`_zoptymalizowany.png; done

Dodatkowy parametr pozwala zmniejszyć pliki jeszcze bardziej, wykonując więcej iteracji:

leniwy@leniwy:~/pliki$ zopflipng -m plik.png plik_zoptymalizowany-m.png
Optimizing plik.png
Input size: 34177 (33K)
Result size: 30802 (30K). Percentage of original: 90.125%
Result is smaller

W niektórych przypadkach można w ten sposób uzyskać jeszcze mniejszy plik wynikowy, jednak odbędzie się to kosztem czasu kompresji (co jest zwykle mało znaczące).

Oszczędności na rozmiarze

Oszczędności będą bardzo zależne od pliku. Średnio w moim przypadku wychodzi około 10%, jednak zdarzały mi się pliki mniejsze o połowę (najczęściej takie, które mają dużo jednolitego tła i niewiele poza nim. Prawdopodobnie jest to spowodowane faktem, że pliki wcześniej nie były optymalizowane w żaden sposób. Google podaje, że uzyskamy zwykle do około 8% zysku. Niby nie dużo, ale zawsze coś!