Łatwe tworzenie obrazów w wysokiej rozdzielczości

Ekrany o dużej gęstości pikseli szybko stają się normą. Twórcy treści muszą się do tego dostosować. Z tego krótkiego przewodnika dowiesz się, jak wyświetlać obrazy wysokiej jakości w internecie bez użycia kodu polyfill, JavaScriptu, kodu CSS i funkcji przeglądarki, które nie zostały jeszcze w pełni wdrożone. Krótko mówiąc: bez wprowadzania drastycznych zmian w przepływie pracy.

Obecnie istnieje wiele elastycznych propozycji obrazów, z których wiele wiąże się ze znacznymi zmianami dla programisty stron internetowych. Implementacja atrybutu standardowej srcset <img> jest trudna, zwłaszcza ze względu na złożoność dodatkowego wyboru na podstawie widocznego obszaru przez srcset:

banner-HD.jpeg 2x, banner-phone.jpeg 100w, banner-phone-HD.jpeg 100w 2x

Mimo że właściwość CSS image-set używa tylko devicePixelRatio do określenia, który obraz wczytać, nadal zmusza programistów do napisania wielu dodatkowych znaczników dla każdego obrazu.

Inne propozycje, takie jak element <picture>, są jeszcze bardziej szczegółowe. Co więcej, nie są one zgodne ze standardami, więc ich dostępność jest nawet bardziej rozbudowana niż atrybut srcset. JavaScript i rozwiązania po stronie serwera to jedyne alternatywne rozwiązania, ale mają one swoje wady, które opisujemy w innych artykułach.

W tym artykule omówimy kilka zastosowań obrazów powszechnie dostępnych w internecie i przedstawimy proste rozwiązania, które sprawdzają się na ekranach o dużej gęstości pikseli i zwykłych. Na potrzeby tej dyskusji każde urządzenie, które zgłasza wartość window.devicePixelRatio większą niż 1, może zostać uznane za wysoką wartość DPI. Oznacza to, że piksele CSS to nie to samo co piksele urządzenia, a obrazy są skalowane w górę.

Podsumowanie:

  • Jeśli to możliwe, używaj kodu CSS/SVG zamiast obrazów rastrowych.
  • Domyślnie używaj obrazów zoptymalizowanych pod kątem wyświetlaczy o dużej gęstości.
  • Do prostych rysunków i pikselowych grafik (np. logo) używaj plików PNG.
  • Używaj skompresowanych plików JPEG w przypadku obrazów w różnych kolorach (np. zdjęć).
  • Zawsze ustawiaj rozmiary dla pełnoletnich (za pomocą CSS lub HTML) dla wszystkich elementów graficznych.

Proste rysunki i Pixel art

Małych obrazów można często całkowicie uniknąć, korzystając z funkcji CSS lub SVG. W przypadku zaokrąglonych rogów nie trzeba np. używać obrazów, bo właściwość CSS border-radius jest powszechnie obsługiwana. Czcionki niestandardowe są również powszechnie obsługiwane, więc nie zalecamy korzystania z tekstu „grafiki”.

Jednak w niektórych przypadkach, np. w przypadku logo, obraz może być jedynym rozwiązaniem. Na przykład to logo Chrome ma naturalny rozmiar 256 x 256. Na wyświetlaczu Retina aliasy linii są widoczne po przekątnych i krzywych, przez co wygląda to nienaturalnie i słabo, zwłaszcza w porównaniu z wyraźnie wyrenderowanym tekstem:

Chrome 1x
PNG 1x

Wymiary naturalne: 256x256px, rozmiar zasobu: 31 kB, format: PNG

Przekonałeś(-aś)? Cieszę się. Użyjmy teraz obrazu w wysokiej gęstości. Może Cię kusić, by zaoszczędzić miejsce, przechowując logo w formacie JPEG, ale nie jest to dobry pomysł, bo zapisywanie logo i innych elementów graficznych w stratnym formacie zwykle powoduje powstawanie artefaktów. W tym przypadku przesadziłem problem, stosując bardzo wysoką kompresję, ale zauważam pasy na gradientach, plamki na białych tłach i rozmazane linie:

Chrome 2x
Jpeg 2x

Wymiary naturalne: 512x512px, rozmiar zasobu: 13 kB, format: JPEG

