2015-06-30 85 views
4

我一直在研究一个简单的Android应用程序,旨在将来自Android Camera2 API管道的流式摄像头帧传递给我的算法。我已经使用Android Camera1 API忠实地完成了多个应用程序,但即使在检查(Google文档,论坛)以确认正确的编码之后,我也无法从onImageAvailable()中的ImageReader捕获任何实际数据。请注意以下相关的代码:捕捉Camera2预览帧返回空缓冲区

  1. 设置所述的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格式。有没有人有这个问题?我是否缺少任何代码?

    +0

    我有同样的问题。你能解决它吗? – SasukeIsCool

    +0

    我相信我在我的例子onImageAvailable(使其成为实际代码的第四行)中缺少“buffer.get(bytes)” – shandroid

    +0

    你是如何处理“不能在不调用Looper.prepare的线程内创建处理程序的()“ 问题 ?? – Bjqn

    回答

    4

    add buffer.get(bytes);byte [] bytes = new byte [buffer.remaining()];

    +0

    许多样品实际上在他们网上有这个错误,如果你没有仔细观察,你可能很容易错过它。 –