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


72

我有一个简单的程序,可将的预览绘制CameraSurfaceView。我想做的是使用onPreviewFrame方法,每次将新框架绘制到中时都会调用该方法,SurfaceView以执行invalidate应该调用该onDraw方法的方法。实际上,该onDraw方法正在被调用,但是没有打印任何内容(我想相机预览将覆盖我尝试绘制的文本)。

这是SurfaceView我拥有的子类的简化版本:

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

您能帮我做些什么,尝试更改按钮单击上的绘图颜色,例如BUTTON1-> red button2-> yellow等如何使用画布执行此操作?我想在实时摄影机上应用与实时摄影机效果相同的应用程序
Erum 2014年

Answers:


87

SurfaceViewView在这方面可能不太正常。

而是,请执行以下操作:

  1. 将您SurfaceView放在 FrameLayoutRelativeLayout布局XML文件中,因为这两个都允许在Z轴上堆叠小部件
  2. 将绘图逻辑移到单独的自定义View类中
  3. 将自定义View类的实例作为FrameLayout或 的子项添加到布局XML文件中RelativeLayout,但将其显示在SurfaceView

这将导致您的自定义View类显示在上方SurfaceView

请参阅此处的示例项目该示例项目SurfaceView用于视频播放的上方弹出面板分层。


非常感谢...这是一个很好的例子,我敢肯定,这就是我要做的一切:)
Cristian 2010年

@CommonsWare那么,在试图将一个Surfaceview叠加到另一个Surfaceview的情况下,您提供的答案是否可行?自定义View类是什么意思?我问的原因是因为我面临一个类似的问题,位于这里:stackoverflow.com/questions/3548666/…–
GobiasKoffi

@rohanbk:SurfaceView据我所知,您不能覆盖两个小部件。“自定义View类是什么意思?” -您自己的子类android.view.View,或您自己的现有小部件类的子类。
CommonsWare 2010年

@CommonsWare因此,老实说,我有什么办法可以修改API演示中的SurfaceViewOverlay示例(developer.android.com/resources/samples/ApiDemos/src/com/…),以便绘制位图。使用FrameLayout在相机Surfaceview顶部的SurfaceView中显示图像?
GobiasKoffi

@rohanbk:不需要SurfaceView绘制位图图像。例如,ImageView不使用SurfaceView,AFAIK。
CommonsWare,2010年

17

尝试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;
}

1

我认为您应该super.draw()在SurfaceView的draw方法中执行任何操作之前先调用该方法。


1
那就是他在原始代码中所做的:)
ITisha
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.