W przypadku stosunkowo małych obrazów należy użyć dwóch plików PNG. Pamiętaj, że różnica w rozmiarze między plikami PNG 1x i 2x jest zazwyczaj spora (w tym przypadku 52 kB). W przypadku logo jest to twarz witryny i pierwsza rzecz, jaką zobaczą użytkownicy. Jeśli będziesz zbyt wiele przeczytać w zamian za rozmiar, będzie to także ostatnia rzecz, jaką zobaczą użytkownicy.

Tak wygląda logo Chrome w całej okazałości, zmniejszone do połowy jego naturalnego rozmiaru, na potrzeby podwójnego wyświetlacza:

Chrome 2x
PNG 2x

Wymiary naturalne: 512x512px, rozmiar zasobu: 83 kB, format: PNG

Znaczniki do wyrenderowania powyżej są takie:

<img src="chrome2x.png" style="width: 256px; height: 256px;"/>

Zwróć uwagę, że określiłem szerokość i wysokość obrazu. Jest to konieczne, ponieważ naturalny rozmiar obrazu to 512 pikseli. Świetnie sobie radzi z wydajnością, bo mechanizm renderowania dobrze rozumie rozmiar elementu i nie wymaga zbyt wiele pracy, by go obliczyć.

Jedną z możliwych optymalizacji, która może pomóc, jest zmniejszenie 24-bitowego pliku PNG do wersji 8-bitowej z palety. Sprawdza się to w przypadku obrazów o niewielkiej liczbie kolorów, z logo Chrome. W tym celu możesz skorzystać z narzędzia takiego jak http://pngquant.org/. Widać tu trochę pasów, ale rozmiar pliku to tylko 13 kB, co daje 6-krotne oszczędności w porównaniu z oryginalnym plikiem PNG o wymiarach 512 x 512.

Chrome 2 x 8-bitowy
PNG 2 x 8bit

Wymiary naturalne: 512x512px, rozmiar zasobu: 13 kB, format: PNG, 8-bit palette

Obrazy w różnych kolorach

Napisałam artykuł o HTML5Rocks, w którym przeanalizowałem różne techniki tworzenia obrazów elastycznych. Zajmowałem się też kompresowaniem plików JPEG 1x i 2x oraz porównywaniem ich rozmiarów i jakości obrazu. Oto jeden z takich kafelków z artykułu powyżej:

Kafelek.

Oznaczyłem obrazy poziomem kompresji (na co wskazuje jakość JPEG), rozmiarem (w bajtach) oraz moją subiektywną opinią na temat ich porównywalnej jakości wizualnej (posortowanej według liczb). Ciekawe jest to, że bardzo skompresowany obraz 2x (oznaczony 3) jest mniejszy i wygląda lepiej niż nieskompresowany obraz 1x (oznaczony etykietą 4). Oznacza to, że między obrazami 4 i 3 udało nam się poprawić jakość obrazów, podwajając każdy z wymiarów i znacznie zwiększając kompresję, przy jednoczesnym zmniejszeniu rozmiaru o 2 KB.

Kompresja, wymiary i jakość wizualna

Chciałabym dowiedzieć się więcej o zaletach kompresji, wymiarów obrazu, jakości wizualnej i rozmiaru obrazu. Na podstawie tego badania przeprowadziłem badanie, który wysunął mi taką hipotezę:

Hipoteza

Przy odpowiedniej kompresji obraz o wielkości 2x będzie wyglądać tak samo jak ten sam obraz pod względem rozmiaru 1x przy innej (niższej) kompresji. W tym przypadku wysoko skompresowany obraz 2x będzie mniejszy niż obraz 1x.

Przetwarzanie

  • Mając obraz 2x, wygeneruj 1 x 1.
  • Kompresuj oba obrazy na różnych poziomach.
  • Utwórz stronę testową, na której oba zestawy obrazów wyświetlają się obok siebie.
  • Znajdź w dwóch zestawach miejsce, w którym obrazy są równoważne.
  • Zwróć uwagę na odpowiadające im rozmiary i poziomy kompresji.
  • Wypróbuj na wyświetlaczu 1x i 2x.

