簡體   English   中英

如何使用Android Camera2 API捕獲單個圖像?

[英]how do I capture a single image with the Android Camera2 API?

我正在使用Android Camera2 API來捕獲和處理圖像。 圖像處理響應於成功捕獲。 我遇到的問題是相機捕獲了2張圖像,我無法更改Camera2Basic示例中的代碼以確保只捕獲一張圖像。 這個問題可以通過添加日志代碼到證明ImageSaver.run()在方法Camera2BasicFragment.java

public void run() {
    Log.d("Camera2", "Saving image");
    ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
    ...
}

編輯 - 經過進一步調查后,問題似乎出現在樣本的實施中,而不是API的任何基礎。 在示例中,以下代碼跟蹤相機的狀態更改,

 private void process(CaptureResult result) {
        switch (mState) {
            case STATE_PREVIEW: {
                // We have nothing to do when the camera preview is working normally.
                break;
            }
            case STATE_WAITING_LOCK: {
                int afState = result.get(CaptureResult.CONTROL_AF_STATE);
                if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
                        CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
                    // CONTROL_AE_STATE can be null on some devices
                    Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                    if (aeState == null ||
                            aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
                        mState = STATE_WAITING_NON_PRECAPTURE;
                        /** CAPTURE 1 */
                        captureStillPicture();
                    } else {
                        runPrecaptureSequence();
                    }
                }
                break;
            }
            case STATE_WAITING_PRECAPTURE: {
                ...
                break;
            }
            case STATE_WAITING_NON_PRECAPTURE: {
                // CONTROL_AE_STATE can be null on some devices
                Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
                    mState = STATE_PICTURE_TAKEN;
                    /** CAPTURE 2 **/
                    captureStillPicture();
                }
                break;
            }
        }
    }

我已經驗證了captureStillPicture兩次調用都會導致生成圖像,從而進行處理。 我不完全確定正確的狀態轉換應該是什么。

我使用的是摩托羅拉Nexus 6

示例代碼中確實存在冗余/錯誤。 簡單的解決方案是在寫入/** CAPTURE 1 */之前更改行

mState = STATE_PICTURE_TAKEN;

只有在所有設置已經正確/收斂時才會輸入此情況,因此也可以啟動靜態捕獲。 它只是沒有記錄它是這樣做的。

既然你的問題我開始閱讀並深入研究它,我相信它的工作方式。 根據doc( 鏈接 )說:

每個請求將生成一個CaptureResult並為一個或多個目標曲面生成新幀

注意它說“幀s ”。 復數形式。

說我相信你應該只考慮內部onCaptureCompleted回調的最后一幀。

這是因為樣本的實施。 要解決這個問題,只需在captureStillPicture()方法結束時調用unlock()方法 -

mPreviewSession.stopRepeating();
mPreviewSession.capture(captureBuilder.build(), mCaptureCallback, null);            
unlockFocus();

以防萬一,這里是解鎖方法

private void unlockFocus() {
        try {
            // Reset the autofucos trigger
            mPreviewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
            mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);

            // After this, the camera will go back to the normal state of preview.
            mState = STATE_PREVIEW;
            mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), mCaptureCallback, backgroundHandler);

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM