我假设您是启动视频源的代码,获取一个 Camera 对象,启动它并将其连接到 SurfaceView 可能是 SurfaceTexture。如果您已设置,则来自 Camera 的帧将直接显示到 SurfaceView:
myHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
myCamera.setPreviewDisplay(myHolder);
这是显示相机帧的一种快速简便的方法,但这意味着您无法控制帧的显示方式。例如,如果您想处理帧然后自己显示它们,则需要订阅onPreviewCallback()
为您提供每个帧的副本的 。如果您随后省略了上述两条表面视图线,则不会自动显示框架,您可以自己绘制它们,但这会慢很多。https://stackoverflow.com/a/4367250/514531
您可以使用Canvas在表面视图上进行绘制。画布有许多用于绘制形状/矩形/线条/圆圈/单词等的方法。您使用 Paint 对象来指定颜色/宽度等。如果现在这是错误的,我很抱歉,但我一直在使用较旧的 Android,但是,如果你这样做通过表面视图显示,您无法将画布锁定到表面视图。https://stackoverflow.com/a/12565208/514531为了解决这个问题,我不久前发现了一些代码,它创建了一个 OverlayView 类。在 Android 中,您可以将视图在 Z 方向上相互叠加。使用不使用的空透明surfaceview,myHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); myCamera.setPreviewDisplay(myHolder);
您可以将canavs锁定到它并开始绘图。
OverlayView 类只是一个扩展 SurfaceView 的类,用作自定义显示。为此,您需要在布局文件中为您的第一个/相机活动声明它,如下所示:
<Your.package.OverlayView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/overView"
/>
<SurfaceView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/surfaceView"/>
在此布局文件R.id.surfaceView
中是您与相机一起使用的第一个表面视图,并像您可能已经拥有的那样进行设置。R.id.overView 是用于绘图的自定义表面视图。
您可以像创建任何其他视图组件一样创建它:
OverLayView overView = (OverlayView)findViewById(R.id.overView);
这也像一个普通的类,所以你可以像往常一样向它发送一些参数并调用它的方法。例如我有一个方法:
overView.setCamera(myCamera, cameraHeight, cameraWidth, getResources(), isFrontCamera);
现在您有一个显示到表面视图的相机和一个可以绘制到的单独的表面视图。所以你现在需要一个TouchEvent处理程序。
在 OverlayView 类中重写方法onTouchEvent(MotionEvent e)
。MotionEvent 告诉您发生了什么事件,触摸开/关。首先检查它是否是触地(在屏幕上按下),然后您可以从 MotionEvent 获取 X 和 Y 坐标e.getX
;
这可以与 canavs 结合起来绘制触摸发生的位置。
需要注意的是:相机预览的尺寸可能与表面视图的尺寸不同。您知道相机对象的相机尺寸和表面视图大小来自surfaceView onchange 方法。所以你需要计算一个比率来转换两者,比如:(viewWidth/touch)*camerawidth。
一旦你有了坐标,你就可以在你想要的地方裁剪相机框架。