IPCamAppBar/CameraView.cs

100 lines
3.1 KiB
C#

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using DateTime = System.DateTime;
namespace IPCamAppBar
{
public partial class CameraView : UserControl
{
private DateTime lastFrameTime;
private Timer noDataTimer;
public CameraView(string url)
{
InitializeComponent();
var cameraStream = new CameraMJPEGStream();
cameraStream.Frame += CameraStreamOnFrame;
cameraStream.Start(url);
noDataTimer = new Timer
{
Interval = 1000
};
noDataTimer.Tick += CheckNoData;
Disposed += (sender, args) =>
{
noDataTimer?.Dispose();
cameraStream?.Dispose();
};
}
private void CameraStreamOnFrame(object sender, FrameEventArgs args)
{
// The event comes from a background thread, so if needed invoke it on the main thread
if (InvokeRequired)
{
Invoke(new Action(() => { CameraStreamOnFrame(sender, args); }));
return;
}
ConnectingLabel.Visible = false;
StreamView.Visible = true;
NoDataLabel.Visible = false;
lastFrameTime = DateTime.Now;
noDataTimer.Start();
var viewImage = new Bitmap(Width, Height);
using (var graphics = Graphics.FromImage(viewImage))
{
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.DrawImage(args.Image, 0, 0, viewImage.Width, viewImage.Height);
using (var path = new GraphicsPath())
{
path.AddString(
lastFrameTime.ToString("G"),
FontFamily.GenericSansSerif,
(int)FontStyle.Regular,
graphics.DpiY * 14 / 72,
Rectangle.Inflate(new Rectangle(0, 0, viewImage.Width, viewImage.Height), -4, -4),
new StringFormat
{
Alignment = StringAlignment.Far,
LineAlignment = StringAlignment.Far
});
graphics.DrawPath(new Pen(Color.Black, 3), path);
graphics.FillPath(Brushes.White, path);
}
graphics.Flush();
}
var oldImage = StreamView.Image;
StreamView.Image = viewImage;
oldImage?.Dispose();
}
private void CheckNoData(object sender, EventArgs e)
{
var timeSinceLastFrame = DateTime.Now - lastFrameTime;
if (timeSinceLastFrame.TotalSeconds < 10)
return;
NoDataLabel.Text = $@"No data for {timeSinceLastFrame.TotalSeconds} seconds";
NoDataLabel.Visible = true;
}
}
}