如何使用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();
    }
    }
    
  • 将此视图添加到纹理视图上

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

最新更新