2016-02-11 3 views
1

Я работаю с дополненной реальностью, и хочу нарисовать линию, которая соединяет два подвижных объекта на верхней части камеры. Однако я получаю это исключениеЛиния холста на холсте Android на камеру

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 методе. Я думаю, что я не могу заблокировать Canvas, потому что это: готово заблокировано камерой, я прав? Однако я рисовать линию возможно (я использую beyondAR augumented библиотеку реальности)

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); 
       } 
      } 
     } 
    } 
} 

ответ

1

Когда поверхность используется для отображения камеры предварительного просмотра, вы не можете рисовать на ней больше. Вы могли бы в принципе открыть отдельный прозрачный холст поверх поверхности предварительного просмотра и нарисовать этот холст. Может быть гораздо проще переключиться на предварительный просмотр OpenGL (используя SurfaceTexture); то вы можете использовать тот же контекст OpenGL для своих рисунков (но они также должны быть выражены в OpenGL). Начните с простого демонстрационного проекта at GitHub.

Но даже в этом случае есть еще одна проблема с вашей задачей: даже если ваше резюме очень быстрое, синхронизация между вашим дополнением и рамкой камеры, идущей прямо от датчиков к экрану, отсутствует. В случае OpenGL есть некоторые простые вещи, которые можно сделать за 0 раз (например, простая свертка на полученной текстуре). Но что-то интересное требует чего-то другого.

Мы обычно скрываем предварительный просмотр в реальном времени от пользователя, получаем кадры в обратном вызове onPreviewFrame(), обрабатываем их и рисуем рамку и любые дополнительные строки или объекты вручную. Это приводит к некоторой задержке, но если ваши алгоритмы действительно эффективны, эта задержка может быть незначительной.

Опять же, OpenGL обычно очень помогает.

0

Не блокируйтеCanvas и прекратите вызов потока & просто введите код ниже в методе 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); 
} 
Смежные вопросы