Udało mi się utworzyć aplikację do porównywania zdjęć obok siebie, podobną do widoku porównania w Lightroom. Ma to na celu wyświetlanie obrazów 1x i 2 obrazów obok siebie, ale także możliwość powiększenia dowolnej sekcji obrazu, aby uzyskać więcej szczegółów. Możesz też wybrać format JPEG lub WebP i zmienić jakość kompresji, aby zobaczyć porównanie rozmiaru pliku i jakości obrazów. Chodzi o zmianę ustawień kilku obrazów, określenie, jaka jakość kompresji, skalowanie i format a jakość obrazu będzie Ci odpowiadać, i użycie tego ustawienia dla wszystkich obrazów.

Zrzut ekranu z porównaniem

Możesz z niego korzystać. Możesz powiększyć obraz, wybierając podobszar, który chcesz powiększyć.

Analiza

Jakość obrazu to kwestia subiektywna. Poza tym konkretny przypadek użycia będzie prawdopodobnie decydować o tym, gdzie leżą priorytety w zakresie jakości obrazu, a jakiego rozmiaru pliku. Poza tym różne rodzaje funkcji związanych z obrazem reagują na skalowanie i jakość kompresji, więc uniwersalne rozwiązania niekoniecznie będą tu działać. To narzędzie pomaga stworzyć intuicję w zakresie kompresowania, skalowania i formatowania obrazów.

Gdy bawiliśmy się powiększaniem obrazów, szybko przyszło mi do głowy kilka rzeczy. Przede wszystkim wolę obrazów quality=30 dpr=2x od quality=90 dpr=1x, aby zwiększyć szczegółowość. Rozmiar tych obrazów również jest porównywalny (w przypadku płaszczyzny skompresowany obraz 2x ma rozmiar 76 KB, a obraz nieskompresowany 1x – 80 kB).

Wyjątkiem od tej reguły są obrazy z gradientem (quality<30). Są narażone na pojawianie się pasów kolorów, co jest równie szkodliwe, niezależnie od skali obrazu. Mogą to być na przykład próbki ptaków i samochodów w narzędziu.

Obrazy WebP wyglądają znacznie wyraźniej niż JPEG, zwłaszcza przy niskim poziomie kompresji. Wygląda na to, że takie pasy nie mają większego problemu. I wreszcie obrazy WebP są znacznie bardziej kompaktowe.

Zastrzeżenia i płetwa

Dbanie o dobre wygląd obrazów na wyświetlaczach o dużej gęstości to tylko połowa problemów z obrazami spowodowanych ogromną zmiennością ekranów. W niektórych przypadkach możesz chcieć wyświetlać zupełnie różne obrazy w zależności od rozmiaru widocznego obszaru. Na przykład zdjęcie portretowe Obamy może pasować do ekranu o wielkości telefonu, ale podstawka przed nim i flaga za nim, a niektóre lepiej pasują do wyświetlacza laptopa.

Celowo uniknąłem tego tematu „kierunku sztuki”, by skupić się tylko na zdjęciach o wysokiej rozdzielczości DPI. Ten problem można rozwiązać na wiele sposobów: za pomocą zapytań o multimedia i obrazów tła (w języku JavaScript), za pomocą nowych funkcji, np. image-set, lub na serwerze. Ten temat omawiamy w artykule Obrazy w wysokiej rozdzielczości dla pikseli o zmiennej gęstości pikseli.

Wprowadzę kilka nierozwiązanych problemów:

  • Wpływ dużej kompresji na wydajność. Jakie są konsekwencje dekodowania wysoce skompresowanych obrazów?
  • Jakie są konsekwencje związane ze zmianą rozmiaru obrazu przy wczytywaniu obrazu 1x na wyświetlaczu 1x?

Podsumujmy, zamiast korzystać z obrazów rastrowych, korzystaj z CSS i SVG. Jeśli obrazy rastrowe są bezwzględnie wymagane, używaj plików PNG w przypadku obrazów o ograniczonej liczbie palet i wielu jednolitych kolorów. Używaj plików JPEG w przypadku obrazów o wielu kolorach i gradientach. Ogromną zaletą tego podejścia jest to, że znaczniki pozostają praktycznie niezmienione. Programista stron internetowych musi tylko wygenerować podwójne zasoby i odpowiednio dopasować rozmiar obrazów w modelu DOM.

Aby dowiedzieć się więcej, przeczytaj artykuł Scotta Jehla na podobny temat. Niech Twoje zdjęcia będą wyraźne, a transmisja danych komórkowych będzie niska.