我一直在研究一个简单的Android应用程序,旨在将来自Android Camera2 API管道的流式摄像头帧传递给我的算法。我已经使用Android Camera1 API忠实地完成了多个应用程序,但即使在检查(Google文档,论坛)以确认正确的编码之后,我也无法从onImageAvailable()中的ImageReader捕获任何实际数据。请注意以下相关的代码:捕捉Camera2预览帧返回空缓冲区
设置所述的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....] }
设置的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...] } }
设置的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...] } };
在代码段#3,我的字节缓冲器总是返回空(全0),而不管ImageReader格式。有没有人有这个问题?我是否缺少任何代码?
我有同样的问题。你能解决它吗? – SasukeIsCool
我相信我在我的例子onImageAvailable(使其成为实际代码的第四行)中缺少“buffer.get(bytes)” – shandroid
你是如何处理“不能在不调用Looper.prepare的线程内创建处理程序的()“ 问题 ?? – Bjqn