本文介绍了相机Android的画布上画线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我与增强现实应用程序工作,我想画上相机顶部连接两个可移动的物体的直线。不过,我得到这个例外

 流程:test.job.reality.augument.job.com.augumentrealitytest,PID:15056
    java.lang.IllegalArgumentException异常
    在android.view.Surface.nativeLockCanvas(本机方法)
    在android.view.Surface.lockCanvas(Surface.java:266)
    在custom.MyCameraView $ MyThread.run(MyCameraView.java:447)

下面是我的code,你可以看到,我开始我的线程在 surfaceCreted 方法。我想,我不能lockCanvas因为它是一个;通过相机准备锁定,对吗?不过,我画线,才有可能(我使用 beyondAR augumented现实库)

 公共类MyCameraView扩展SurfaceView实现SurfaceHolder.Callback,Camera.PictureCallback {
私人MyThread的线程;公共MyCameraView(上下文的背景下,ATTRS的AttributeSet){
    超(背景下,ATTRS);
    初始化(上下文);
}@燮pressWarnings(德precation)
私人无效的init(上下文的背景下){
    MIS previewing = FALSE;
    mHolder = getHolder();
    mHolder.addCallback(本);    configureCamera();    如果(Build.VERSION.SDK_INT&下; = 10){//的Andr​​oid 2.3.x版本或更低
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }    线程=新MyThread的(getHolder(),这一点);
    。getHolder()的addCallback(本);
    setFocusable(真);
} @覆盖
保护无效的onDraw(帆布油画){
    super.onDraw(画布);
}公共无效surfaceCreated(SurfaceHolder持有人){
    //表面有被创建,获取摄像机,并告诉它在哪里
    //绘制。    thread.startrun(真);
    thread.start();
    尝试{        如果(mCamera == NULL){
            初始化(的getContext());
            如果(mCamera == NULL){
                返回;
            }
        }        mCamera.set previewDisplay(支架);
    }赶上(IOException异常除外){
        如果(mCamera!= NULL){
            mCamera.release();
        }
        mCamera = NULL;
        Logger.e(TAGCameraView - 误差en SurfaceCreated除外);
    }
}公共无效surfaceDestroyed(SurfaceHolder持有人){
    releaseCamera();    thread.startrun(假);
    使用Thread.stop();
}公共类MyThread的继承Thread {    私人SurfaceHolder msurfaceHolder;
    私人MyCameraView mSurfaceView;
    私人布尔mrun = FALSE;    公共MyThread的(SurfaceHolder持有人,MyCameraView mSurfaceView){        this.msurfaceHolder =持有人;
        this.mSurfaceView = mSurfaceView;
    }    公共无效startrun(布尔运行){        mrun =运行;
    }    @燮pressLint(WrongCall)
    @覆盖
    公共无效的run(){        super.run();
        帆布油画;
        而(mrun){
            帆布= NULL;
            尝试{
                画布= msurfaceHolder.lockCanvas();
                同步(msurfaceHolder){
                    mSurfaceView.onDraw(画布);
                }
            } {最后
                如果(帆布!= NULL){
                    msurfaceHolder.unlockCanvasAndPost(画布);
                }
            }
        }
    }
}


解决方案

在一个面是用来显示相机preVIEW,你不能在上面画了。你可以在原则上,打开了preVIEW面顶部的独立的透明画布,并绘制画布上。这可能是更容易切换到OpenGL preVIEW(使用表面纹理);那么你可以使用相同的OpenGL上下文的图纸(但必须是在OpenGL pssed前$ P $,太)。您可以在GitHub的一个简单的演示项目的开始。

但即使在这种情况下,有一个与你的任务另一个问题:即使你的简历是非常快的,还有就是你增加和从传感器到屏幕上就直接将相机架之间没有synchornization。在OpenGL的情况下,有的部分的简单的事情,可以在0时完成(例如,在收到的纹理简单的卷积)。但是,任何事情更有趣的,需要不同的东西。

我们通常向用户隐藏活preVIEW,获得帧中的上previewFrame()回调,过程中他们并绘制框架和任何其他行或物体手动。这会产生一些延迟,但如果你的算法是真正有效,这种延迟可能是微不足道的。

再次OpenGL的通常这里有很大的帮助的。

I'm working with augmented reality app and I want to draw a line that connects two movable objects on top of the camera. However I get this exception

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)

Here's my code as you can see I start my thread in surfaceCreted method. I'm thinking that I can't lockCanvas because it's a;ready locked by camera, am I right? However I to draw line is it possible (I'm using beyondAR augumented reality library)

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);
                }
            }
        }
    }
}
解决方案

When a surface is used to display camera preview, you cannot draw on it anymore. You could, in principle, open a separate transparent canvas on top of the preview surface, and draw on that canvas. It may be much easier to switch to OpenGL preview (using SurfaceTexture); then you can use the same OpenGL context for your drawings (but they must be expressed in OpenGL, too). You can find a simple demo project at GitHub to begin with.

But even in this case, there is another problem with your task: even if your CV is very fast, there is no synchornization between your augmentation and the camera frame that goes straight from the sensors to the screen. In the case of OpenGL, there are some simple things that can be done in 0 time (e.g. simple convolution on the received texture). But anything more interesting requires something different.

We usually hide the live preview from the user, get the frames in the onPreviewFrame() callback, process them and draw the frame and whatever additional lines or objects manually. This introduces some delay, but if your algorithms are really efficient, this delay may be negligible.

Again, OpenGL is usually of great help here.

这篇关于相机Android的画布上画线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 13:29
查看更多