2015-06-30 86 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

    許多樣品實際上在他們網上有這個錯誤,如果你沒有仔細觀察,你可能很容易錯過它。 –