我从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);
}
}
答案 0 :(得分:26)
问题在于许多前置摄像头具有固定焦距。因此,在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();
}
}
答案 1 :(得分:12)
对于Camera2 Api,Google的视频示例适用于前后摄像头,但对于图像捕捉,Google的示例仅适用于后置摄像头,而不适用于前置摄像头。
对我有用的解决方案是
在lockFocus()
方法中,替换行
mCaptureSession.capture(mPreviewRequestBuilder.build(),
mCaptureCallback, mBackgroundHandler);
与
captureStillPicture();
希望这会有所帮助!!
答案 2 :(得分:4)
@ ArvindSingh的解决方案并不是最好的解决方案,因为你也会禁用后置摄像头的对焦功能。一个更好的解决方案是在takePicture内部进行相机检查:
update_option('siteurl', 'http://www.pioneersurgicalsystems.in');
update_option('home', 'http://www.pioneersurgicalsystems.in');
对于此解决方案,您只需要将当前使用的当前内容保存在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();
}
}
答案 3 :(得分:1)
在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);
}
答案 4 :(得分:-1)
Plz尝试使用此代码进行捕获
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;
}