如何使用Xamarin.Android在相机流上绘制标记?

时间:2017-02-16 12:28:15

标签: c# android xamarin camera xamarin.android

我设法在TextureView上显示相机流,并使Bitmap读取流的每一帧的像素。然后,我可以应用跟踪算法来跟踪球。但现在,我想显示一个红色标记(例如),显示找到的球的位置。我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

我相信有很多方法可以在相机视图上绘制标记。我在这里使用了SurfaceView。基本思路是在SurfaceView的顶部设置一个透明背景的Textureview

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <TextureView android:id="@+id/textureView"
               android:layout_height="match_parent"
               android:layout_width="match_parent" />

  <SurfaceView
        android:id="@+id/surfaceview"
        android:layout_height="match_parent"
        android:layout_width="match_parent" />
</RelativeLayout >
代码背后的代码:

public class MainActivity : Activity, TextureView.ISurfaceTextureListener
{
    private Android.Hardware.Camera _camera;
    private TextureView _textureView;
    private SurfaceView _surfaceView;
    private ISurfaceHolder holder;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        _textureView = (TextureView)FindViewById(Resource.Id.textureView);
        _textureView.SurfaceTextureListener = this;

        _surfaceView = (SurfaceView)FindViewById(Resource.Id.surfaceview);
        //set to top layer
        _surfaceView.SetZOrderOnTop(true);
        //set the background to transparent
        _surfaceView.Holder.SetFormat(Format.Transparent);
        holder = _surfaceView.Holder;
        _surfaceView.Touch += _surfaceView_Touch;
    }

    private void _surfaceView_Touch(object sender, View.TouchEventArgs e)
    {
        //define the paintbrush
        Paint mpaint = new Paint();
        mpaint.Color = Color.Red;
        mpaint.SetStyle(Paint.Style.Stroke);
        mpaint.StrokeWidth = 2f;

        //draw
        Canvas canvas = holder.LockCanvas();
        //clear the paint of last time
        canvas.DrawColor(Color.Transparent, PorterDuff.Mode.Clear);
        //draw a new one, set your ball's position to the rect here
        var x = e.Event.GetX();
        var y = e.Event.GetY();
        Rect r = new Rect((int)x, (int)y, (int)x + 100, (int)y + 100);
        canvas.DrawRect(r, mpaint);
        holder.UnlockCanvasAndPost(canvas);
    }

    public bool OnSurfaceTextureDestroyed(SurfaceTexture surface)
    {
        _camera.StopPreview();
        _camera.Release();

        return true;
    }

    public void OnSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
    {
        _camera = Android.Hardware.Camera.Open();

        try
        {
            _camera.SetPreviewTexture(surface);
            _camera.SetDisplayOrientation(90);
            _camera.StartPreview();
        }
        catch (Java.IO.IOException ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

    public void OnSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height)
    {
    }

    public void OnSurfaceTextureUpdated(SurfaceTexture surface)
    {
    }
}

由于我没有跟踪算法来跟踪球,因此每次点击Touch时,我都会使用SurfaceView的{​​{1}}事件。将在拍打位置绘制红色笔划。您可以将SurfaceView方法中的代码修改为跟踪算法并绘制红色标记。

答案 1 :(得分:0)

您必须创建一个新视图,在该视图上绘制任何内容,然后将其添加到textureview上。

  • 创建新的视图并绘制任何内容

    public class DrawingView : View
    {
        public DrawingView(Context context) : base(context)
        {
    
        }
    
        protected override void OnDraw(Canvas canvas)
        {
            Paint paint;
            paint = new Paint();
            paint.Color = (Color.Green);
            canvas.DrawRect(0, 0, 300, 300, paint);
            //Draw Anything
            Invalidate();
        }
    }
    
  • 在您的TextureView上添加此视图

        void SetupUserInterface()
        {
            mainLayout = new RelativeLayout(Context);
    
            liveView = new TextureView(Context);
            RelativeLayout.LayoutParams liveViewParams = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MatchParent,
                RelativeLayout.LayoutParams.MatchParent);
            liveView.LayoutParameters = liveViewParams;
            mainLayout.AddView(liveView);
    
    
    
            drawingView = new DrawingView(Context);
            RelativeLayout.LayoutParams captureButtonParams = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MatchParent,
                RelativeLayout.LayoutParams.MatchParent);
            drawingView.LayoutParameters = captureButtonParams;
            mainLayout.AddView(drawingView);
    
          AddView(mainLayout);
        }