You're code to start the video feed, I would assume, gets a Camera object, starts it and connects it to a SurfaceView maybe a SurfaceTexture. The frames from the Camera are directly displayed to the SurfaceView if you have set:
myHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
myCamera.setPreviewDisplay(myHolder);
This is a fast and easy way to display the camera frames, but it means you cannot control how the frames are displayed. For instance, if you wanted to process the frames and then display them yourself, you would need to subscribe to the onPreviewCallback()
which gives you a copy of each frame. If you then omitted the above two surfaceview lines, the frames would not be automatically displayed and you could draw them yourself, however this would be alot slower. https://stackoverflow.com/a/4367250/514531
You can draw on top of a surfaceview using a Canvas. A canvas has many methods for drawig shapes/rectangles/lines/circles/words etc. You use Paint objects to specfify color/width etc.
Im sorry if this is wrong now but I have been using an older Android, but, if you do display via the surfaceview you cannot lock a canvas to the surfaceview. https://stackoverflow.com/a/12565208/514531 To get around this I found some code a while ago which creates an OverlayView class. In Android you can place views on top of each other in the Z direction. Using an empty transparent surfaceview that doesnt use myHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); myCamera.setPreviewDisplay(myHolder);
you can lock a canavs to it and start drawing.
The OverlayView class is simply a class extending SurfaceView and is used as a custom display. To do this you need to declare it in your layout file for your first/camera activity, like this:
<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"/>
In this layout file R.id.surfaceView
is your first surfaceview you use with the camera and set up like you probably already have. The R.id.overView is the custom surfaceview for drawing.
You can create it like any other view component:
OverLayView overView = (OverlayView)findViewById(R.id.overView);
This acts like a normal class as well so you can send some parameters to it as normal and call methods on it. For instance I have a method:
overView.setCamera(myCamera, cameraHeight, cameraWidth, getResources(), isFrontCamera);
Now you have a camera displaying to a surfaceview and a separate surfaceview you can draw to. So you now need a TouchEvent handler.
In the OverlayView class override the method onTouchEvent(MotionEvent e)
. The MotionEvent tells you what event occured, touch on/off. First check that it is a touch down(press on the screen) and then you can get the X and Y coordinates from the MotionEvent e.getX
;
This could be combined with the canavs to draw where a touch as occurred.
On thing to note: The dimensions of the camera preview will probably be different to that of the surfaceview. You know the camera dimensions from the camera object and the surfaceview sizes are from the surfaceView onchange method. So you need to calculate a ratio to convert the two, something like: (viewWidth/touch)*camerawidth.
Once you have the coordinates you could use crop the camera frame where you want.