Camera2 Api:LegacyCameraDevice_nativeGetSurfaceId:无法从曲面检索本机Surface

时间:2018-10-19 03:14:36

标签: android android-camera2

我尝试使用Android的Camera2 API时,前凸轮工作正常,但是当后凸轮附带时,我认为会发生此错误:

LegacyCameraDevice_nativeGetSurfaceId: Could not retrieve native Surface from surface.

这是在我单击按钮拍照后发生的。捕获回调成功,但是onImageAvailable上没有图像。

我遵循了https://inducesmile.com/android/android-camera2-api-example-tutorial/的教程,但我对如何处理我现在面临的错误一无所知。

这是用于捕获图像的代码。

private void takePicture() {
    if (mCameraDevice == null) {
        return;
    }
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        CameraManager mManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

        try {
            CameraCharacteristics mCharacteristics = mManager.getCameraCharacteristics(mCameraDevice.getId());
            Size[] jpegSizes = null;

            if (mCharacteristics != null) {
                jpegSizes = mCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
            }

            int width = 640;
            int height = 480;

            for(int x = 0; x < jpegSizes.length; x++) {
                Log.wtf("jpegSizes", String.valueOf(jpegSizes[x]));
            }

            if (jpegSizes != null && jpegSizes.length > 0) {
                width = jpegSizes[4].getWidth();
                height = jpegSizes[4].getHeight();
            }

            final ImageReader mReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);

            List<Surface> mOutputSurface = new ArrayList<>(2);
            mOutputSurface.add(mReader.getSurface());
            mOutputSurface.add(new Surface(mTextureView.getSurfaceTexture()));

            final CaptureRequest.Builder mCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            mCaptureBuilder.addTarget(mReader.getSurface());
            mCaptureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);

            int mRotation = getWindowManager().getDefaultDisplay().getRotation();
            int jpegOrientation = (ORIENTATIONS.get(mRotation) + mSensorOrientation + 270) % 360;

            if(cameraId.equals("0")) {
                mCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(mRotation));
            } else {
                if(extras.getString("orient").equals("landscape")) {
                    mCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(mRotation));
                } else {
                    mCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION, jpegOrientation);
                }
            }

            final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                    super.onCaptureCompleted(session, request, result);
                    if(mImage == null) {
                        Toast.makeText(StartCameraActivity.this, "Capturing Image Failed, Please Try Again", Toast.LENGTH_SHORT).show();
                        Log.wtf("onCaptureComplete", "Image not Available");
                    } else {
                        Log.wtf("onCaptureComplete", "Image Available");
                    }
                    //createCameraPreview();
                }

                @Override
                public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
                    super.onCaptureFailed(session, request, failure);
                    Log.wtf("FAILED", failure.toString());
                }
            };

            mCameraDevice.createCaptureSession(mOutputSurface, new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession session) {
                    Log.wtf("onConfigured", "succes");
                    try {
                        session.capture(mCaptureBuilder.build(), captureListener, mBackgroundHandler);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                    Log.wtf("onConfigureFailed", "failed");
                }
            }, mBackgroundHandler);

            mReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
                @Override
                public void onImageAvailable(final ImageReader reader) {
                    mImage = reader.acquireLatestImage();
                    Log.wtf("imageAvail", "OnImageAvailable");

                    StartCameraActivity.this.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (mImage == null) {
                                return;
                            }
                            final Image.Plane[] planes = mImage.getPlanes();
                            final ByteBuffer buffer = planes[0].getBuffer();
                            byte[] bytes = new byte[buffer.capacity()];
                            buffer.get(bytes);
                            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

                            mTextureView.setVisibility(View.INVISIBLE);
                            if(cameraId.equals("0")) {
                                screenshotHolder.setImageBitmap(bitmap);
                            } else {
                                screenshotHolder.setImageBitmap(flip(bitmap, mImage.getWidth(), mImage.getHeight()));
                            }
                            new RenderPicture(StartCameraActivity.this).execute();

                            if (mImage != null) {
                                mImage.close();
                            }
                            if(mReader != null) {
                                mReader.close();
                            }

                        }
                    });
                }
            }, mBackgroundHandler);


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

1 个答案:

答案 0 :(得分:2)

您的ImageReader是takePicture中的局部变量,看起来不像它存储在父类的任何位置。可能是在takePicture退出后立即或不久就被垃圾回收了,所以当相机尝试自行设置时,Surface会报废。

Surface就像一个弱引用,不会自动使ImageReader保持活动状态。像使用摄像头设备一样,将其存储在父类中。

相关问题