我正在捕获网络视频流并在面板winform控件中预览它。 现在,在该视频流的顶部,我想显示线条。
我尝试使用面板的绘制事件添加线条,但它显示在网络视频流后面。
是否有任何可能的解决方案在该网络摄像头流的顶部显示该行,以便用户可以在视频结果中显示该行?
注意: 网络摄像头流媒体和线路都工作正常,我只是想在网络摄像头视频流的顶部显示线条。使用相同的面板显示所有内容,使用DirectX捕获网络摄像头视频流。
如果您对我的问题有任何可行的解决方案,请分享您的想法。
这是我的代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DirectX.Capture;
using Microsoft.VisualBasic;
using DShowNET;
using System.IO;
namespace ScreenCapture
{
public partial class frmDemo : Form
{
#region Variable
/*START - Graph line variables initialization*/
int Y1 = 200;
int Y2 = 300;
int fixedX = Screen.PrimaryScreen.WorkingArea.Width;
Pen pen = new Pen(Color.Red, 3);
int linePattern = 1;
/*END*/
private bool dragging;
private Point dragAt = Point.Empty;
private Capture capture = null;
private Filters filters = new Filters();
protected ISampleGrabber sampGrabber = null;
#endregion
#region Constructor
public frmDemo()
{
InitializeComponent();
/*START - Graph line parameter initialization*/
this.DoubleBuffered = true;
this.panelVideo.Paint += new PaintEventHandler(panelVideo_Paint);
this.panelVideo.MouseMove += new MouseEventHandler(panelVideo_MouseMove);
this.panelVideo.MouseDown += new MouseEventHandler(panelVideo_MouseDown);
this.panelVideo.MouseUp += new MouseEventHandler(panelVideo_MouseUp);
this.Lines = new List<GraphLine>()
{
new GraphLine (0, 200, fixedX, 200),
new GraphLine (0, 300, fixedX, 300),
};
/*END*/
#if DEBUG
capture = new Capture(filters.VideoInputDevices[0], filters.AudioInputDevices[0]);
#endif
try { updateMenu(); } catch { }
}
#endregion
#region Event
private void panelVideo_Paint(object sender, PaintEventArgs e)
{
/*Graphline code*/
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
foreach (var line in Lines)
{
//var color = line == SelectedLine ? Color.Red : Color.Red;
label2.Text = string.Empty;
if (linePattern != 0)
{
e.Graphics.DrawLine(pen, line.StartPoint, line.EndPoint);
e.Graphics.DrawLine(new Pen(Color.Red, 2), new Point(200, Y1), new Point(200, Y2)); //draw verticle line and display label
label2.ForeColor = Color.Red;
label2.Text = string.Format("{0}m", (Convert.ToInt32(System.Math.Abs(Y1 - Y2)) * 0.26) * 1000);
}
}
}
private void panelVideo_MouseUp(object sender, MouseEventArgs e)
{
/*Graphline code*/
if (Moving != null)
{
this.panelVideo.Capture = false;
Moving = null;
}
RefreshLineSelection(e.Location);
}
private void panelVideo_MouseDown(object sender, MouseEventArgs e)
{
/*Graphline code*/
RefreshLineSelection(e.Location);
if (this.SelectedLine != null && Moving == null)
{
this.panelVideo.Capture = true;
Moving = new MoveInfo
{
Line = this.SelectedLine,
StartLinePoint = SelectedLine.StartPoint,
EndLinePoint = SelectedLine.EndPoint,
StartMoveMousePoint = e.Location
};
}
RefreshLineSelection(e.Location);
}
private void panelVideo_MouseMove(object sender, MouseEventArgs e)
{
/*Graphline*/
if (Moving != null)
{
Moving.Line.StartPoint = new PointF(0, Moving.StartLinePoint.Y + e.Y - Moving.StartMoveMousePoint.Y);
Moving.Line.EndPoint = new PointF(fixedX, Moving.EndLinePoint.Y + e.Y - Moving.StartMoveMousePoint.Y);
}
RefreshLineSelection(e.Location);
//for verticle line
Y1 = e.Location.Y;
bool flag = true;
foreach (var line in Lines)
{
if (flag)
{
flag = false;
Y1 = Convert.ToInt32(line.StartPoint.Y);
}
else
{
Y2 = Convert.ToInt32(line.StartPoint.Y);
}
}
//this.Paint += new PaintEventHandler(panelVideo_Paint);
}
/*END*/
#endregion
#region Method
/*START- Graphline methods and classes*/
private void RefreshLineSelection(Point point)
{
var selectedLine = FindLineByPoint(Lines, point);
if (selectedLine != this.SelectedLine)
{
this.SelectedLine = selectedLine;
this.panelVideo.Invalidate();
}
if (Moving != null)
this.panelVideo.Invalidate();
this.panelVideo.Cursor =
Moving != null ? Cursors.Hand :
SelectedLine != null ? Cursors.SizeAll :
Cursors.Default;
}
public List<GraphLine> Lines = new List<GraphLine>();
GraphLine SelectedLine = null;
MoveInfo Moving = null;
static GraphLine FindLineByPoint(List<GraphLine> lines, Point p)
{
var size = 10;
var buffer = new Bitmap(size * 2, size * 2);
foreach (var line in lines)
{
//draw each line on small region around current point p and check pixel in point p
using (var g = Graphics.FromImage(buffer))
{
g.Clear(Color.Black);
g.DrawLine(new Pen(Color.Green, 3), line.StartPoint.X - p.X + size, line.StartPoint.Y - p.Y + size, line.EndPoint.X - p.X + size, line.EndPoint.Y - p.Y + size);
}
if (buffer.GetPixel(size, size).ToArgb() != Color.Black.ToArgb())
return line;
}
return null;
}
public class MoveInfo
{
public GraphLine Line;
public PointF StartLinePoint;
public PointF EndLinePoint;
public Point StartMoveMousePoint;
}
public class GraphLine
{
public GraphLine(float x1, float y1, float x2, float y2)
{
this.StartPoint = new PointF(x1, y1);
this.EndPoint = new PointF(x2, y2);
}
public PointF StartPoint;
public PointF EndPoint;
}
/*END*/
public void Pick(Control control, int x, int y)
{
dragging = true;
dragAt = new Point(x, y);
control.Capture = true;
}
public void Drop(Control control)
{
dragging = false;
control.Capture = false;
}
public static Image BytetoImage(byte[] imageData)
{
try
{
Image newImage;
using (MemoryStream ms = new MemoryStream(imageData, 0, imageData.Length))
{
ms.Write(imageData, 0, imageData.Length);
newImage = Image.FromStream(ms, true);
}
return newImage;
}
catch (Exception)
{
return null;
}
}
#endregion
#region CameraMethod
private void updateMenu()
{
Filter f;
Source s;
Source current;
PropertyPage p;
Control oldPreviewWindow = null;
// Disable preview to avoid additional flashes (optional)
if (capture != null)
{
oldPreviewWindow = capture.PreviewWindow;
capture.PreviewWindow = null;
}
// Load video devices
Filter videoDevice = null;
if (capture != null)
videoDevice = capture.VideoDevice;
// Reenable preview if it was enabled before
if (capture != null)
capture.PreviewWindow = oldPreviewWindow;
capture.PreviewWindow = panelVideo;
}
#endregion
}
}