我一直在研究一個簡單的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