Forráskód Böngészése

add: 添加摄像头上位机程序的源码

Wendal Chen 3 éve
szülő
commit
b6a648c90c

+ 16 - 0
usb_camera_wpf/Air105摄像头预览.csproj

@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>WinExe</OutputType>
+    <TargetFramework>net6.0-windows</TargetFramework>
+    <Nullable>enable</Nullable>
+    <UseWindowsForms>true</UseWindowsForms>
+    <ImplicitUsings>enable</ImplicitUsings>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="System.Drawing.Common" Version="6.0.0" />
+    <PackageReference Include="System.IO.Ports" Version="6.0.0" />
+  </ItemGroup>
+
+</Project>

+ 25 - 0
usb_camera_wpf/Air105摄像头预览.sln

@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32319.34
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Air105摄像头预览", "Air105摄像头预览.csproj", "{6A56D66D-C1BB-44A4-AD3A-811D388C6577}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{6A56D66D-C1BB-44A4-AD3A-811D388C6577}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6A56D66D-C1BB-44A4-AD3A-811D388C6577}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6A56D66D-C1BB-44A4-AD3A-811D388C6577}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6A56D66D-C1BB-44A4-AD3A-811D388C6577}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {4A5FE193-6752-4CA8-B3AA-58A4B35D241F}
+	EndGlobalSection
+EndGlobal

+ 151 - 0
usb_camera_wpf/Form1.Designer.cs

