Problemy z przezroczystością

Jako autor udostępnianych w internecie grafik otrzymuję czasem pytania od osób chcących wykorzystać moje prace na swoich stronach dlaczego rysunki nie są przezroczyste. Rzeczywiście, udostępniane przez mnie rysunki posiadają białe tło. Ten materiał opisuje powody takiego stanu rzeczy.

Przezroczystość wprowadzono między innymi po to aby możliwe było ustawianie rysunku na dowolnym tle, jak się jednak okazuje istnieją pewne problemy z nią związane. Tabela 1 przedstawia istotę problemu - na różnych tłach (A,B,C) umieszczane są te same obrazy.

Opracowanie dotyczy formatów graficznych obsługujących tryb indeksowany i przezroczystość - png, gif (oraz roboczy format Gimpa - xcf na czas pracy z rysunkiem). Do tego typu grafik zalecam i wyłącznie stosuję jako końcowy format png, który zapewnia lepszą niż gif kompresję, możliwość zapisu dodatkowo w trybie RGB i odcieniach szarości (gif tylko w trybie indeksowanym), oraz, co bardzo ważne został opracowany przez wspólnotę OpenSource.

Tabela 1. Możliwości dopasowania grafik do wybranego tła

L.p. A B C Opis
1) Obraz zindeksowany w fatalny sposób; 1294 bajty

Przezroczysty obraz został bez dodatkowych zabiegów zindeksowany do około 200 kolorów co doprowadziło do pojawienia się poszarpanych krawędzi. Czy ktoś chce takiego boćka na stronie? Nie? Więc rozważamy pozostałe możliwości.

2) Obraz w trybie RGB; 2859 bajtów

Jeżeli używasz MS Internet Explorer to prawdopodobnie ten rysunek nie jest u Ciebie przezroczysty. Zamiast przezroczystości pojawia się wówczas (losowy?) kolor zazwyczaj niepasujący do tła. W Mozilli problem ten nie występuje. Zwróć uwagę na stosunkowo duży rozmiar pliku, ponad trzy razy większy niż właściwie zindeksowane obrazy poniżej.

3) Obraz spłaszczony (podstawienie wybranego koloru w miejsce przezroczystości) z białym tłem, a następnie zindeksowany do 20 kolorów; 854 bajty

Najprosztszy sposób przygotowania prawidłowo zindeksowanego obrazu to spłaszczenie obrazu z użyciem docelowego koloru tła, a następnie zindeksowanie go. Widać (w kolumnie A), że 20 kolorów zapewnia w przypadku tego rysunku jakość nie ustępującą trybowi RGB. Gdyby rysunek zawierał więcej kolorów wówczas indeksując go do odpowiednio większej ilości kolorów (max. 255) uzyskano by również zadowalający efekt.

4) Obraz z białą otoczką zindeksowany do 20 kolorów; 947 bajtów

Taki obraz wymaga odrobinę więcej pracy, ale jak widać mimo przygotowania go z myślą o białym tle dość dobrze sprawdza się również na w miarę jasnym - tutaj żółtym tle. Jest to prawdopodobnie najwłaściwszy sposób przygotowania indeksowanych grafik.

  1. Problem poszarpanych krawędzi

Dopóki praca odbywa się w trybie RGB (<Obraz> -> Obraz -> Tryb) bociek sprawuje się bardzo dobrze. W oknie warstw (<Obraz> -> Warstwy -> Warstwy, kanały i ścieżki <Ctrl+l>) można oglądać boćka na kolejnych tłach przesuwając warstwy na bliższy/dalszy plan lub ukrywając warstwy klikając na wybranym symbolu oka.


Rysunek 1. Bezproblemowa praca z obrazami w trybie RGB

Powiększając obraz (znaki =/-) do 600% można zauważyć, że obraz zawiera częsciowo przezroczyste piksele na granicy tła i konturu rysunku. Piksele te należy traktować jako czarne, częściowo przezroczyste - nie szare (zobacz wartości Alfa określające przezroczystość). Na rysunku 2 widać, że pod częściowo przezroczystymi pikselami znajduje się kolor czerwony na pierwszym i biały na drugim obrazie.


Rysunek 2. Przezroczystość pikseli w obrazach RGB

Obrazy RGB budowane są z trzech kanałów Czerwony/Zielony/Niebieski. Na informację o każdym z kanałów przeznaczany jest

1 bajt=8 bitów=2^8=256 poziomów odcieni danego kanału.

Taki obraz nazywa się wówczas obrazem 24 bitowym (3 kanały po 8 bitów). Owe 24 bity przypadają na każdy pojedynczy piksel. Obraz RGB bez kompresji (bitmapa) o wielkości 2x2 piksele zajmowałby więc 2x2x3 bajty = 12 bajtów, niezależnie od używanych kolorów (nie licząc nagłówka pliku).

