我一直在开发一个简单的Android应用程序,旨在将流式相机帧从Android Camera2 API管道传递到我的算法中。我已经制作了几个应用程序,都是使用Android Camera1 API忠实地完成此操作的,但即使在检查(Google文档、论坛)以确认正确编码后,我仍无法从onImageAvailable()中的ImageReader中捕获任何真实数据。请注意以下相关代码:
Setting up the ImageReaders:
private void setUpCameraOutputs(int width, int height) { [....code....] mImageReader = ImageReader.newInstance(smallestJPEG.getWidth(), smallestJPEG.getHeight(), ImageFormat.JPEG, /*maxImages*/2); // mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null); mPreviewImageReader = ImageReader.newInstance(smallest.getWidth(), smallest.getHeight(), ImageFormat.YUV_420_888, 2); mPreviewImageReader.setOnImageAvailableListener(mOnPreviewImageAvailableListener, mBackgroundHandler); [....code....] }
Setting up the CaptureSession:
private void createCameraPreviewSession() { try { //Create Texture from Screen's TextureView SurfaceTexture texture = mTextureView.getSurfaceTexture(); assert texture != null; //Configure Default Buffer Size texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); //Create Output Surface from Texture Surface surface = new Surface(texture); // Set up a CaptureRequest.Builder with the output Surface. mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); //Add Output Display surface mPreviewRequestBuilder.addTarget(surface); //Add Preview frame-grabbing surface mPreviewRequestBuilder.addTarget(mPreviewImageReader.getSurface()); mCameraDevice.createCaptureSession(Arrays.asList(surface, mPreviewImageReader.getSurface()), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession cameraCaptureSession) { // The camera is already closed if (null == mCameraDevice) { return; } // When the session is ready, we start displaying the preview. mCaptureSession = cameraCaptureSession; try { // Auto focus should be continuous for camera preview. [...code...] mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // Flash is automatically enabled when necessary. mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); // Finally, we start displaying the camera preview. mPreviewRequest = mPreviewRequestBuilder.build(); mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler); } catch (CameraAccessException e) { [...code...] } } @Override public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { [...code...] } }, null ); } catch (CameraAccessException e) { [...code...] } }
Setting up the OnImageAvailableListener:
private ImageReader mPreviewImageReader; private final ImageReader.OnImageAvailableListener mOnPreviewImageAvailableListener = new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader reader) { //Acquire Image, ByteBuffer, then byte array Image image = reader.acquireLatestImage(); ByteBuffer buffer = image.getPlanes()[0].getBuffer(); byte[] bytes = new byte[buffer.remaining()]; //Check bytes array for anydata int cnt = 0; for (int i = 0; i < bytes.length; i++){ if (bytes[i] != 0)cnt++; } Log.i(TAG, "cnt = " + cnt); image.close(); //At this point, byte[] bytes is empty (all zero) [...code...] } };