小蚂蚁 发表于 2021-12-30 16:45:30

C# WPF项目实战(经典)

目的:输出两台摄像头图像和两路设备图像,每一路设备截图6张
主要知识:
1. 通过SDK调取摄像头图像,并对图像进行剪裁;
2. WPF中定时器DispatcherTimer用法;
3. WPF中跨线程访问控件方法
Dispatcher.Invoke((Action)delegate {});
区别于winform中
this.Invoke((Action)delegate {});
4.xml操作:


XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "\\config.xml");
XmlNode settingNode = xmlDoc.DocumentElement;


XmlElement e = settingNode.SelectSingleNode("DeviceType") as XmlElement;
if (e == null)
                {
deviceType = "tps2000";
                }
else
                {
deviceType = e.InnerText;
                }

​5. 带多个参数的委托


            DP1 = new DataProcess(DeviceIP1, LocalPort1,0);
DP1.ShowEvent1 = DrawControls1;
DP1.Start();//启动线程

6.多线程操作





            Thread t1 = new Thread(new ThreadStart(DataRevThread));                  //开启DataRevThread
t1.Name = "DataRevThread";                                          //线程名字
t1.Start();
t1.IsBackground = true;                                                //后台运行

7. UDP接收,解码;
8. emgucv使用;
9. 工厂模式:





   ModelFactory MF = new ModelFactory();
   DM = MF.CreateDataModelFactory_v1(sNeed.ToString());

10.信号量线程间同步





Semaphore TaskSemaphoreData = new Semaphore(0, 2560);         //数据缓存队列缓存区
TaskSemaphoreRev.WaitOne();                //等待接收队列

11.Bitmap转换为ImageSource






      public static extern bool DeleteObject(IntPtr hObject);


      public static ImageSource ChangeBitmapToImageSource(Bitmap bitmap)
      {
            IntPtr hBitmap = bitmap.GetHbitmap();
            ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                hBitmap,
                IntPtr.Zero,
                Int32Rect.Empty,
                BitmapSizeOptions.FromEmptyOptions());


            if (!DeleteObject(hBitmap))
            {
                throw new System.ComponentModel.Win32Exception();
            }
            return wpfBitmap;
      }

12.Queue和list的操作
包括但是不限于以上内容
代码如下:
MainWindow.xaml:


<Fluent:RibbonWindow x:Class="thzSoftware.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Fluent="urn:fluent-ribbon"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
xmlns:local="clr-namespace:thzSoftware"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="800" WindowStartupLocation="CenterScreen" WindowState="Maximized" Background="LightBlue" Closing="RibbonWindow_Closing">
<Grid ShowGridLines="True" >
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="10*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="10*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Name="labelCamera1Status" Content="摄像头连接状态" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="LightCyan"/>
<wfi:WindowsFormsHost Grid.Row="1" Grid.Column="0" Background="LightGray">
<wf:PictureBox x:Name="Cam1" />
</wfi:WindowsFormsHost>
<Label Grid.Row="2" Grid.Column="0" Name="labelCamera2Status"Content="摄像头连接状态" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="LightCyan"/>
<wfi:WindowsFormsHost Grid.Row="3" Grid.Column="0" Background="LightGray">
<wf:PictureBox x:Name="Cam2" />
</wfi:WindowsFormsHost>
<Label Grid.Row="0" Grid.Column="1" Name="labelThz1Status"Content="太赫兹连接状态" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="LightCyan"/>
<Image Grid.Row="1" Grid.Column="1" Name="Thz1"/>
<Label Grid.Row="2" Grid.Column="1" Name="labelThz2Status"Content="太赫兹连接状态" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="LightCyan"/>
<Image Grid.Row="3" Grid.Column="1" Name="Thz2" />

