自 2025 年 3 月 27 日起,我們建議您使用 android-latest-release
而非 aosp-main
建構及貢獻 AOSP。詳情請參閱「Android 開放原始碼計畫變更」。
輸出串流、裁剪和縮放
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
輸出串流
相機子系統只會在所有解析度和輸出格式的 ANativeWindow 管道上運作。您可以一次設定多個串流,將單一影格傳送至多個目標,例如 GPU、影片編碼器、RenderScript 或應用程式可見的緩衝區 (RAW Bayer、經處理的 YUV 緩衝區或 JPEG 編碼緩衝區)。
為了進行最佳化,這些輸出串流必須事先設定,且一次只能存在有限的串流。這可讓您預先配置記憶體緩衝區和相機硬體設定,因此在提交請求時,即使列出多個或不同的輸出管道,也不會延遲或延遲滿足要求。
如要進一步瞭解依據支援的硬體等級而提供的保證串流輸出組合,請參閱 createCaptureSession()
。
裁剪
透過 ANDROID_SCALER_CROP_REGION 設定,可傳達全像素陣列的裁剪方式 (適用於數位變焦和其他需要較小 FOV 的用途)。這是個別要求設定,可依據個別要求變更,這對於實現流暢的數位縮放效果至關重要。
區域定義為矩形 (x、y、寬度、高度),其中 (x、y) 會描述矩形的左上角。矩形是在感應器有效像素陣列的座標系統中定義,其中 (0,0) 是有效像素陣列的左上角像素。因此,寬度和高度不得大於 ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY 靜態資訊欄位中回報的尺寸。HAL 會透過 ANDROID_SCALER_MAX_DIGITAL_ZOOM 靜態資訊欄位回報允許的最小寬度和高度,該欄位會說明支援的最大縮放係數。因此,裁剪區域的寬度和高度下限如下:
{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) }
如果裁剪區域需要符合特定需求 (例如,需要從偶數座標開始,且寬度/高度必須為偶數),HAL 就必須進行必要的捨入,並寫出輸出結果中繼資料中使用的最終裁剪區域。同樣地,如果 HAL 實作影片防震功能,則必須調整結果裁剪區域,以便描述套用影片防震功能後,輸出內容實際包含的區域。一般來說,使用相機的應用程式必須能夠根據裁剪區域、影像感應器的尺寸和鏡頭焦距,判斷所接收的視野範圍。
裁剪區域會套用至所有串流,而這些串流的顯示比例可能與裁剪區域不同,因此每個串流使用的確切感應器區域可能會小於裁剪區域。具體來說,每個串流都應盡可能保留方形像素及其顯示比例,並進一步裁剪定義的裁剪區域。如果串流的顯示比例比裁剪區域寬,則應進一步垂直裁剪串流;如果串流的顯示比例比裁剪區域窄,則應進一步水平裁剪串流。
無論如何,串流裁剪區域都必須置中於完整裁剪區域內,且每個串流只能相對於完整裁剪區域進行水平或垂直裁剪,絕不能同時進行。
舉例來說,如果定義了兩個串流 (640x480 串流 [4:3 顯示比例] 和 1280x720 串流 [16:9 顯示比例]),下方會示範在假設的 3 MP (2000 x 1500 像素陣列) 感應器上,每個串流的預期輸出區域,以及幾個範例裁剪區域。
裁剪區域:(500, 375, 1000, 750) (4:3 顯示比例)
640x480 串流裁剪:(500, 375, 1000, 750) (與裁剪區域相同)
1280x720 串流裁剪:(500, 469, 1000, 562)
圖 1. 顯示比例 4:3
裁剪區域:(500, 375, 1333, 750) (16:9 顯示比例)
640x480 串流裁剪:(666, 375, 1000, 750)
1280x720 串流裁剪:(500, 375, 1333, 750) (等於裁剪區域)
圖 2. 顯示比例 16:9
裁剪區域:(500, 375, 750, 750) (1:1 顯示比例)
640x480 串流裁剪:(500, 469, 750, 562)
1280x720 串流裁剪:(500, 543, 750, 414)
圖 3. 顯示比例 1:1
最後一個範例是 1024x1024 正方形顯示比例串流,而不是 480p 串流:
裁剪區域:(500, 375, 1000, 750) (4:3 顯示比例)
1024x1024 串流裁剪:(625, 375, 750, 750)
1280x720 串流裁剪:(500, 469, 1000, 562)
圖 4. 4:3 顯示比例,正方形
重新處理
針對 Bayer 格式原始資料,提供額外的原始圖片檔案支援功能。這項支援功能可讓相機管道處理先前擷取的 RAW 緩衝區和中繼資料 (先前記錄的整個影格),產生新的算繪 YUV 或 JPEG 輸出內容。
Zoom
對於搭載 Android 11 以上版本的裝置,應用程式可以透過 ANDROID_CONTROL_ZOOM_RATIO
設定使用相機的數位和光學變焦功能。
變焦比例定義為浮點因數。應用程式可以使用 ANDROID_CONTROL_ZOOM_RATIO
控制縮放等級,並使用 ANDROID_SCALER_CROP_REGION
進行水平和垂直裁剪,以便取得與原生攝影機感應器不同的顯示比例。ANDROID_SCALER_CROP_REGION
多鏡頭系統可能包含多個焦距不同的鏡頭,使用者可以透過切換鏡頭使用光學變焦功能。在下列情況下,使用 ANDROID_CONTROL_ZOOM_RATIO
可帶來許多好處:
- 從廣角鏡頭縮放至望遠鏡頭:浮點比率相較於
ANDROID_SCALER_CROP_REGION
的整數值,可提供更精確的結果。
- 從廣角鏡頭縮小到超廣角鏡頭:
ANDROID_CONTROL_ZOOM_RATIO
支援縮小功能 (<1.0f),但 ANDROID_SCALER_CROP_REGION
不支援。
為說明這一點,以下列舉幾個使用前面章節定義的假想相機,並以不同縮放比例、裁剪區域和輸出串流的情況為例。
縮放比例:2.0;原始視野範圍的 1/4
裁剪區域:(0, 0, 2000, 1500) (4:3 顯示比例)
640x480 串流裁剪:(0, 0, 2000, 1500) (等於裁剪區域)
1280x720 串流裁剪:(0, 187, 2000, 1125)
圖 5. 2.0 倍縮放,4:3 顯示比例
縮放比例:2.0;原始視野範圍的 1/4
裁剪區域:(0, 187, 2000, 1125) (16:9 顯示比例)
640x480 串流裁剪:(250, 187, 1500, 1125) (以固定寬度顯示)
1280x720 串流裁剪:(0, 187, 2000, 1125) (等於裁剪區域)
圖 6. 2.0 倍縮放,顯示比例 16:9
變焦倍率:0.5;原始視野的 4 倍 (從廣角鏡頭切換為超廣角鏡頭)
裁剪區域:(250, 0, 1500, 1500) (1:1 顯示比例)
640x480 串流裁剪:(250, 187, 1500, 1125) (上下黑邊)
1280x720 串流裁剪:(250, 328, 1500, 844) (上下黑邊)
圖 7. 縮放 0.5、顯示比例 1:1
如上圖所示,裁剪區域的座標系統會變更為縮放後的有效視野,並以矩形表示,其尺寸為:(0
、0
、activeArrayWith
、activeArrayHeight
)。AE/AWB/AF 區域和臉孔也適用相同的做法。這項座標系統變更不適用於 RAW 擷取作業及其相關中繼資料,例如 intrinsicCalibration
和 lensShadingMap
。
使用上述相同的假設示例,並假設輸出串流 #1 (640x480) 是取景器串流,您可以透過下列任一方式達到 2.0 倍變焦:
zoomRatio = 2.0
、scaler.cropRegion = (0, 0, 2000, 1500)
zoomRatio = 1.0
(預設)、scaler.cropRegion = (500, 375, 1000, 750)
如要讓應用程式將 android.control.aeRegions
設為觀景窗視野左上角的四分之一,請將 android.control.aeRegions
設為 (0, 0, 1000, 750)
,並將 android.control.zoomRatio
設為 2.0
。或者,應用程式可以將 android.control.aeRegions
設為 1.0
的 android.control.zoomRatio
的 (500, 375, 1000, 750)
等同區域。
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-06-12 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-06-12 (世界標準時間)。"],[],[],null,["# Output streams, cropping, and zoom\n\nOutput streams\n--------------\n\nThe camera subsystem operates solely on the ANativeWindow-based pipeline for\nall resolutions and output formats. Multiple streams can be configured at\none time to send a single frame to many targets such as the GPU, the video\nencoder,\n[RenderScript](/docs/core/architecture/vndk/renderscript),\nor app-visible buffers (RAW Bayer, processed YUV\nbuffers, or JPEG-encoded buffers).\n\nAs an optimization, these output streams must be configured ahead of time, and\nonly a limited number may exist at once. This allows for pre-allocation of\nmemory buffers and configuration of the camera hardware, so that when requests\nare submitted with multiple or varying output pipelines listed, there won't be\ndelays or latency in fulfilling the request.\n\nFor further information about the guaranteed stream output combinations\nthat depend on the supported hardware level, see\n[createCaptureSession()](https://developer.android.com/reference/android/hardware/camera2/CameraDevice#createCaptureSession(java.util.List%3Candroid.view.Surface%3E,%20android.hardware.camera2.CameraCaptureSession.StateCallback,%20android.os.Handler)).\n\nCropping\n--------\n\nCropping of the full pixel array (for digital zoom and other use cases where a\nsmaller FOV is desirable) is communicated through the ANDROID_SCALER_CROP_REGION\nsetting. This is a per-request setting, and can change on a per-request basis,\nwhich is critical for implementing smooth digital zoom.\n\nThe region is defined as a rectangle (x, y, width, height), with (x, y)\ndescribing the top-left corner of the rectangle. The rectangle is defined on the\ncoordinate system of the sensor active pixel array, with (0,0) being the\ntop-left pixel of the active pixel array. Therefore, the width and height cannot\nbe larger than the dimensions reported in the ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY\nstatic info field. The minimum allowed width and height are reported by the HAL\nthrough the ANDROID_SCALER_MAX_DIGITAL_ZOOM static info field, which describes\nthe maximum supported zoom factor. Therefore, the minimum crop region width and\nheight are: \n\n```\n {width, height} =\n { floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[0] /\n ANDROID_SCALER_MAX_DIGITAL_ZOOM),\n floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[1] /\n ANDROID_SCALER_MAX_DIGITAL_ZOOM) }\n```\n\nIf the crop region needs to fulfill specific requirements (for example, it needs\nto start on even coordinates, and its width/height needs to be even), the HAL\nmust do the necessary rounding and write out the final crop region used in the\noutput result metadata. Similarly, if the HAL implements video stabilization, it\nmust adjust the result crop region to describe the region actually included in\nthe output after video stabilization is applied. In general, a camera-using\napp must be able to determine the field of view it is receiving based on\nthe crop region, the dimensions of the image sensor, and the lens focal length.\n\nSince the crop region applies to all streams, which may have different aspect\nratios than the crop region, the exact sensor region used for each stream may be\nsmaller than the crop region. Specifically, each stream should maintain square\npixels and its aspect ratio by minimally further cropping the defined crop\nregion. If the stream's aspect ratio is wider than the crop region, the stream\nshould be further cropped vertically, and if the stream's aspect ratio is\nnarrower than the crop region, the stream should be further cropped\nhorizontally.\n\nIn all cases, the stream crop must be centered within the full crop region, and\neach stream is only either cropped horizontally or vertical relative to the full\ncrop region, never both.\n\nFor example, if two streams are defined, a 640x480 stream (4:3 aspect), and a\n1280x720 stream (16:9 aspect), below demonstrates the expected output regions\nfor each stream for a few sample crop regions, on a hypothetical 3 MP (2000 x\n1500 pixel array) sensor.\n\n\nCrop region: (500, 375, 1000, 750) (4:3 aspect ratio) \n\n640x480 stream crop: (500, 375, 1000, 750) (equal to crop region) \n\n1280x720 stream crop: (500, 469, 1000, 562)\n\n\n**Figure 1.** 4:3 aspect ratio\n\nCrop region: (500, 375, 1333, 750) (16:9 aspect ratio) \n\n640x480 stream crop: (666, 375, 1000, 750) \n\n1280x720 stream crop: (500, 375, 1333, 750) (equal to crop region)\n\n\n**Figure 2.** 16:9 aspect ratio\n\nCrop region: (500, 375, 750, 750) (1:1 aspect ratio) \n\n640x480 stream crop: (500, 469, 750, 562) \n\n1280x720 stream crop: (500, 543, 750, 414)\n\n\n**Figure 3.** 1:1 aspect ratio\n\n\nAnd a final example, a 1024x1024 square aspect ratio stream instead of the 480p\nstream: \n\nCrop region: (500, 375, 1000, 750) (4:3 aspect ratio) \n\n1024x1024 stream crop: (625, 375, 750, 750) \n\n1280x720 stream crop: (500, 469, 1000, 562)\n\n\n**Figure 4.** 4:3 aspect ratio, square\n\nReprocessing\n------------\n\nAdditional support for raw image files is provided by reprocessing support for RAW Bayer\ndata. This support allows the camera pipeline to process a previously captured\nRAW buffer and metadata (an entire frame that was recorded previously), to\nproduce a new rendered YUV or JPEG output.\n\nZoom\n----\n\nFor devices running Android 11 or higher, an app can use a camera's zoom\n(digital and optical) through the `ANDROID_CONTROL_ZOOM_RATIO` setting.\n\nThe zoom ratio is defined as a floating point factor. Instead of\nusing `ANDROID_SCALER_CROP_REGION` for crop and zoom, an app can use\n`ANDROID_CONTROL_ZOOM_RATIO` to control the zoom level, and use\n`ANDROID_SCALER_CROP_REGION` for horizontal and vertical cropping to\nachieve aspect ratios different than the native camera sensor.\n\nA multi-camera system may contain more than one lens with different\nfocal lengths, and the user can use optical zoom by switching between lenses.\nUsing `ANDROID_CONTROL_ZOOM_RATIO` has benefits in the scenarios below:\n\n- Zooming in from a wide lens to a telephoto lens: A floating point ratio provides better precision compared to integer values of `ANDROID_SCALER_CROP_REGION`.\n- Zooming out from a wide lens to an ultrawide lens: `ANDROID_CONTROL_ZOOM_RATIO` supports zoom-out (\\\u003c1.0f) whereas `ANDROID_SCALER_CROP_REGION` doesn't.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nTo illustrate, here are several scenarios of different zoom ratios, crop regions, and output streams, using the same hypothetical camera defined in the previous section.\n\n\u003cbr /\u003e\n\n\nZoom ratio: 2.0; 1/4 of original field of view \n\nCrop region: (0, 0, 2000, 1500) (4:3 aspect ratio) \n\n640x480 stream crop: (0, 0, 2000, 1500) (equal to crop region) \n\n1280x720 stream crop: (0, 187, 2000, 1125)\n\n\n**Figure 5.** 2.0 zoom, 4:3 aspect ratio\n\nZoom ratio: 2.0; 1/4 of original field of view \n\nCrop region: (0, 187, 2000, 1125) (16:9 aspect ratio) \n\n640x480 stream crop: (250, 187, 1500, 1125) (pillarboxed) \n\n1280x720 stream crop: (0, 187, 2000, 1125) (equal to crop region)\n\n\n**Figure 6.** 2.0 zoom, 16:9 aspect ratio\n\nZoom ratio: 0.5; 4x of original field of view (switched from wide lens to ultrawide lens) \n\nCrop region: (250, 0, 1500, 1500) (1:1 aspect ratio) \n\n640x480 stream crop: (250, 187, 1500, 1125) (letterboxed) \n\n1280x720 stream crop: (250, 328, 1500, 844) (letterboxed)\n\n\n**Figure 7.** 0.5 zoom, 1:1 aspect ratio\n\nAs seen from the graphs above, the coordinate system of the crop region changes to the effective\nafter-zoom field of view, and is represented by the rectangle with the following dimensions:\n(`0`, `0`, `activeArrayWith`, `activeArrayHeight`).\nThe same applies to AE/AWB/AF regions and faces. This coordinate system change doesn't apply to\nRAW capture and its related metadata such as `intrinsicCalibration` and\n`lensShadingMap`.\n\nUsing the same hypothetical example above, and assuming output stream #1 (640x480) is the\nviewfinder stream, 2.0x zoom can be achieved in one of two ways:\n\n- `zoomRatio = 2.0`, `scaler.cropRegion = (0, 0, 2000, 1500)`\n- `zoomRatio = 1.0` (default), `scaler.cropRegion = (500, 375, 1000, 750)`\n\nFor an app to set `android.control.aeRegions` to be the top-left\nquarter of the viewfinder field of view, set\n`android.control.aeRegions` to `(0, 0, 1000, 750)` with\n`android.control.zoomRatio` set to `2.0`. Alternatively,\nthe app can set `android.control.aeRegions` to the equivalent\nregion of `(500, 375, 1000, 750)` for\n`android.control.zoomRatio` of `1.0`."]]