I\'m making a virtual reality application where the camera should detect faces, locate them and show their location on the camera preview.
I know of 3 ways to do it,
You can't lock and draw on a SurfaceView
which has Type.PUSH_BUFFERS
, (the one you're displaying frames to). You have to create another view above your original one in the Z direction and draw on a SurfaceView
in that View
.
So in your main.xml
create a custom view below your original view in a FrameLayout
.
Create and handle a SurfaceView
in your Activity View. Add this view to the Camera preview display. Start your custom view passing the SurfaceHolder
. In this view you can lock and draw on a canvas.
As James pointed out you need to create custom surface which extends SurfaceView (I usually implement SurfaceHolder.Callback also):
public class CameraSurfacePreview extends SurfaceView implements SurfaceHolder.Callback
Constructor will be something like:
public CameraSurfacePreview(Context context) {
super(context);
...
mHolder = getHolder();
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
...
You need to bind camera with your surface after camera open call (if you implement implements SurfaceHolder.Callback put this somewhere inside overridden surfaceCreated):
mCamera = Camera.open();
mCamera.setPreviewDisplay(mHolder);
Finally you need to add instance of your custom surface somehere in activity content view:
CameraSurfacePreview cameraSurfacePreview = new CameraSurfacePreview(this);
//camera surface preview is first child!
((ViewGroup)findViewById(R.id.cameraLayout)).addView(cameraSurfacePreview, 0);
In my example layout for activity looks something like(I am showing camera preview in main frame layout):
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="top|left"
android:id="@+id/cameraLayout">
I could said,
It's not about a Thread.
It not because of this line that make error either.
canvas.drawPoint(leftEye.x, leftEye.y, red);
It because of the canvas still using and can't lock it
If you carefully check, you will see this canvas you get is == null
canvas = canvasHolder.lockCanvas();
if (canvas == null) Log.i("Error", "Canvas == null!");
You might have question then where is it already use?
It already use to display to show what's going on to you! That is
camera.setPreviewDisplay(previewHolder);
So, I suggest, If you want to draw Point over your eye, you might need to have another SurfaceView / SurfaceHolder over you SurfaceView for preview camera :]
The lockcanvas/unlockcanvasandpost approach is not appropriate when using openGL as the openGL code is controlling and locking the surface. If you want to use the standard 2d APIs, don't use OpenGL.