簡體   English   中英

Camera2 中的前置攝像頭不捕捉圖像

[英]Front Camera in Camera2 not capturing image

我有來自https://github.com/googlesamples/android-Camera2Basic的 Camera2 代碼。

我面臨的問題是,當我使用前置攝像頭時,我無法拍攝照片,但使用后置攝像頭可以正常工作。

有沒有人實現過Camera2 Api 請幫忙!

這是代碼片段:

private void setUpCameraOutputs(int width, int height) {
    Activity activity = getActivity();
    CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
    try {
        for (String cameraId : manager.getCameraIdList()) {
            CameraCharacteristics characteristics
                    = manager.getCameraCharacteristics(cameraId);

            // We don't use a front facing camera in this sample.
            int facing = characteristics.get(CameraCharacteristics.LENS_FACING);
            Log.i(TAG,"Front Cam ID: "+ facing);
            if (characteristics.get(CameraCharacteristics.LENS_FACING)==CameraCharacteristics.LENS_FACING_FRONT)
            {



                StreamConfigurationMap map = characteristics.get(
                        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);


                // For still image captures, we use the largest available size.
                Size largest = Collections.max(
                        Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
                        new CompareSizesByArea());
                mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
                        ImageFormat.JPEG, /*maxImages*/2);
                mImageReader.setOnImageAvailableListener(
                        mOnImageAvailableListener, mBackgroundHandler);

                // Danger, W.R.! Attempting to use too large a preview size could  exceed the camera
                // bus' bandwidth limitation, resulting in gorgeous previews but the storage of
                // garbage capture data.
                mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
                        width, height, largest);

                // We fit the aspect ratio of TextureView to the size of preview we picked.
                int orientation = getResources().getConfiguration().orientation;
                if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                    mTextureView.setAspectRatio(
                            mPreviewSize.getWidth(), mPreviewSize.getHeight());
                } else {
                    mTextureView.setAspectRatio(
                            mPreviewSize.getHeight(), mPreviewSize.getWidth());
                }

                mCameraId = cameraId;
                return;
            }
            else
            {
                onActivityCreated(Bundle.EMPTY);
            }
        }
    } catch (CameraAccessException e) {
        e.printStackTrace();
    } catch (NullPointerException e) {
        // Currently an NPE is thrown when the Camera2API is used but not supported on the
        // device this code runs.
        ErrorDialog.newInstance(getString(R.string.camera_error))
                .show(getChildFragmentManager(), FRAGMENT_DIALOG);
    }
}

問題是許多前置攝像頭的焦距固定的 因此,在lockFocus()的自動對焦觸發器之后,自動對焦狀態 ( CONTROL_AF_STATE ) 保持INACTIVE並且自動對焦觸發器不執行任何操作。

因此,為了使其工作,您需要檢查是否支持自動對焦。 為此,請將以下內容添加到setUpCameraOutputs()

int[] afAvailableModes = characteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);

if (afAvailableModes.length == 0 || (afAvailableModes.length == 1
        && afAvailableModes[0] == CameraMetadata.CONTROL_AF_MODE_OFF)) {
    mAutoFocusSupported = false;
} else {
    mAutoFocusSupported = true;
}

最后,如果您想拍照時不支持,請不要鎖定焦點:

private void takePicture() {
    if (mAutoFocusSupported) {
        lockFocus();
    } else {
        captureStillPicture();
    }
}

對於 Camera2 Api,Google 的視頻示例適用於前置和后置攝像頭,但對於圖像捕獲,Google 的示例僅適用於后置攝像頭,不適用於前置攝像頭。
對我有用的解決方案是

lockFocus()方法中,替換行

mCaptureSession.capture(mPreviewRequestBuilder.build(),
                                                  mCaptureCallback, mBackgroundHandler);

captureStillPicture();

希望這會有所幫助!!

@ArvindSingh 的解決方案不是最好的解決方案,因為您還會禁用后置攝像頭的對焦功能。 更好的解決方案是在 takePicture 內進行相機朝向檢查,如下所示:

private void takePicture() {
    if (CameraCharacteristics.LENS_FACING_FRONT == mSelectedFacing) {
        // front camera selected, so take a picture without focus
        captureStillPicture();
    } else {
        // back camera selected, trigger the focus before creating an image
        lockFocus();
    }
}

對於此解決方案,您只需將當前使用的面保存在mSelectedFacing某處,例如此處

在 lockFocus() 方法中,替換行

mCaptureSession.capture(mPreviewRequestBuilder.build(),
                                              mCaptureCallback,    mBackgroundHandler);

captureStillPicture();

為了防止不需要的方向,您可以使用

/** * 從屏幕旋轉到 JPEG 方向的轉換。 */

   static {
       ORIENTATIONS.append(Surface.ROTATION_0, 270);
       ORIENTATIONS.append(Surface.ROTATION_90, 0);
       ORIENTATIONS.append(Surface.ROTATION_180, 180);
       ORIENTATIONS.append(Surface.ROTATION_270, 270);
   }

請嘗試使用此代碼進行捕獲

case STATE_WAITING_LOCK: {
                Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
                if (afState == null) {
                    captureStillPicture();
                } else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
                        CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState ||
                         CaptureResult.CONTROL_AF_STATE_INACTIVE == afState /*add this*/) {
                    // 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_PICTURE_TAKEN;
                        captureStillPicture();
                    } else {
                        runPrecaptureSequence();
                    }
                }
                break;
            }

暫無
暫無

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

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