繁体   English   中英

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

[英]How to draw a mark on a camera stream with Xamarin.Android?

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

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

<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)
    {
    }
}

由于我没有跟踪球的跟踪算法,我使用了SurfaceViewTouch事件,每次点击SurfaceView ,都会在点击位置绘制一个带有红色笔划的矩形。 您可以将我的_surfaceView_Touch方法中的代码修改为您的跟踪算法并绘制您的红色标记。

您必须创建一个新视图,在此视图上绘制任何内容并将其添加到纹理视图上。

  • 创建一个新的视图并绘制任何东西

    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); }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM