Camera2 Api: LegacyCameraDevice_nativeGetSurfaceId: не удалось получить естественную поверхность с поверхности - PullRequest
0 голосов
/ 19 октября 2018

Я пытался использовать Camera2 API Android, передняя камера работает нормально, но когда она поставляется с задней камерой, я думаю, что эта ошибка возникает:

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 голосов
/ 19 октября 2018

Ваш ImageReader является локальной переменной в takePicture, и, похоже, он не хранится где-либо в родительском классе.Скорее всего, это сборщик мусора сразу или вскоре после выхода takePicture, поэтому, когда камера пытается настроить себя, Surface сообщает об отказе.

Поверхность похожа на слабую ссылку и не будет поддерживать ImageReader в живых.само собой.Сохраните его в родительском классе, как вы делаете это с устройством камеры.

...