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ępują 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) opisuje 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ć wynikowy region przycięcia, 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 matrycy i ogniskowej obiektywu.
Obszar kadrowania jest stosowany do wszystkich strumieni, które mogą mieć inne proporcje niż obszar kadrowania, więc 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, transmisję należy dodatkowo przyciąć w pionie. Jeśli format transmisji jest węższy niż obszar przycinania, transmisję należy dodatkowo przyciąć w poziomie.
W każdym przypadku przycięcie strumienia musi być wyśrodkowane w pełnym regionie przycięcia, a każdy strumień jest przycinany tylko w poziomie lub w pionie w stosunku do pełnego regionu przycięcia, nigdy w obu kierunkach.
Jeśli na przykład zdefiniowane są 2 strumienie: strumień 640 x 480 (format 4:3) i strumień 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 przycinania: (500, 375, 1000, 750) (format obrazu 4:3)
Przycinanie strumienia 640 x 480: (500, 375, 1000, 750) (równy obszarowi przycinania)
Przycinanie 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 kwadratowym 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, kwadrat
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_RATIO
obsługuje oddalanie obrazu (<1,0 f), aANDROID_SCALER_CROP_REGION
nie.
Współczynnik powiększenia: 2,0; 1/4 pierwotnego pola widzenia
Obszar przycięcia: (0, 0, 2000, 1500) (format obrazu 4:3)
Przycięcie strumienia 640x480: (0, 0, 2000, 1500) (równe obszarowi przycięcia)
Przycięcie strumienia 1280x720: (0, 187, 2000, 1125)

Rysunek 5. Powiększenie 2,0, 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ówny 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 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 przycięcia 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 ustawiła wartość android.control.aeRegions
jako lewą górną ćwiartkę 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)
dla android.control.zoomRatio
w 1.0
.