Zrozumienie pojęć Canvas i Surface

114

Staram się zrozumieć proces rysowania, SurfaceViewa tym samym cały Surface/ Canvas/ Bitmapsystem, który jest używany w Androidzie.

Przeczytałem wszystkie artykuły i strony dokumentacji API, które udało mi się znaleźć na stronie dla programistów Androida, kilka samouczków z grafiką Androida, kod źródłowy LunarLander i to pytanie .

Proszę, powiedz mi, które z tych stwierdzeń są prawdziwe, a które nie, i dlaczego.

  1. Canvasma swoje własne Bitmapdołączone do niego. Surfacema swoje własne Canvasdołączone do niego.
  2. Wszystkie Viewokna współdzielą to samo, Surfacea zatem współużytkują to samo Canvas.
  3. SurfaceViewjest podklasą View, która, w przeciwieństwie do innych Viewpodklas i Viewsama w sobie, ma swoje własne Surfacerysunki.

Jest jeszcze jedno dodatkowe pytanie:

  • Po co jest potrzebna Surfaceklasa, skoro już istnieje Canvasdla operacji wysokiego poziomu z bitmapą. Podaj przykład sytuacji, w której Canvasnie nadaje się do wykonywania pracy, którą Surfacemożna wykonać.
fyodorananiev
źródło
2
Dokument
fadden

Odpowiedzi:

223

Oto kilka definicji:

  • Powierzchnia to obiekt zawierający piksele, które są komponowane na ekranie. Każde okno, które widzisz na ekranie (okno dialogowe, aktywność na pełnym ekranie, pasek stanu) ma własną powierzchnię, do której wciąga, a Surface Flinger renderuje je na ostateczny ekran w prawidłowej kolejności Z. Powierzchnia zwykle ma więcej niż jeden bufor (zwykle dwa) do renderowania podwójnie buforowanego: aplikacja może rysować swój następny stan interfejsu użytkownika, podczas gdy powierzchnia odrzutnika komponuje ekran przy użyciu ostatniego bufora, bez konieczności czekania na zakończenie aplikacji rysunek.

  • Okno przypomina w zasadzie okno na pulpicie. Ma pojedynczą powierzchnię, w której renderowana jest zawartość okna. Aplikacja współdziała z Menedżerem okien w celu tworzenia okien; Menedżer okien tworzy powierzchnię dla każdego okna i przekazuje ją aplikacji do rysowania. Aplikacja może rysować na powierzchni, co chce; dla Menedżera okien jest to tylko nieprzezroczysty prostokąt.

  • Widok to interaktywny element interfejsu użytkownika wewnątrz okna. Okno ma dołączoną pojedynczą hierarchię widoków, która zapewnia całe zachowanie okna. Ilekroć okno wymaga ponownego narysowania (na przykład, ponieważ widok sam się unieważnił), jest to robione na powierzchni okna. Powierzchnia jest zablokowana, co zwraca kanwę, której można użyć do narysowania na niej. Przechodzenie przez rysowanie jest wykonywane w dół hierarchii, przekazując kanwę w dół dla każdego widoku, aby narysować jego część interfejsu użytkownika. Po zakończeniu Surface jest odblokowywany i publikowany, dzięki czemu właśnie narysowany bufor jest zamieniany na pierwszy plan, aby następnie zostać złożony na ekranie przez Surface Flinger.

  • SurfaceView to specjalna implementacja View, która tworzy również własną dedykowaną powierzchnię, do której aplikacja może bezpośrednio rysować (poza normalną hierarchią widoków, która w przeciwnym razie musi współużytkować pojedynczą powierzchnię dla okna). Sposób, w jaki to działa, jest prostszy, niż można by się spodziewać - wszystko, co robi SurfaceView, to poproszenie menedżera okien o utworzenie nowego okna, nakazanie mu uporządkowania tego okna bezpośrednio za lub przed oknem SurfaceView i ustawienie go tak, aby pasowało gdzie SurfaceView pojawia się w oknie zawierającym. Jeśli powierzchnia jest umieszczana za oknem głównym (w kolejności Z), SurfaceView również wypełnia swoją część okna głównego przezroczystością, aby powierzchnia była widoczna.

  • Mapa bitowa to tylko interfejs do niektórych danych pikseli. Piksele mogą być przydzielane przez samą Bitmapę, gdy tworzysz ją bezpośrednio, lub mogą wskazywać na piksele, których nie posiada, na przykład to, co wewnętrznie zdarza się podpiąć kanwę do powierzchni w celu rysowania. (Mapa bitowa jest tworzona i wskazywana na bieżący bufor rysunku powierzchni).

Należy również pamiętać, że, jak to sugeruje, SurfaceView jest dość ciężkim obiektem. Jeśli masz wiele SurfaceViews w konkretnym interfejsie użytkownika, zatrzymaj się i zastanów się, czy jest to naprawdę potrzebne. Jeśli masz więcej niż dwa, prawie na pewno za dużo.

hackbod
źródło
Dziękuję Ci bardzo! Odpowiedź wyjaśniła sprawę. Część dotycząca podłączania Canvas do Surface jest jednak niejasna. Nie wyobrażam sobie, gdzie taka operacja jest potrzebna. Czy następny może być przykład tej operacji: rysowanie mapy bitowej na kanwie, pozyskanej z SurfaceHolder metodą lockCanvas ()?
fyodorananiev
1
Tak dzieje się rysowanie Canvas jest interfejsem API do rysowania 2D. Jeśli zamierzasz rysować na powierzchni, musisz utworzyć Canvas, które wskazuje na jego bufor, aby użyć interfejsu API rysowania Canvas 2d do rysowania do niego.
hackbod
6
Oprócz #hackbod'sodpowiedzi SurfaceViewmożna również renderować z wątku wtórnego, co nie jest możliwe w przypadku Viewobiektów
Mohanraj Balasubramaniam
47

Koncepcyjne omówienie okna, powierzchni, kanwy i mapy bitowej

Oto bardzo podstawowy i prosty przegląd pojęciowy dotyczący interakcji między oknem, powierzchnią, kanwą i mapą bitową.
Czasami reprezentacja wizualna bardzo pomaga w zrozumieniu pokręconych koncepcji.
Mam nadzieję, że ta grafika mogłaby komuś pomóc.

Sabeeh
źródło
4
Obrazy wizualne są lepsze niż tekst: D
Maveň ツ
18

Bitmapa to po prostu opakowanie dla kolekcji pikseli. Pomyśl o tym jako o tablicy pikseli z innymi wygodnymi funkcjami.

Canvas to po prostu klasa zawierająca wszystkie metody rysowania. Jest podobna do klasy Graphics w AWT / Swing, jeśli jesteś z nią zaznajomiony. Cała logika dotycząca rysowania koła, ramki itp. Znajduje się w kanwie. Kanwa rysuje się na mapie bitowej lub otwartym kontenerze GL, ale nie ma powodu, aby w przyszłości mogła zostać rozszerzona w celu rysowania na innych typach rastrów.

SurfaceView to widok zawierający Surface. Powierzchnia jest podobna do mapy bitowej (zawiera magazyn pikseli). Nie wiem, w jaki sposób jest zaimplementowany, ale wyobrażam sobie, że jest to rodzaj opakowania bitmapy z dodatkowymi metodami dla rzeczy, które są bezpośrednio związane z wyświetlaniem na ekranie (to jest powód dla powierzchni, mapa bitowa jest zbyt ogólna). Możesz pobrać kanwę ze swojej powierzchni, która naprawdę uzyskuje kanwę skojarzoną z bazową mapą bitową.

Twoje pytania.

1. płótno ma dołączoną własną bitmapę. Surface ma dołączone własne płótno.

Tak, płótno działa na mapie bitowej (lub otwartym panelu GL). Surface zapewnia kanwę działającą na dowolnym urządzeniu Surface używanym do przechowywania pikseli w stylu mapy bitowej.

2. Wszystkie widoki okna mają tę samą powierzchnię, a zatem mają tę samą kanwę.

Nie. Możesz mieć dowolną liczbę widoków powierzchni.

3.SurfaceView jest podklasą View, która w przeciwieństwie do innych podklas View i samego View ma własną powierzchnię do rysowania.

Tak. Podobnie jak ListView jest podklasą View, która ma własną strukturę danych List. Każda podklasa View robi coś innego.

sksamuel
źródło
1
A więc Bitmapczy Surfacesą to tylko różne rodzaje sklepów pikselowych i czy Canvasmożna zawinąć którykolwiek z nich?
fyodorananiev
2
Zasadniczo tak. Z wyjątkiem tego, że Canvas nie może pisać na powierzchni, działa na czymkolwiek Surface używa jako własnego magazynu pikseli (bez patrzenia na źródło Androida nie mogę powiedzieć na pewno, co to jest). Prawdopodobnie jest to jakieś rozszerzenie Bitmap, ponieważ Canvas dostarcza tylko konstruktorów dla Bitmap i GL.
sksamuel
Świetna pomoc, dziękuję! O odpowiedzi 2. W moim pytaniu miałem na myśli standardowe widoki, a nie SurfaceViews. Załóżmy, że mam RelativeLayout z dużą ilością pól i przycisków. W tym przypadku, czy powierzchnia jest dołączona do całego okna i współdzielona przez wszystkie widoki w hierarchii widoków?
fyodorananiev
1
Pamiętaj, że Surface to po prostu zbiór pikseli. Tak więc każdy widok powierzchni ma swoją własną powierzchnię i każdy z nich może być renderowany na innej części ekranu. Nie muszą wypełniać ekranu (chociaż jest to powszechne użycie, aby renderować grafikę w grze pełnoekranowej).
sksamuel
1
Naprawdę nie pomyślałbym o bitmapie i powierzchni jako równoważnych. Powierzchnia to obiekt, o którym wie Surface Flinger, twórca okien. Oznacza to, że jest to coś bezpośrednio widocznego na ekranie, ma na ekranie kolejność Z itp.
hackbod