Android draw on camera preview

一曲冷凌霜 提交于 2019-11-28 04:25:55
James Burnstone

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

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.

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 :]

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!