Obraz z kanałem alfa, zwany czasem RGBA używa dodatkowo 8 bitów na informację o przezroczystości co daje w sumie obraz 32 bitowy (to że obraz jest 32 bitowy nie oznacza, że musi posiadać kanał alfa - można np. przeznaczyć więcej bitów na informację o RGB uzyskując lepszą jakość). Przezroczystość występująca w obrazach RGB może przyjmować wartości od 0 do 255 (0 do 100%). Zmieniając parametr Nieprzepuszczalność w oknie warstw można przechodzić między stanami prezentowanymi na rysunku 3. Dla przedstawionych rysunków ustawiono wartości nieprzepuszczalność dla warstwy bociek na kolejno: 100, 40, 20.


Rysunek 3. Zmiana wartości Nieprzepuszczalność w obrazach RGB

Stąd blisko już do wyjaśnienia istoty postawionego w temacie problemu. Tryb indeksowany pozwala na ustawianie tylko dwóch poziomów przezroczystości (1 bit informacji zamiast 8 bitów czyli kanału Alfa w RGB). W trybie indeksowanym piksel może być albo całkowicie przezroczysty albo całkowicie nieprzezroczysty. Poniżej zaprezentowano zmianę obrazu przy przejściu z RGB do trybu indeksowanego (<Obraz> -> Obraz -> Tryb -> Indeksowany). Rysunek zawiera przezroczystą warstwę bociek i warstwę białą pod spodem. Informacja o stu poziomach przezroczystości w warstwie bociek musi zostać zredukowana do dwóch poziomów. Jak wyjaśniano wcześniej piksele konturu boćka należało traktować jako częściowo przezroczyste, nie szare. W efekcie indeksowania owe przezroczyste-czarne piksele staną się teraz albo całkowicie czarne (piksele o stopniu nieprzepuszczalności większym niż 50) lub całkowicie znikną (nieprzepuszczalność mniejsza niż 50) zgodnie z regułą dwóch możliwych dla pikseli stanów. Warto sprawdzić co dzieje się z jednobitowo-przezroczystym rysunkiem indeksowanym przy przechodzeniu przez poziom 50 na suwaku Nieprzepuszczalność.


Rysunek 4. Niewłaściwe przejście z trybu RGB do trybu indeksowanego


Rysunek 5. Efekt końcowy błędnego przejścia do trybu indeksowanego

  1. Prawidłowe przygotowanie grafik z wykorzystaniem pierwotnego źródła grafik

W skrócie:

    1. Zdobycie wersji xcf dużego formatu;

    2. Spłaszczenie obrazu z kolorem docelowego tła;

    3. Opcjonalnie wprowadzenie przezroczystości z pozostawieniem cienkiej warstwy przy krawędzi obiektu;

    4. Przeskalowanie i zindeksowanie obrazu;

    1. Ostateczny rysunek udostępniany w sieci często jest pomniejszoną wersją rysunku większych rozmiarów. Jako że możliwości edycyjne ostatecznych wersji rysunków są zazwyczaj ograniczone należy zdobyć pierwotną wersję obrazu. Jeżeli autor miał na uwadze możliwości dalszej modyfikacji obrazu prawdopodobnie zachował grafikę jako plik xcf, który jest naturalnym formatem gimpa. Pierwotny obraz xcf może zawierać warstwy (czego nie potrafi żaden z ostatecznych formatów - png/jpeg/bmp/gif), prawdopodobnie będzie przezroczysty i wielokrotnie większy niż ostateczny plik, co daje spore możliwości modyfikacji.


Rysunek 6. Duży obraz daje spore możliwości modyfikacji

W dalszej części przedstawiono opis przygotowania rysunku z zieloną otoczką. Jak już wcześniej wyjaśniono rysunek taki będzie właściwie dopasowany do strony www z zielonym tłem. Obraz http://www.inf.sgsp.edu.pl/pub/MALUNKI_DUZE/PLD_DUZE/4_powered.xcf.gz należy załadować do gimpa.

2.2) Rysunek powinien być precyzyjnie dopasowany do danej strony dlatego należy ustalić wartości RGB koloru tła strony. Można to zrobić na dwa sposoby:

2.2.1) Przeglądając źródło html strony i odnajdując triplet szesnastkowy lub dziesiętny tła, np:

<BODY BGCOLOR="#ffefd3"> lub <body background-color: rgb(255,239,211);>

Po ustaleniu wartości koloru można go ustawić w gimpie poprzez menu Wybór koloru.


Rysunek 7. Wybór koloru

2.2.2) Pobierając zrzut ekranu strony html w gimpie (Plik -> Pobierz -> Zrzut ekranu) i pobranie pipetą koloru.


Rysunek 8. Pobranie koloru pipetą i ustawienie go jako kolor tła

W obydwu przypadkach należy ustalony kolor ustawić jako kolor tła w gimpie. Pokazuje to operacja (3) wykorzystana w drugiej metodzie - strzałki zamieniają kolor narzędzia z kolorem tła. W dalszym etapie rysunek będzie spłaszczony z podstawieniem koloru tła w miejsce przezroczystości i połączeniem wszystkich warstw w jedną. Kolor tła powinien zostać ustawiony jak na rysunku 9.


Rysunek 9. Kolor narzędzia i tła

Ostatni moment na modyfikację warstw zanim rysunek zostanie spłaszczony. Można usunąć niepotrzebne warstwy, poprzesuwać je względem siebie lub dodać nowe. Rysunek jest już w zasadzie gotowy do umieszczenia go na stronie jako prosokąt z zielonym tłem. Wystarczy go przeskalować, spłaszczyć i zindeksować (punkt 2.4).

2.3) W celu uzyskania przezroczystego obrazu z zieloną otoczką należy wykonać jeszcze kilka dodatkowych czynności. Dwukrotne kliknięcie na narzędziu różdżka (zaznaczanie sąsiednich obszarów) w oknie gimpa otworzy okno z opcjami narzędzia. Próg należy ustawić na minimalną, większą od zera wartość (można pomagać sobie kursorami). Następnie należy kliknąć różdżką na jednym z zielonych pikseli tła. Parametr próg decyduje o stopniu podobieństwa kolorów. Niska wartość progu gwarantuje, że tylko piksele zielone zostaną zaznaczone.


Rysunek 10. Sposób zaznaczenia tylko w pełni zielonego koloru

Spłaszczenie obrazu spowodowało usunięcie kanału alfa. Kanał alfa musi się ponownie znaleźć w obrazie, aby możliwe było wycięcie zaznaczonych, zielonych pikseli i uzyskanie w to miejsce przezroczystości - prawy przycisk myszy na warstwie w oknie warstw -> Dodaj kanał alfa. Wycięcie zaznaczonych pikseli przeprowadza sie przez <Obraz> -> Edycja -> Wytnij / ctrl+x. Rysunek można teraz przeskalować, a później zindeksować. Jeżeli wszystko przeprowadzono właściwie obraz powinien wyglądać jak poniżej1


Rysunek 11. Przygotowany poprawnie obraz z otoczką

Dlaczego tym razem przezroczysty obraz można zindeksować otrzymując pozytywne efekty - brak poszarpanych krawędzi? Na to pytanie odpowiada rysunek 12. W wyniku spłaszczenia warstwy bociek z zielonym tłem dawniej przezroczyste-czarne boćkowe piksele wymieszały się z zielonym kolorem. Podczas takiej operacji (to samo dotyczy łączenia dwóch lub więcej warstw w jedną) nowo powstałe piksele uzyskują wypadkowy kolor i stają się całkowicie nieprzezroczyste - nie są już częściowo przezroczyste - szare. W czasie skalowania rysunku powstały nowe przezroczyste-zielone piksele. Jak już wiadomo w wyniku indeksowania część przezroczysto-zielonych pikseli (przy krawędzi) zostanie usunięta, a część stanie się całkowicie nieprzezroczysta. Piksele znajdujące się dalej od krawędzi są całkowicie nieprzezroczyste (nie zmieniły swojego stopnia przezroczystości przy skalowaniu obrazu) więc ten problem ich nie dotyczy.


Rysunek 12. Zmiana poziomu przezroczystości dotyczy tylko pikseli przy krawędzi

Jak widać można uzyskać dobrej jakości indeksowane przezroczyste obrazy. Najważniejszy wniosek wynikający z tego dokumentu można sformułować następująco:

Obiekty znajdujące się na przezroczystych warstwach wywołują efekt poszarpanych krawędzi podczas przejścia z trybu RGB do indeksowanego. Aby temu zapobiec spłaszcz obraz przed zindeksowaniem lub wprowadź do rysunku dodatkowe piksele, które wezmą na siebie problem przejścia do prostszego, dwustanowego modelu przezroczystości.

2.4) Ostatnim etapem jest przygotowanie obrazu do umieszczenia na stronie. Pierwszą czynnością powinno być przeskalowanie obrazu (<Obraz> -> Obraz -> Przeskaluj obraz). Następnie obraz należy spłaszczyć poprzez <Obraz> -> Warstwy -> Spłaszcz obraz. Ostatnią operacją powinno być zindeksowanie obrazu, dzięki czemu będzie on zajmował mniej miejsca (<Obraz> -> Obraz -> Tryb -> Indeksowany).

Należy pamiętać o tym aby nie skalować obrazów indeksowanych gdyż daje to fatalne efekty. Jeżeli obraz jest już w trybie indeksowanym należy najpierw zmienić tryb na RGB i dopiero wówczas przeskalować. Indeksowanie powinno być zawsze ostatnią czynnością przed zapisem obrazu.

Opracował:

Karol Kreński, mimooh at inf sgsp edu pl









Istnieje alternatywna, prostsza metoda utworzenia otoczki wokół obiektu wykorzystująca filtr Dodaj jarzenie. Filtry ułatwiają wiele czynności lecz ze względu na automatykę mają małą wartość dydaktyczną. Omawiany filtr jest uruchamiany przez <Obraz> -> Filtry -> Renderowanie -> Dodaj jarzenie.

1