<Image Grid.Row="1" Grid.Column="2" Name="Thz1Image1" />
<Image Grid.Row="1" Grid.Column="3" Name="Thz1Image2" />
<Image Grid.Row="1" Grid.Column="4" Name="Thz1Image3" />
<Image Grid.Row="1" Grid.Column="5" Name="Thz1Image4" />
<Image Grid.Row="1" Grid.Column="6" Name="Thz1Image5" />
<Image Grid.Row="1" Grid.Column="7" Name="Thz1Image6" />
<Image Grid.Row="3" Grid.Column="2" Name="Thz2Image1" />
<Image Grid.Row="3" Grid.Column="3" Name="Thz2Image2" />
<Image Grid.Row="3" Grid.Column="4" Name="Thz2Image3" />
<Image Grid.Row="3" Grid.Column="5" Name="Thz2Image4" />
<Image Grid.Row="3" Grid.Column="6" Name="Thz2Image5" />
<Image Grid.Row="3" Grid.Column="7" Name="Thz2Image6" />
</Grid>
</Fluent:RibbonWindow>



MainWindow.xaml.cs


using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Threading;
using MessageBox = System.Windows.MessageBox;
using thzModel;
using System.Drawing;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Xml;
using Emgu.CV;
using Emgu.CV.Structure;
using System.Threading;
using System.Drawing.Imaging;
using System.Collections.Generic;
using System.Windows.Controls;
using Image = System.Windows.Controls.Image;


namespace thzSoftware
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Fluent.RibbonWindow
    {
DispatcherTimer Cam1ReconnectTimer, Cam2ReconnectTimer;
public MainWindow()
{
try
            {
InitializeComponent();
Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory;

init();
            }
catch (Exception ex)
            {
MessageBox.Show(ex.StackTrace + ex.Message);


LogWrite.logWrite(ex.Message, ex.StackTrace);


            }
      }


public IntPtr PictureDev1Cam { get { return Cam1.Handle; } }
public IntPtr PictureDev2Cam { get { return Cam2.Handle; } }
IntPtr Cam1Handle = IntPtr.Zero;
IntPtr Cam2Handle = IntPtr.Zero;
Camera Camera1 = new Camera();
Camera Camera2 = new Camera();
static private string Cam1IP = "192.168.1.64";
static private string Cam2IP = "192.168.1.61";
DataProcess DP1 = null, DP2 = null;
object ThreadLockBitmap = new object();
List<ImageSource> thzBitmapList1 = new List<ImageSource>();
List<ImageSource> thzBitmapList2 = new List<ImageSource>();
int snapFlag1 = 0, snapFlag2 = 0;
static public String DeviceType
      {
get
            {
return deviceType;
            }
set
            {
deviceType = value;
            }
      }
static private string deviceType = "tps2000";


void init()
{
ReadConfigXML();
Cam1Handle = PictureDev1Cam;
Cam2Handle = PictureDev2Cam;
Cam1.SizeMode = PictureBoxSizeMode.Zoom;
Cam2.SizeMode = PictureBoxSizeMode.Zoom;


Cam1ReconnectTimer = new DispatcherTimer();
Cam1ReconnectTimer.Interval = new TimeSpan(0, 0, 3);//定时间隔3秒
Cam1ReconnectTimer.Tick += Cam1ReconnectTimer_Tick;//加载事件,敲tab键事件框架可以自己出来
Cam1ReconnectTimer.Start();


Cam2ReconnectTimer = new DispatcherTimer();
Cam2ReconnectTimer.Interval = new TimeSpan(0, 0, 3);//定时间隔3秒
Cam2ReconnectTimer.Tick += Cam2ReconnectTimer_Tick;//加载事件,敲tab键事件框架可以自己出来
Cam2ReconnectTimer.Start();


thzModel.Command.CommandUp(8);//发送启动指令


string DeviceIP1 = "192.168.1.110";
int LocalPort1 = 8007;
DP1 = new DataProcess(DeviceIP1, LocalPort1,0);
DP1.ShowEvent1 = DrawControls1;
DP1.Start();//启动线程


string DeviceIP2 = "192.168.1.120";
int LocalPort2 = 8009;
DP2 = new DataProcess(DeviceIP2, LocalPort2, 1);
DP2.ShowEvent2 = DrawControls2;
DP2.Start();//启动线程


      }
private void DrawControls1(Bitmap image, bool isWarning, bool isBlack)
{
Image[] iSource = { Thz1Image1, Thz1Image2, Thz1Image3, Thz1Image4, Thz1Image5, Thz1Image6 };
Dispatcher.Invoke((Action)delegate
            {
labelThz1Status.Content = "太赫兹连接成功";
Thz1.Source = ChangeBitmapToImageSource(image);


snapFlag1++;
thzBitmapList1.Add(Thz1.Source);
if (thzBitmapList1.Count > 6)
thzBitmapList1.RemoveAt(0);
if (snapFlag1 > 8)
                {
snapFlag1 = 0;
for (int i = 0; i < thzBitmapList1.Count; i++)
                  {
iSource.Source = thzBitmapList1;
                  }
                }


            });
      }
      
public static extern bool DeleteObject(IntPtr hObject);


public static ImageSource ChangeBitmapToImageSource(Bitmap bitmap)
{
IntPtr hBitmap = bitmap.GetHbitmap();
ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());


if (!DeleteObject(hBitmap))
            {
throw new System.ComponentModel.Win32Exception();
            }
return wpfBitmap;
      }
