我在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);
}
}
}
我既失去了一些東西還是我只是太老了這個:)
此外,這是我的第一篇文章在這裏所以大家:)