@@ -0,0 +1,151 @@
+namespace Air105摄像头预览
+{
+    partial class Form1
+    {
+        /// <summary>
+        ///  Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        ///  Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        ///  Required method for Designer support - do not modify
+        ///  the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.pictureBox_main = new System.Windows.Forms.PictureBox();
+            this.label_comName = new System.Windows.Forms.Label();
+            this.button_power = new System.Windows.Forms.Button();
+            this.label_data_log = new System.Windows.Forms.Label();
+            this.comboBox_coms = new System.Windows.Forms.ComboBox();
+            this.button2 = new System.Windows.Forms.Button();
+            this.label1 = new System.Windows.Forms.Label();
+            this.textBox_br = new System.Windows.Forms.TextBox();
+            ((System.ComponentModel.ISupportInitialize)(this.pictureBox_main)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // pictureBox_main
+            // 
+            this.pictureBox_main.BackColor = System.Drawing.SystemColors.ControlDark;
+            this.pictureBox_main.Location = new System.Drawing.Point(60, 93);
+            this.pictureBox_main.Name = "pictureBox_main";
+            this.pictureBox_main.Size = new System.Drawing.Size(240, 320);
+            this.pictureBox_main.TabIndex = 0;
+            this.pictureBox_main.TabStop = false;
+            // 
+            // label_comName
+            // 
+            this.label_comName.AutoSize = true;
+            this.label_comName.Location = new System.Drawing.Point(12, 14);
+            this.label_comName.Name = "label_comName";
+            this.label_comName.Size = new System.Drawing.Size(39, 20);
+            this.label_comName.TabIndex = 2;
+            this.label_comName.Text = "串口";
+            this.label_comName.Click += new System.EventHandler(this.label_comName_Click);
+            // 
+            // button_power
+            // 
+            this.button_power.BackColor = System.Drawing.Color.Green;
+            this.button_power.Location = new System.Drawing.Point(259, 49);
+            this.button_power.Name = "button_power";
+            this.button_power.Size = new System.Drawing.Size(94, 29);
+            this.button_power.TabIndex = 3;
+            this.button_power.Text = "开始读取";
+            this.button_power.UseVisualStyleBackColor = false;
+            this.button_power.Click += new System.EventHandler(this.button1_Click);
+            // 
+            // label_data_log
+            // 
+            this.label_data_log.AutoSize = true;
+            this.label_data_log.Location = new System.Drawing.Point(12, 438);
+            this.label_data_log.Name = "label_data_log";
+            this.label_data_log.Size = new System.Drawing.Size(69, 20);
+            this.label_data_log.TabIndex = 4;
+            this.label_data_log.Text = "数据日志";
+            // 
+            // comboBox_coms
+            // 
+            this.comboBox_coms.FormattingEnabled = true;
+            this.comboBox_coms.Location = new System.Drawing.Point(92, 12);
+            this.comboBox_coms.Name = "comboBox_coms";
+            this.comboBox_coms.Size = new System.Drawing.Size(151, 28);
+            this.comboBox_coms.TabIndex = 5;
+            // 
+            // button2
+            // 
+            this.button2.Location = new System.Drawing.Point(259, 10);
+            this.button2.Name = "button2";
+            this.button2.Size = new System.Drawing.Size(94, 29);
+            this.button2.TabIndex = 6;
+            this.button2.Text = "刷新串口";
+            this.button2.UseVisualStyleBackColor = true;
+            this.button2.Click += new System.EventHandler(this.button2_Click);
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(13, 49);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(54, 20);
+            this.label1.TabIndex = 7;
+            this.label1.Text = "波特率";
+            // 
+            // textBox_br
+            // 
+            this.textBox_br.Location = new System.Drawing.Point(92, 49);
+            this.textBox_br.Name = "textBox_br";
+            this.textBox_br.Size = new System.Drawing.Size(151, 27);
+            this.textBox_br.TabIndex = 8;
+            this.textBox_br.Text = "1500000";
+            // 
+            // Form1
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.BackColor = System.Drawing.SystemColors.Control;
+            this.ClientSize = new System.Drawing.Size(368, 475);
+            this.Controls.Add(this.textBox_br);
+            this.Controls.Add(this.label1);
+            this.Controls.Add(this.button2);
+            this.Controls.Add(this.comboBox_coms);
+            this.Controls.Add(this.label_data_log);
+            this.Controls.Add(this.button_power);
+            this.Controls.Add(this.label_comName);
+            this.Controls.Add(this.pictureBox_main);
+            this.MaximizeBox = false;
+            this.Name = "Form1";
+            this.Text = "Air105摄像头预览";
+            this.Load += new System.EventHandler(this.Form1_Load);
+            ((System.ComponentModel.ISupportInitialize)(this.pictureBox_main)).EndInit();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private PictureBox pictureBox_main;
+        private Label label_comName;
+        private Button button_power;
+        private Label label_data_log;
+        private ComboBox comboBox_coms;
+        private Button button2;
+        private Label label1;
+        private TextBox textBox_br;
+    }
+}

+ 203 - 0
usb_camera_wpf/Form1.cs

@@ -0,0 +1,203 @@
+using System.Collections.Generic;
+using System.IO.Ports;
+using System.Text.RegularExpressions;
+
+namespace Air105摄像头预览
+{
+    public partial class Form1 : Form
+    {
+        Thread thread;
+        SerialPort serialPort = new SerialPort();
+        string comName = "COM91";
+        bool power_ready = false;
+        int com_br = 1500000;
+        public Form1()
+        {
+            InitializeComponent();
+            thread = new Thread(Run_mac_flasher);
+            thread.Name = "com_reader";
+            thread.IsBackground = true;
+        }
+
+        private void Form1_Load(object sender, EventArgs e)
+        {
+            reload_com_names();
+            thread.Start();
+        }
+        void reload_com_names()
+        {
+            comboBox_coms.Items.Clear();
+            foreach (string com in System.IO.Ports.SerialPort.GetPortNames())
+            {
+                comboBox_coms.Items.Add(com);
+            }
+            if (comboBox_coms.Items.Count > 0)
+            {
+                comboBox_coms.SelectedIndex = 0;
+                //richTextBox_logs.Text = "找到" + comboBox_coms.Items.Count + "个串口";
+            }
+            else
+            {
+                //richTextBox_logs.Text = "没有任何串口";
+            }
+        }
+
+        void show_log(string text)
+        {
+            this.label_data_log.BeginInvoke(new Action(() => {
+                this.label_data_log.Text = text;
+            }));
+        }
+
+        void Run_mac_flasher()
+        {
+            Thread.Sleep(1000);
+            var buff = new byte[64 * 1024];
+            while (true)
+            {
+                if (comName == "" || power_ready == false)
+                {
+                    Thread.Sleep(100);
+                    continue;
+                }
+                if (!serialPort.IsOpen)
+                {
+                    try
+                    {
+                        serialPort.PortName = comName;
+                        serialPort.BaudRate = this.com_br;
+                        serialPort.DataBits = 8;
+                        serialPort.StopBits = StopBits.One;
+                        serialPort.Parity = Parity.None;
+                        serialPort.Open();
+                    }
+                    catch (Exception ex)
+                    {
+                        show_log("打开串口异常 " + comName + " " + ex);
+                        Thread.Sleep(1000);
+                        continue;
+                    }
+                }
+                var rlen = serialPort.Read(buff, 0, buff.Length);
+                var dataHeader = "Air105 USB JPG ";
+                var text = "";
+                for (int i = 0; i < buff.Length; i++)
+                {
+                    //buff[i] = 0;
+                }
+                if (rlen > 0)
+                {
+                    if (buff[0] == 'A' && buff[1] == 'i' && buff[2] == 'r')
+                    {
+                        for (int i = 0; i < buff.Length; i++)
+                        {
+                            if (buff[i] == '\r' && buff[i+1] == '\n')
+                            {
+                                var head = System.Text.Encoding.UTF8.GetString(buff, 0, i);
+                                if (!head.StartsWith(dataHeader))
+                                {
+                                    break;
+                                }
+                                // 解析出长度
+                                var tmp = head.Substring(dataHeader.Length);
+                                var dataRequire = 0;
+                                try
+                                {
+                                    dataRequire = Int32.Parse(tmp);
+                                }
+                                catch (FormatException)
+                                {
+                                    text = "错误的字符串" + tmp + " >> " + head;
+                                    this.label_data_log.BeginInvoke(new Action(() =>
+                                    {
+                                        this.label_data_log.Text = text;
+                                    }));
+                                    break;
+                                }
+                                //var dataRecv = rlen;
+                                while (rlen < dataRequire + i + 2)
+                                {
+                                    var len2 = serialPort.Read(buff, rlen, 8192);
+                                    if (len2 > 0)
+                                    {
+                                        rlen += len2;
+                                    }
+                                    else if (len2 < 0)
+                                    {
+                                        break;
+                                    }
+                                    //Thread.Sleep(1);
+                                }
+                                text = "期待长度 " + (dataRequire  + i + 2) + " 总共读取 " + rlen;
+                                var tmpbuff = new byte[dataRequire];
+                                for (int z = 0; z < dataRequire; z++)
+                                {
+                                    tmpbuff[z] = buff[i + 2 + z];
+                                }
+                                File.WriteAllBytes("temp.jpg", tmpbuff);
+                                System.Drawing.Image image = null;
+                                try
+                                {
+                                    image = System.Drawing.Image.FromStream(new MemoryStream(buff, i + 2, dataRequire));
+                                    text = "图片解码成功 长度" + dataRequire + "字节";
+                                }
+                                catch
+                                {
+                                    text = "图片不合法";
+                                }
+                                this.label_data_log.BeginInvoke(new Action(() =>
+                                {
+                                    this.label_data_log.Text = text;
+                                    if (image != null)
+                                        this.pictureBox_main.Image = image;
+                                }));
+                                break;
+                            }
+                        }
+                    }
+                }
+                Thread.Sleep(100);
+            }
+        }
+
+        private void label_comName_Click(object sender, EventArgs e)
+        {
+
+        }
+
+        private void button2_Click(object sender, EventArgs e)
+        {
+            reload_com_names();
+        }
+
+        private void button1_Click(object sender, EventArgs e)
+        {
+            if (power_ready)
+            {
+                power_ready = false;
+                this.button_power.Text = "开始读取";
+                this.button_power.BackColor = Color.Green;
+                return;
+            }
+            if (this.comboBox_coms.SelectedIndex < 0 || this.comboBox_coms.Items[comboBox_coms.SelectedIndex] == null)
+            {
+                comName = "";
+                MessageBox.Show(this, "请先刷新并选择串口");
+                return;
+            }
+            try
+            {
+                this.com_br = Int32.Parse(this.textBox_br.Text);
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show(this, "波特率不合法,请检查");
+                return;
+            }
+            this.power_ready = true;
+            this.button_power.Text = "停止读取";
+            this.comName = this.comboBox_coms.Items[comboBox_coms.SelectedIndex].ToString();
+            this.button_power.BackColor = Color.Red;
+        }
+    }
+}

+ 60 - 0
usb_camera_wpf/Form1.resx

@@ -0,0 +1,60 @@
+<root>
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 17 - 0
usb_camera_wpf/Program.cs

@@ -0,0 +1,17 @@
+namespace Air105摄像头预览
+{
+    internal static class Program
+    {
+        /// <summary>
+        ///  The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            // To customize application configuration such as set high DPI settings or default font,
+            // see https://aka.ms/applicationconfiguration.
+            ApplicationConfiguration.Initialize();
+            Application.Run(new Form1());
+        }
+    }
+}

+ 7 - 0
usb_camera_wpf/README.md

@@ -0,0 +1,7 @@
+# Air105 USB虚拟串口摄像头的上位机程序
+
+C#  + WPF + VS2022 , 水平有限, 就能用的级别
+
+需要配合 core-air105 和 camera_usb demo来使用
+
+