在 onPreviewFrame 中使用 lockCanvas() 时,我正在与 IllegalArgumentException 作斗争。
基本上我想要实现的是抓取框架,处理它,然后直接将它绘制到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 中相机的文档和主题,我认为锁定绘制框架的表面是不可能的,因为它超出了应用程序控制的范围。这是真的吗?
一种可能的解决方案是在表面视图的顶部绘制另一个视图,但我想保持我处理的帧(会有一些精巧的边缘检测和颜色校正,这可能很耗时)与预览同步绘制。当相机继续以良好的 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);
}
}
}
我要么错过了一些东西,要么我太老了:)
另外,这是我在这里的第一篇文章,大家好:)