代码之家  ›  专栏  ›  技术社区  ›  Cristian

如何在Android上相机使用的SurfaceView上绘制覆盖图?

  •  66
  • Cristian  · 技术社区  · 15 年前

    我有一个简单的程序来绘制 Camera 变成一个 SurfaceView . 我要做的是使用 onPreviewFrame 方法,每次将新帧绘制到 曲面视图 ,以便执行 invalidate 方法,它应该调用 onDraw 方法。事实上, OnDRAW 正在调用方法,但没有打印任何内容(我猜相机预览正在覆盖我试图绘制的文本)。

    这是 曲面视图 我拥有的子类:

    public class Superficie extends SurfaceView implements SurfaceHolder.Callback {
     SurfaceHolder mHolder;
     public Camera camera;
     Superficie(Context context) {
      super(context);
      mHolder = getHolder();
      mHolder.addCallback(this);
      mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
     }
     public void surfaceCreated(final SurfaceHolder holder) {
      camera = Camera.open();
      try {
       camera.setPreviewDisplay(holder);
       camera.setPreviewCallback(new PreviewCallback() {
        public void onPreviewFrame(byte[] data, Camera arg1) {
         invalidar();
        }
       });
      } catch (IOException e) {}
     }
     public void invalidar(){
      invalidate();
     }
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
      Camera.Parameters parameters = camera.getParameters();
      parameters.setPreviewSize(w, h);
      camera.setParameters(parameters);
      camera.startPreview();
     }
     @Override
     public void draw(Canvas canvas) {
      super.draw(canvas);
      // nothing gets drawn :(
      Paint p = new Paint(Color.RED);
      canvas.drawText("PREVIEW", canvas.getWidth() / 2,
        canvas.getHeight() / 2, p);
     }
    }
    
    3 回复  |  直到 9 年前
        1
  •  83
  •   Cristian    14 年前

    SurfaceView 可能不像普通人那样工作 View 在这方面。

    相反,请执行以下操作:

    1. 把你的 曲面视图 里面 FrameLayout RelativeLayout 在里面 布局XML文件,因为 这些允许在上面堆叠小部件 Z轴
    2. 移动绘图逻辑 变成一个单独的习惯 视图
    3. 添加自定义视图的实例 将布局XML文件作为 儿童的 框架布局 相对布局 但是让它出现 后 曲面视图

    这将导致你的习惯 视图 类显示为浮动在 曲面视图 .

    See here for a sample project 将弹出面板层叠在 曲面视图 用于视频播放。

        2
  •  17
  •   BartoszKP    9 年前

    尝试呼叫 setWillNotDraw(false) surfaceCreated :

    public void surfaceCreated(SurfaceHolder holder) {
        try {
            setWillNotDraw(false); 
            mycam.setPreviewDisplay(holder);
            mycam.startPreview();
        } catch (Exception e) {
            e.printStackTrace();
            Log.d(TAG,"Surface not created");
        }
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
    
        canvas.drawRect(area, rectanglePaint);
        Log.w(this.getClass().getName(), "On Draw Called");
    }
    

    呼唤 invalidate onTouchEvent :

    public boolean onTouch(View v, MotionEvent event) {
    
        invalidate();
        return true;
    }
    
        3
  •  1
  •   Stephan Branczyk    14 年前

    我想你应该打电话给 super.draw() 方法,然后在SurfaceView的Draw方法中执行任何操作。