如何在 Android 上的 Camera 使用的 SurfaceView 上绘制叠加层?

Posted

技术标签:

【中文标题】如何在 Android 上的 Camera 使用的 SurfaceView 上绘制叠加层?【英文标题】:How to draw an overlay on a SurfaceView used by Camera on Android? 【发布时间】:2011-02-25 09:46:46 【问题描述】:

我有一个简单的程序将Camera 的预览绘制到SurfaceView 中。我要做的是使用onPreviewFrame 方法,每次将新帧绘制到SurfaceView 时都会调用该方法,以执行应该调用onDraw 方法的invalidate 方法.事实上,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);
 

【问题讨论】:

你能帮我看看你是怎么做的吗?我想申请与现场摄像头效果一样的现场摄像头 【参考方案1】:

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

相反,请执行以下操作:

    将您的SurfaceView 放入 FrameLayoutRelativeLayout 在 您的布局 XML 文件,因为两者 那些允许堆叠小部件 Z轴 移动绘图逻辑 进入一个单独的自定义View 类 添加自定义视图的实例 类到布局 XML 文件作为 FrameLayout 的孩子或 RelativeLayout,但让它出现 在SurfaceView之后

这将导致您的自定义 View 类看起来浮在 SurfaceView 上方。

【讨论】:

非常感谢...这是一个很好的例子,我相信这就是我需要做的一切:) @CommonsWare 那么,您提供的这个答案是否适用于您试图将一个表面视图覆盖在另一个表面视图之上的情况?自定义 View 类是什么意思?我问的原因是因为我在这里遇到了类似的问题:***.com/questions/3548666/… @rohanbk:据我了解,您不能叠加两个 SurfaceView 小部件。 “自定义视图类是什么意思?” -- 您自己的android.view.View 子类,或您自己的现有小部件类的子类。 @CommonsWare 所以,老实说,我有什么办法可以修改 API 演示 (developer.android.com/resources/samples/ApiDemos/src/com/…) 中的 SurfaceViewOverlay 示例,以便我可以在顶部的表面视图中绘制位图图像使用 FrameLayout 的相机表面视图? @rohanbk:您不需要SurfaceView 来绘制位图图像。例如,ImageView 不使用 SurfaceView,AFAIK。【参考方案2】:

尝试从surfaceCreated 调用setWillNotDraw(false)

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

并从onTouchEvent 调用invalidate

public boolean onTouch(View v, MotionEvent event) 

    invalidate();
    return true;

【讨论】:

【参考方案3】:

我认为你应该先调用super.draw() 方法,然后再在surfaceView 的draw 方法中做任何事情。

【讨论】:

这正是他在原始代码中所做的:)

以上是关于如何在 Android 上的 Camera 使用的 SurfaceView 上绘制叠加层?的主要内容,如果未能解决你的问题,请参考以下文章

Android Camera 2 API 在 Nougat 7.1 上的 flash 问题

通过具有 16:9 传感器阵列的相机上的 android Camera2 API 捕获 4:3 相机图片

Android API 级别 23 上的相机 1 包

如何实现Android平台GB28181设备对接Camera2数据

如何实现RTMP推送Android Camera2数据

android Camera 如何判断当前使用的摄像头是前置还是后置