private void DrawControls2(Bitmap image, bool isWarning, bool isBlack)
{
Image[] iSource = { Thz2Image1, Thz2Image2, Thz2Image3, Thz2Image4, Thz2Image5, Thz2Image6 };
Dispatcher.Invoke((Action)delegate
            {
labelThz2Status.Content = "太赫兹连接成功";
Thz2.Source = ChangeBitmapToImageSource(image);


snapFlag2++;
thzBitmapList2.Add(Thz2.Source);
if (thzBitmapList2.Count > 6)
thzBitmapList2.RemoveAt(0);
if (snapFlag2 > 8)
                {
snapFlag2 = 0;
for (int i = 0; i < thzBitmapList2.Count; i++)
                  {
iSource.Source = thzBitmapList2;
                  }
                }
            });
      }


private void ReadConfigXML()
{
try
            {
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "\\config.xml");
XmlNode settingNode = xmlDoc.DocumentElement;


XmlElement e = settingNode.SelectSingleNode("DeviceType") as XmlElement;
if (e == null)
                {
deviceType = "tps2000";
                }
else
                {
deviceType = e.InnerText;
                }
            }
catch (Exception ex)
            {
LogWrite.logWrite(ex.Message, ex.StackTrace);
            }
      }
private void ConnectCamera(int whitch)
{
try
            {
string userName = "admin";
string password = "a123456.";
int PortCamera = 8000;
if (whitch == 1)
                {
labelCamera1Status.Content = "摄像头连接中...";
Task.Run(() =>
                  {
if (!Camera1.ConnectCamera(Cam1IP, PortCamera, userName, password))
                        {
Dispatcher.Invoke((Action)delegate { labelCamera1Status.Content = "摄像头连接失败"; });
                        }
else
                        {
Dispatcher.Invoke((Action)delegate { labelCamera1Status.Content = "摄像头连接成功"; });
Camera1.Preview(Cam1Handle);
Camera1.AdjustMirrorPara(1);
Cam1ReconnectTimer.Stop();
                        }
                  });
                }
else
                {
labelCamera2Status.Content = "摄像头连接中...";
Task.Run(() =>
                  {
if (!Camera2.ConnectCamera(Cam2IP, PortCamera, userName, password))
                        {
Dispatcher.Invoke((Action)delegate { labelCamera2Status.Content = "摄像头连接失败"; });
                        }
else
                        {
Dispatcher.Invoke((Action)delegate { labelCamera2Status.Content = "摄像头连接成功"; });
Camera2.Preview(Cam2Handle);
Camera2.AdjustMirrorPara(1);
Cam2ReconnectTimer.Stop();
                        }
                  });
                }
            }
catch (Exception ex)
            {
MessageBox.Show(ex.StackTrace + ex.Message);
LogWrite.logWrite(ex.Message, ex.StackTrace);
            }
      }
private void Cam1ReconnectTimer_Tick(object sender, EventArgs e)
{
ConnectCamera(1);


      }


private void RibbonWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
thzModel.Command.CommandUp(0);//发送停止指令
//Application.Exit();




      }


private void Cam2ReconnectTimer_Tick(object sender, EventArgs e)
{
ConnectCamera(2);
      }





    }


}



​其余部分代码太长,不贴了,需要的话自己下载:百度网盘
链接:https://pan.baidu.com/s/1k2F0C-0gXX-tK_32m_ksOA
提取码:abs5


欢迎关注公众号: dotnet编程大全






https://blog.51cto.com/u_15383815/4863208
页: [1]
查看完整版本: C# WPF项目实战(经典)