Camera2中的前置摄像头不捕捉图像

我有从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, WR! 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); } } 

Solutions Collecting From Web of "Camera2中的前置摄像头不捕捉图像"

问题在于许多前置摄像头具有固定的焦距 。 所以在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; } 

最后不要locking焦点,如果它不支持当你想拍照:

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

对于Camera2 Api来说,Google的video示例对于前置和后置摄像头都非常有用,但对于图像采集,Google的示例仅适用于后置摄像头,而不适用于前置摄像头。
解决scheme是适合我的

lockFocus()方法中,replace行

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

 captureStillPicture(); 

希望这会有所帮助!

@ ArvindSingh的解决scheme不是最好的解决scheme,因为你也会禁用后置摄像头的对焦function。 一个更好的解决办法是在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(); } } 

对于这个解决scheme,只需要在mSelectedFacing保存当前使用的mSelectedFacing

在lockFocus()方法中,replace行

 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); } 
 Plz try this code for capture 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; }