Strumienie wyjściowe
Podsystem aparatu działa wyłącznie w oparciu o potok ANativeWindow dla wszystkich rozdzielczości i formatów wyjściowych. Można skonfigurować wiele strumieni jednocześnie, aby wysyłać pojedynczą klatkę do wielu miejsc docelowych, takich jak procesor graficzny, koder wideo, RenderScript lub bufory widoczne dla aplikacji (bufory RAW Bayer, przetworzone bufory YUV lub bufory zakodowane w formacie JPEG).
W celu optymalizacji te strumienie wyjściowe muszą być skonfigurowane z wyprzedzeniem, a jednocześnie może istnieć tylko ograniczona ich liczba. Umożliwia to wstępne przydzielanie buforów pamięci i konfigurowanie sprzętu kamery, dzięki czemu w przypadku przesyłania żądań z wieloma lub różnymi potokami wyjściowymi nie wystąpią opóźnienia w ich realizacji.
Więcej informacji o gwarantowanych kombinacjach wyjściowych strumienia, które zależą od obsługiwanego poziomu sprzętu, znajdziesz w createCaptureSession().
Przycinanie
Przycinanie pełnej tablicy pikseli (na potrzeby zoomu cyfrowego i innych przypadków użycia, w których pożądane jest mniejsze pole widzenia) jest przekazywane za pomocą ustawienia ANDROID_SCALER_CROP_REGION. Jest to ustawienie dotyczące poszczególnych żądań, które można zmieniać w zależności od żądania. Ma to kluczowe znaczenie w przypadku płynnego cyfrowego powiększania.
Region jest zdefiniowany jako prostokąt (x, y, szerokość, wysokość), gdzie (x, y) to lewy górny róg prostokąta. Prostokąt jest zdefiniowany w układzie współrzędnych aktywnej tablicy pikseli czujnika, gdzie (0,0) to lewy górny piksel aktywnej tablicy pikseli. Dlatego szerokość i wysokość nie mogą być większe niż wymiary podane w polu informacji statycznych ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY. Minimalna dozwolona szerokość i wysokość są zgłaszane przez HAL w polu informacji statycznych ANDROID_SCALER_MAX_DIGITAL_ZOOM, które opisuje maksymalny obsługiwany współczynnik powiększenia. Minimalna szerokość i wysokość obszaru przycinania to:
{width, height} =
{ floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[0] /
ANDROID_SCALER_MAX_DIGITAL_ZOOM),
floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[1] /
ANDROID_SCALER_MAX_DIGITAL_ZOOM) }
Jeśli obszar przycięcia musi spełniać określone wymagania (np. musi zaczynać się od parzystych współrzędnych, a jego szerokość i wysokość muszą być parzyste), HAL musi wykonać niezbędne zaokrąglenie i zapisać ostateczny obszar przycięcia użyty w metadanych wyniku wyjściowego. Podobnie, jeśli HAL implementuje stabilizację wideo, musi dostosować region przycięcia wyniku, aby opisać region faktycznie uwzględniony w danych wyjściowych po zastosowaniu stabilizacji wideo. Ogólnie rzecz biorąc, aplikacja korzystająca z aparatu musi być w stanie określić pole widzenia na podstawie obszaru przycięcia, wymiarów czujnika obrazu i ogniskowej obiektywu.
Obszar kadrowania jest stosowany do wszystkich strumieni, które mogą mieć inne proporcje niż obszar kadrowania. Dlatego dokładny obszar czujnika używany w przypadku każdego strumienia może być mniejszy niż obszar kadrowania. Każdy strumień powinien zachowywać kwadratowe piksele i format obrazu, minimalnie przycinając zdefiniowany region przycięcia. Jeśli format transmisji jest szerszy niż obszar przycinania, należy dodatkowo przyciąć transmisję w pionie. Jeśli format transmisji jest węższy niż obszar przycinania, należy dodatkowo przyciąć transmisję w poziomie.
W każdym przypadku przycięty strumień musi być wyśrodkowany w pełnym obszarze przycięcia, a każdy strumień jest przycinany tylko w poziomie lub w pionie w stosunku do pełnego obszaru przycięcia, nigdy w obu kierunkach.
Jeśli na przykład zdefiniowane są 2 strumienie: 640 x 480 (format 4:3) i 1280 x 720 (format 16:9), poniżej przedstawiono oczekiwane obszary wyjściowe dla każdego strumienia w przypadku kilku przykładowych obszarów przycięcia na hipotetycznym czujniku o rozdzielczości 3 MP (2000 x 1500 pikseli).
Obszar przycięcia: (500, 375, 1000, 750) (format obrazu 4:3)
Przycięcie strumienia 640 x 480: (500, 375, 1000, 750) (równe obszarowi przycięcia)
Przycięcie strumienia 1280 x 720: (500, 469, 1000, 562)
Rysunek 1. Format obrazu 4:3
Region przycięcia: (500, 375, 1333, 750) (format obrazu 16:9)
Przycięcie strumienia 640x480: (666, 375, 1000, 750)
Przycięcie strumienia 1280x720: (500, 375, 1333, 750) (równe regionowi przycięcia)
Rysunek 2. Współczynnik proporcji 16:9
Obszar przycięcia: (500, 375, 750, 750) (format obrazu 1:1)
Przycięcie strumienia 640x480: (500, 469, 750, 562)
Przycięcie strumienia 1280x720: (500, 543, 750, 414)
Rysunek 3. Format obrazu 1:1
Ostatni przykład: strumień w formacie obrazu 1024 x 1024 zamiast strumienia 480p:
Region przycinania: (500, 375, 1000, 750) (format obrazu 4:3)
Przycięcie strumienia 1024 x 1024: (625, 375, 750, 750)
Przycięcie strumienia 1280 x 720: (500, 469, 1000, 562)
Rysunek 4. Format obrazu 4:3, kwadratowy
Ponowne przetwarzanie
Dodatkowa obsługa plików obrazów RAW jest zapewniana przez ponowne przetwarzanie danych RAW Bayer. Dzięki temu potok kamery może przetwarzać wcześniej zarejestrowany bufor RAW i metadane (całą klatkę, która została wcześniej nagrana), aby wygenerować nowe renderowane dane wyjściowe YUV lub JPEG.
Zoom
Na urządzeniach z Androidem 11 lub nowszym aplikacja może używać zoomu aparatu (cyfrowego i optycznego) za pomocą ustawienia ANDROID_CONTROL_ZOOM_RATIO.
Współczynnik powiększenia jest określany jako liczba zmiennoprzecinkowa. Zamiast używać ANDROID_SCALER_CROP_REGION do kadrowania i powiększania, aplikacja może używać ANDROID_CONTROL_ZOOM_RATIO do sterowania poziomem powiększenia oraz ANDROID_SCALER_CROP_REGION do kadrowania w poziomie i pionie, aby uzyskać proporcje obrazu inne niż natywne proporcje czujnika aparatu.
System wieloobiektywowy może zawierać więcej niż jeden obiektyw o różnych ogniskowych, a użytkownik może korzystać z zoomu optycznego, przełączając się między obiektywami.
Korzystanie z ANDROID_CONTROL_ZOOM_RATIO jest korzystne w tych sytuacjach:
- Powiększanie obrazu z obiektywu szerokokątnego do teleobiektywu: stosunek zmiennoprzecinkowy
zapewnia większą precyzję niż wartości całkowite
ANDROID_SCALER_CROP_REGION. - Oddalanie obrazu z obiektywu szerokokątnego do ultraszerokokątnego:
ANDROID_CONTROL_ZOOM_RATIOobsługuje oddalanie (<1,0f), aANDROID_SCALER_CROP_REGIONnie.
Współczynnik powiększenia: 2,0; 1/4 pierwotnego pola widzenia
Obszar przycięcia: (0, 0, 2000, 1500) (proporcje 4:3)
Przycięcie strumienia 640 x 480: (0, 0, 2000, 1500) (równe obszarowi przycięcia)
Przycięcie strumienia 1280 x 720: (0, 187, 2000, 1125)
Rysunek 5. Powiększenie 2,0x, format obrazu 4:3
Współczynnik powiększenia: 2,0; 1/4 pierwotnego pola widzenia
Obszar przycięcia: (0, 187, 2000, 1125) (format obrazu 16:9)
Przycięcie strumienia 640x480: (250, 187, 1500, 1125) (pillarboxing)
Przycięcie strumienia 1280x720: (0, 187, 2000, 1125) (równe obszarowi przycięcia)
Rysunek 6. 2-krotny zoom, format obrazu 16:9
Współczynnik powiększenia: 0,5; 4-krotne powiększenie oryginalnego pola widzenia (przełączanie z obiektywu szerokokątnego na obiektyw ultraszerokokątny)
Obszar przycięcia: (250, 0, 1500, 1500) (format obrazu 1:1)
Przycięcie strumienia 640x480: (250, 187, 1500, 1125) (letterboxing)
Przycięcie strumienia 1280x720: (250, 328, 1500, 844) (letterboxing)
Rysunek 7. Powiększenie 0,5x, format obrazu 1:1
Jak widać na powyższych wykresach, układ współrzędnych obszaru wycinania zmienia się na efektywne pole widzenia po powiększeniu i jest reprezentowany przez prostokąt o wymiarach: (0, 0, activeArrayWith, activeArrayHeight). To samo dotyczy obszarów AE/AWB/AF i twarzy. Ta zmiana układu współrzędnych nie dotyczy zdjęć w formacie RAW ani powiązanych z nimi metadanych, takich jak intrinsicCalibration i lensShadingMap.
Korzystając z tego samego hipotetycznego przykładu co powyżej i zakładając, że strumień wyjściowy 1 (640x480) to strumień wizjera, 2-krotny zoom można uzyskać na 2 sposoby:
zoomRatio = 2.0,scaler.cropRegion = (0, 0, 2000, 1500)zoomRatio = 1.0(domyślny),scaler.cropRegion = (500, 375, 1000, 750)
Aby aplikacja mogła ustawić wartość android.control.aeRegions jako lewy górny kwartał pola widzenia wizjera, ustaw wartość android.control.aeRegions na (0, 0, 1000, 750), a wartość android.control.zoomRatio na 2.0. Aplikacja może też ustawić wartość android.control.aeRegions na odpowiedni region (500, 375, 1000, 750) w przypadku android.control.zoomRatio w 1.0.