我正在使用增强现实应用程序,我想绘制一条连接相机顶部两个可移动物体的线。但是我得到了这个例外
Process: test.job.reality.augument.job.com.augumentrealitytest, PID: 15056
java.lang.IllegalArgumentException
at android.view.Surface.nativeLockCanvas(Native Method)
at android.view.Surface.lockCanvas(Surface.java:266)
at custom.MyCameraView$MyThread.run(MyCameraView.java:447)
这是我的代码,你可以看到我在surfaceCreted
方法中启动我的线程。我想我不能锁定帆船,因为它是一个;准备好被相机锁定,我是对的吗?但是我画线是可能的(我正在使用beyondAR
增强现实库)
public class MyCameraView extends SurfaceView implements SurfaceHolder.Callback, Camera.PictureCallback {
private MyThread thread;
public MyCameraView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
@SuppressWarnings("deprecation")
private void init(Context context) {
mIsPreviewing = false;
mHolder = getHolder();
mHolder.addCallback(this);
configureCamera();
if (Build.VERSION.SDK_INT <= 10) {// Android 2.3.x or lower
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
thread=new MyThread(getHolder(),this);
getHolder().addCallback(this);
setFocusable(true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
thread.startrun(true);
thread.start();
try {
if (mCamera == null) {
init(getContext());
if (mCamera == null) {
return;
}
}
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
if (mCamera != null) {
mCamera.release();
}
mCamera = null;
Logger.e(TAG, "CameraView -- ERROR en SurfaceCreated", exception);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
releaseCamera();
thread.startrun(false);
thread.stop();
}
public class MyThread extends Thread{
private SurfaceHolder msurfaceHolder;
private MyCameraView mSurfaceView;
private boolean mrun =false;
public MyThread(SurfaceHolder holder, MyCameraView mSurfaceView) {
this.msurfaceHolder = holder;
this.mSurfaceView=mSurfaceView;
}
public void startrun(boolean run) {
mrun=run;
}
@SuppressLint("WrongCall")
@Override
public void run() {
super.run();
Canvas canvas;
while (mrun) {
canvas=null;
try {
canvas = msurfaceHolder.lockCanvas();
synchronized (msurfaceHolder) {
mSurfaceView.onDraw(canvas);
}
} finally {
if (canvas != null) {
msurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
答案 0 :(得分:1)
当使用曲面显示相机预览时,您无法再使用它。原则上,您可以在预览曲面的顶部打开一个单独的透明画布,然后在该画布上绘制。切换到OpenGL预览可能要容易得多(使用SurfaceTexture);那么你可以为你的绘图使用相同的OpenGL上下文(但它们也必须用OpenGL表示)。您可以找到一个简单的演示项目at GitHub。
但即使在这种情况下,您的任务还有另一个问题:即使您的简历速度非常快,您的增强功能与直接从传感器到屏幕的摄像机框架之间也不会同步。在OpenGL的情况下,一些简单的事情可以在0时间内完成(例如,对接收到的纹理进行简单卷积)。但更有趣的是需要不同的东西。
我们通常隐藏用户的实时预览,获取onPreviewFrame()
回调中的帧,处理它们并手动绘制帧和任何其他行或对象。这会引入一些延迟,但如果您的算法非常有效,则此延迟可以忽略不计。
同样,OpenGL在这里通常会有很大的帮助。
答案 1 :(得分:1)
不要lockCanvas并停止线程调用&amp;只需在Draw方法中输入以下代码即可。我希望它能奏效。
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Paint paint = new Paint();
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
int screenWidth = metrics.widthPixels;
int screenHeight = metrics.heightPixels;
screenHeight = (int) (metrics.heightPixels * 0.6290);
paint.setAntiAlias(true);
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.argb(255, 255, 255, 255));
canvas.drawLine((screenWidth / 4), 0,
(screenWidth / 4), screenHeight + 500, paint);
if(screenWidth == 1280 && screenHeight == 473) // this condition for 10" tab only
canvas.drawLine((screenWidth / 2f), 0,
(screenWidth / 2f), screenHeight + 500, paint);
else
canvas.drawLine((screenWidth / 2.20f), 0,
(screenWidth / 2.20f), screenHeight + 500, paint);
canvas.drawLine(0, (screenHeight / 2.15f) * 2, screenWidth,
(screenHeight / 2.15f) * 2, paint);
canvas.drawLine(0, (screenHeight / 2.15f) , screenWidth,
(screenHeight / 2.15f), paint);
}