IPCamAppBar/CameraView.cs

101 lines
3.3 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;
public CameraView(string url)
{
InitializeComponent();
var cameraStream = new CameraMJPEGStream();
cameraStream.Frame += CameraStreamOnFrame;
cameraStream.StreamException += CameraStreamOnStreamException;
cameraStream.Start(url);
Disposed += (sender, args) =>
{
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;
IssueLabel.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 CameraStreamOnStreamException(object sender, StreamExceptionEventArgs args)
{
IssueLabel.Text = args.Exception.Message;
IssueLabel.Visible = true;
IssueLabel.BringToFront();
}
private void NoDataTimer_Tick(object sender, EventArgs e)
{
var timeSinceLastFrame = DateTime.Now - lastFrameTime;
if (timeSinceLastFrame.TotalSeconds < 10)
return;
IssueLabel.Text = $@"No data for {(int)timeSinceLastFrame.TotalSeconds} seconds";
IssueLabel.Visible = true;
IssueLabel.BringToFront();
}
}
}