2013-04-17 29 views
4

我在onPreviewFrame中使用lockCanvas()時發生IllegalArgumentException異常。我可以在onPreviewFrame回調中使用lockCanvas()嗎?

基本上我想實現的是抓住框架,處理它,並將其直接繪製到SurfacePreview的表面。

這裏是我的onPreviewFrame

@Override 
public void onPreviewFrame(byte[] data, Camera camera) { 
    Canvas canvas = null; 

    if (mHolder == null) { 
     return; 
    } 

    int mImgFormat = mCamera.getParameters().getPreviewFormat(); 

    try { 
     canvas = mHolder.lockCanvas(); 
     canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR); 
     mHolder.unlockCanvasAndPost(canvas); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     if (canvas != null) 
     { 
      mHolder.unlockCanvasAndPost(canvas); 
     } 
    } 
} 

代碼中,我閱讀了大量的文件和有關攝像頭的Android的主題,我想是鎖定該幀繪製在表面上是不可能的,因爲它是超出了應用程序控制的範圍。這是真的嗎?

可能的解決方案之一是在另一個視圖上繪製表面視圖的頂部,但我想保留我處理的幀(將會出現一些Canny邊緣檢測和顏色校正,這可能很耗時)預覽。當相機將保持具有良好fps的隨機幀時,我的計算將很難趕上,並且在最壞的情況下,繪製一個落後幾十幀的覆蓋圖。

我學的OpenCV源,對我來說看起來他們已經成功地做到這一點在CameraBridgeViewBase.java:

protected void deliverAndDrawFrame(CvCameraViewFrame frame) { 
    Mat modified; 

    if (mListener != null) { 
     modified = mListener.onCameraFrame(frame); 
    } else { 
     modified = frame.rgba(); 
    } 

    boolean bmpValid = true; 
    if (modified != null) { 
     try { 
      Utils.matToBitmap(modified, mCacheBitmap); 
     } catch(Exception e) { 
      Log.e(TAG, "Mat type: " + modified); 
      Log.e(TAG, "Bitmap type: " + mCacheBitmap.getWidth() + "*" + mCacheBitmap.getHeight()); 
      Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage()); 
      bmpValid = false; 
     } 
    } 

    if (bmpValid && mCacheBitmap != null) { 
     Canvas canvas = getHolder().lockCanvas(); 
     if (canvas != null) { 
      canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR); 
      canvas.drawBitmap(mCacheBitmap, (canvas.getWidth() - mCacheBitmap.getWidth())/2, (canvas.getHeight() - mCacheBitmap.getHeight())/2, null); 
      if (mFpsMeter != null) { 
       mFpsMeter.measure(); 
       mFpsMeter.draw(canvas, 20, 30); 
      } 
      getHolder().unlockCanvasAndPost(canvas); 
     } 
    } 
} 

我既失去了一些東西還是我只是太老了這個:)

此外,這是我的第一篇文章在這裏所以大家:)

回答

1

事實上,OPENCV的攝像頭起到了小動作。在CameraBridgeViewBase.java和JavaCameraView.java文件中。我發現SurfaceTexture類(來自api 11)用於從相機接收幀。 SurfaceTexture的優點是你不需要總是把它繪製在屏幕上(它可以包含在內存中)。然後一個SurfaceView類負責從onPreviewFrame函數中繪製已處理的框架。請注意,此SurfaceView未綁定到相機。希望這可以幫助。

相關問題