diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..768f2c1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,360 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates +libs/* +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*[.json, .xml, .info] + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd diff --git a/src/PBAnaly.sln b/src/PBAnaly.sln new file mode 100644 index 0000000..1628aeb --- /dev/null +++ b/src/PBAnaly.sln @@ -0,0 +1,65 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PBAnaly", "PBAnaly\PBAnaly.csproj", "{B9CEF793-3D50-48A7-8B1A-3F121ECABE12}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PBBiology", "PBBiology\PBBiology.vcxproj", "{EC5572D1-750B-4F4B-ADC2-02B9827E0647}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PBBiologyVC", "PBBiologyVC\PBBiologyVC.vcxproj", "{C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12}.Debug|x64.ActiveCfg = Debug|Any CPU + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12}.Debug|x64.Build.0 = Debug|Any CPU + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12}.Debug|x86.ActiveCfg = Debug|Any CPU + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12}.Debug|x86.Build.0 = Debug|Any CPU + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12}.Release|Any CPU.Build.0 = Release|Any CPU + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12}.Release|x64.ActiveCfg = Release|Any CPU + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12}.Release|x64.Build.0 = Release|Any CPU + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12}.Release|x86.ActiveCfg = Release|Any CPU + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12}.Release|x86.Build.0 = Release|Any CPU + {EC5572D1-750B-4F4B-ADC2-02B9827E0647}.Debug|Any CPU.ActiveCfg = Debug|x64 + {EC5572D1-750B-4F4B-ADC2-02B9827E0647}.Debug|Any CPU.Build.0 = Debug|x64 + {EC5572D1-750B-4F4B-ADC2-02B9827E0647}.Debug|x64.ActiveCfg = Debug|x64 + {EC5572D1-750B-4F4B-ADC2-02B9827E0647}.Debug|x64.Build.0 = Debug|x64 + {EC5572D1-750B-4F4B-ADC2-02B9827E0647}.Debug|x86.ActiveCfg = Debug|Win32 + {EC5572D1-750B-4F4B-ADC2-02B9827E0647}.Debug|x86.Build.0 = Debug|Win32 + {EC5572D1-750B-4F4B-ADC2-02B9827E0647}.Release|Any CPU.ActiveCfg = Release|x64 + {EC5572D1-750B-4F4B-ADC2-02B9827E0647}.Release|Any CPU.Build.0 = Release|x64 + {EC5572D1-750B-4F4B-ADC2-02B9827E0647}.Release|x64.ActiveCfg = Release|x64 + {EC5572D1-750B-4F4B-ADC2-02B9827E0647}.Release|x64.Build.0 = Release|x64 + {EC5572D1-750B-4F4B-ADC2-02B9827E0647}.Release|x86.ActiveCfg = Release|Win32 + {EC5572D1-750B-4F4B-ADC2-02B9827E0647}.Release|x86.Build.0 = Release|Win32 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}.Debug|Any CPU.ActiveCfg = Debug|x64 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}.Debug|Any CPU.Build.0 = Debug|x64 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}.Debug|x64.ActiveCfg = Debug|x64 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}.Debug|x64.Build.0 = Debug|x64 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}.Debug|x86.ActiveCfg = Debug|Win32 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}.Debug|x86.Build.0 = Debug|Win32 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}.Release|Any CPU.ActiveCfg = Release|x64 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}.Release|Any CPU.Build.0 = Release|x64 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}.Release|x64.ActiveCfg = Release|x64 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}.Release|x64.Build.0 = Release|x64 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}.Release|x86.ActiveCfg = Release|Win32 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C1622B5B-B88B-4DE1-8CE7-A4398F04AE53} + EndGlobalSection +EndGlobal diff --git a/src/PBAnaly/App.config b/src/PBAnaly/App.config new file mode 100644 index 0000000..193aecc --- /dev/null +++ b/src/PBAnaly/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/PBAnaly/DataProcessForm.Designer.cs b/src/PBAnaly/DataProcessForm.Designer.cs new file mode 100644 index 0000000..316ba42 --- /dev/null +++ b/src/PBAnaly/DataProcessForm.Designer.cs @@ -0,0 +1,194 @@ +namespace PBAnaly +{ + partial class DataProcessForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DataProcessForm)); + this.PictureBoxpanel = new System.Windows.Forms.Panel(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.Control_panel = new System.Windows.Forms.Panel(); + this.panel2 = new System.Windows.Forms.Panel(); + this.materialButton_Load = new MaterialSkin.Controls.MaterialButton(); + this.panel1 = new System.Windows.Forms.Panel(); + this.materialLabel1 = new MaterialSkin.Controls.MaterialLabel(); + this.materialFloatingActionButton_Plus = new MaterialSkin.Controls.MaterialFloatingActionButton(); + this.materialFloatingActionButton_Minus = new MaterialSkin.Controls.MaterialFloatingActionButton(); + this.PictureBoxpanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.Control_panel.SuspendLayout(); + this.panel2.SuspendLayout(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // PictureBoxpanel + // + this.PictureBoxpanel.Controls.Add(this.pictureBox1); + this.PictureBoxpanel.Dock = System.Windows.Forms.DockStyle.Bottom; + this.PictureBoxpanel.Location = new System.Drawing.Point(3, 72); + this.PictureBoxpanel.Margin = new System.Windows.Forms.Padding(0); + this.PictureBoxpanel.Name = "PictureBoxpanel"; + this.PictureBoxpanel.Size = new System.Drawing.Size(408, 351); + this.PictureBoxpanel.TabIndex = 0; + // + // pictureBox1 + // + this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.pictureBox1.Location = new System.Drawing.Point(0, 0); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(408, 351); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBox1.TabIndex = 0; + this.pictureBox1.TabStop = false; + // + // Control_panel + // + this.Control_panel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.Control_panel.Controls.Add(this.panel2); + this.Control_panel.Controls.Add(this.panel1); + this.Control_panel.Dock = System.Windows.Forms.DockStyle.Top; + this.Control_panel.Location = new System.Drawing.Point(3, 24); + this.Control_panel.Name = "Control_panel"; + this.Control_panel.Size = new System.Drawing.Size(408, 44); + this.Control_panel.TabIndex = 1; + // + // panel2 + // + this.panel2.Controls.Add(this.materialButton_Load); + this.panel2.Dock = System.Windows.Forms.DockStyle.Left; + this.panel2.Location = new System.Drawing.Point(0, 0); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(42, 40); + this.panel2.TabIndex = 1; + // + // materialButton_Load + // + this.materialButton_Load.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_Load.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_Load.Depth = 0; + this.materialButton_Load.Dock = System.Windows.Forms.DockStyle.Left; + this.materialButton_Load.HighEmphasis = true; + this.materialButton_Load.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_Load.Icon"))); + this.materialButton_Load.Location = new System.Drawing.Point(0, 0); + this.materialButton_Load.Margin = new System.Windows.Forms.Padding(4, 6, 4, 6); + this.materialButton_Load.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_Load.Name = "materialButton_Load"; + this.materialButton_Load.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_Load.Size = new System.Drawing.Size(64, 40); + this.materialButton_Load.TabIndex = 0; + this.materialButton_Load.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_Load.UseAccentColor = true; + this.materialButton_Load.UseVisualStyleBackColor = true; + // + // panel1 + // + this.panel1.Controls.Add(this.materialLabel1); + this.panel1.Controls.Add(this.materialFloatingActionButton_Plus); + this.panel1.Controls.Add(this.materialFloatingActionButton_Minus); + this.panel1.Dock = System.Windows.Forms.DockStyle.Right; + this.panel1.Location = new System.Drawing.Point(259, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(145, 40); + this.panel1.TabIndex = 0; + // + // materialLabel1 + // + this.materialLabel1.AutoSize = true; + this.materialLabel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.materialLabel1.Depth = 0; + this.materialLabel1.Font = new System.Drawing.Font("Roboto", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.materialLabel1.FontType = MaterialSkin.MaterialSkinManager.fontType.Caption; + this.materialLabel1.ForeColor = System.Drawing.SystemColors.Desktop; + this.materialLabel1.Location = new System.Drawing.Point(54, 12); + this.materialLabel1.MouseState = MaterialSkin.MouseState.HOVER; + this.materialLabel1.Name = "materialLabel1"; + this.materialLabel1.Size = new System.Drawing.Size(16, 14); + this.materialLabel1.TabIndex = 2; + this.materialLabel1.Text = "1X"; + // + // materialFloatingActionButton_Plus + // + this.materialFloatingActionButton_Plus.Depth = 0; + this.materialFloatingActionButton_Plus.Icon = ((System.Drawing.Image)(resources.GetObject("materialFloatingActionButton_Plus.Icon"))); + this.materialFloatingActionButton_Plus.Location = new System.Drawing.Point(88, 2); + this.materialFloatingActionButton_Plus.Mini = true; + this.materialFloatingActionButton_Plus.MouseState = MaterialSkin.MouseState.HOVER; + this.materialFloatingActionButton_Plus.Name = "materialFloatingActionButton_Plus"; + this.materialFloatingActionButton_Plus.Size = new System.Drawing.Size(40, 40); + this.materialFloatingActionButton_Plus.TabIndex = 1; + this.materialFloatingActionButton_Plus.Text = "materialFloatingActionButton2"; + this.materialFloatingActionButton_Plus.UseVisualStyleBackColor = true; + // + // materialFloatingActionButton_Minus + // + this.materialFloatingActionButton_Minus.Depth = 0; + this.materialFloatingActionButton_Minus.Icon = ((System.Drawing.Image)(resources.GetObject("materialFloatingActionButton_Minus.Icon"))); + this.materialFloatingActionButton_Minus.Location = new System.Drawing.Point(2, 2); + this.materialFloatingActionButton_Minus.Mini = true; + this.materialFloatingActionButton_Minus.MouseState = MaterialSkin.MouseState.HOVER; + this.materialFloatingActionButton_Minus.Name = "materialFloatingActionButton_Minus"; + this.materialFloatingActionButton_Minus.Size = new System.Drawing.Size(40, 40); + this.materialFloatingActionButton_Minus.TabIndex = 0; + this.materialFloatingActionButton_Minus.Text = "materialFloatingActionButton1"; + this.materialFloatingActionButton_Minus.UseVisualStyleBackColor = true; + // + // DataProcessForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(414, 426); + this.Controls.Add(this.PictureBoxpanel); + this.Controls.Add(this.Control_panel); + this.FormStyle = MaterialSkin.Controls.MaterialForm.FormStyles.ActionBar_None; + this.Name = "DataProcessForm"; + this.Padding = new System.Windows.Forms.Padding(3, 24, 3, 3); + this.Text = "DataProcessForm"; + this.PictureBoxpanel.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.Control_panel.ResumeLayout(false); + this.panel2.ResumeLayout(false); + this.panel2.PerformLayout(); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel PictureBoxpanel; + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.Panel Control_panel; + private System.Windows.Forms.Panel panel2; + private MaterialSkin.Controls.MaterialButton materialButton_Load; + private System.Windows.Forms.Panel panel1; + private MaterialSkin.Controls.MaterialLabel materialLabel1; + private MaterialSkin.Controls.MaterialFloatingActionButton materialFloatingActionButton_Plus; + private MaterialSkin.Controls.MaterialFloatingActionButton materialFloatingActionButton_Minus; + } +} \ No newline at end of file diff --git a/src/PBAnaly/DataProcessForm.cs b/src/PBAnaly/DataProcessForm.cs new file mode 100644 index 0000000..d4f950f --- /dev/null +++ b/src/PBAnaly/DataProcessForm.cs @@ -0,0 +1,228 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using MaterialSkin; +using MaterialSkin.Controls; +using OpenCvSharp; +using OpenCvSharp.Extensions; +using PBAnaly.Module; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.Rebar; + +namespace PBAnaly +{ + public partial class DataProcessForm : MaterialForm + { + private Mat image = null; + private string filePath = ""; + private List bands = new List(); + private Cursor cursor = null; + private int bands_index = -1; + + public DataProcessForm(MaterialSkinManager materialSkinManager,string filePath) + { + InitializeComponent(); + UIInit(); + Inn_materialSkinManager = materialSkinManager; + this.filePath = filePath; + image = Cv2.ImRead(filePath, ImreadModes.Unchanged); + + if (image.Depth() != MatType.CV_8U) + { + Mat convertedImage = new Mat(); + image.ConvertTo(convertedImage, MatType.CV_8U, 0.00390625); + pictureBox1.Image = convertedImage.ToBitmap(); + } + else + { + pictureBox1.Image = image.ToBitmap(); + } + this.MouseDown += DataProcessForm_MouseDown; + this.pictureBox1.MouseMove += PictureBox1_MouseMove; + this.pictureBox1.MouseDown += PictureBox1_MouseDown; + } + + private void PictureBox1_MouseDown(object sender, MouseEventArgs e) + { + if (cursor != null) + { + if (cursor == Cursors.SizeAll) + { + for (int i = 0; i < bands.Count(); i++) + { + PBAnalyCommMannager.band_infos _band= bands[i]; + if (bands_index == i) + { + _band.thick = 2; + if(PBAnalyCommMannager.laneChartForm!=null) + PBAnalyCommMannager.laneChartForm.Draw(_band); + } + else + { + _band.thick = 1; + } + bands[i] = _band; + } + Draw(); + } + } + } + + private void PictureBox1_MouseMove(object sender, MouseEventArgs e) + { + if (pictureBox1.Image == null) return; + #region + // 获取PictureBox的尺寸和图像的原始尺寸 + float imageWidth = pictureBox1.Image.Width; + float imageHeight = pictureBox1.Image.Height; + float pictureBoxWidth = pictureBox1.Width; + float pictureBoxHeight = pictureBox1.Height; + + // 计算缩放比例 + float scaleX = pictureBoxWidth / imageWidth; + float scaleY = pictureBoxHeight / imageHeight; + float scale = Math.Min(scaleX, scaleY); + + // 计算图像实际显示的尺寸 + float displayWidth = imageWidth * scale; + float displayHeight = imageHeight * scale; + + // 计算图像在PictureBox中的位置偏移 + float offsetX = (pictureBoxWidth - displayWidth) / 2; + float offsetY = (pictureBoxHeight - displayHeight) / 2; + + // 转换坐标 + int actualX = (int)Math.Floor((e.X - offsetX) / scale); + int actualY = (int)Math.Floor((e.Y - offsetY) / scale); + + this.pictureBox1.Cursor = Cursors.Default; + // 确保坐标在有效范围内 + if (actualX >= 0 && actualX <= imageWidth && actualY >= 0 && actualY <= imageHeight) + { + int index = 0; + foreach (var item in bands) + { + if (actualX >= item.startX - 3 && actualX <= item.startX + 3) + { + bands_index = index; + cursor = Cursors.SizeWE; + this.pictureBox1.Cursor = Cursors.SizeWE; + break; + } + else if (actualX > item.startX + 3 && actualX < item.endX - 3) + { + bands_index = index; + cursor = Cursors.SizeAll; + this.pictureBox1.Cursor = Cursors.SizeAll; + break; + } + else if (actualX >= item.endX - 3 && actualX <= item.endX + 3) + { + bands_index = index; + cursor = Cursors.SizeWE; + this.pictureBox1.Cursor = Cursors.SizeWE; + break; + } + index++; + } + + } + + #endregion + + #region 根据获得到的图像索引去找是那个矩形 + #endregion + + } + + private void DataProcessForm_MouseDown(object sender, MouseEventArgs e) + { + + PBAnalyCommMannager.processForm = this; + Console.WriteLine("切换form:"+filePath); + } + + public MaterialSkinManager Inn_materialSkinManager; + + public void UIInit() + { + this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true); + Inn_materialSkinManager = MaterialSkinManager.Instance; // 初始化 MaterialSkinManager 实例 + Inn_materialSkinManager.AddFormToManage(this); // 将要应用 Material Design 的窗体添加到管理列表中 + //Inn_materialSkinManager.Theme = MaterialSkinManager.Themes.DARK; // Theme 属性用来设置整体的主题 + //Inn_materialSkinManager.ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.Cyan700, TextShade.WHITE); // ColorScheme 属性来设置配色方案 + } + + + + #region 对外接口 + public Mat getImage + { + get { return image; } + } + + public Mat SetImage + { + set + { + + var bitmapImage = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(value); + pictureBox1.Image = bitmapImage; + } + } + + public List SetBands + { + set + { + this.bands = value; + } + } + + /// + /// 在原图基础上绘制泳道或者条带 + /// + public void Draw() + { + Mat input_cn1 = new Mat(); + image.ConvertTo(input_cn1, MatType.CV_8U, 0.00390625); + if (input_cn1.Channels() == 1) + { + Cv2.CvtColor(input_cn1, input_cn1, ColorConversionCodes.GRAY2BGR); + } + foreach (var _band in bands) + { + + OpenCvSharp.Point rectStart = new OpenCvSharp.Point(_band.startX, _band.startY); + OpenCvSharp.Point rectEnd = new OpenCvSharp.Point(_band.endX, _band.endY); + Cv2.Rectangle(input_cn1, rectStart, rectEnd, _band.color, _band.thick); // 线条粗细为2 + + + // 绘制十字形 + // 十字线长度 + int lineLength = 5; // 可以根据实际需求调整 + float centerX = (float)(rectStart.X +(rectEnd.X - rectStart.X)/2.0); + float centerY = rectStart.Y + _band._Info.band_point[0][0]; + int thickness = 1; + Scalar crossColor = new Scalar(0, 0, 255); // 红色 + // 水平线 + Cv2.Line(input_cn1, new OpenCvSharp.Point(centerX - lineLength, centerY), new OpenCvSharp.Point(centerX + lineLength, centerY), crossColor, thickness); + // 垂直线 + Cv2.Line(input_cn1, new OpenCvSharp.Point(centerX, centerY - lineLength), new OpenCvSharp.Point(centerX, centerY + lineLength), crossColor, thickness); + + // 绘制条带矩形 + crossColor = new Scalar(255, 0, 0); // 蓝色 + OpenCvSharp.Point rectStart1 = new OpenCvSharp.Point(_band.startX, rectStart.Y + _band._Info.band_point[0][1]); + OpenCvSharp.Point rectEnd1 = new OpenCvSharp.Point(_band.endX, rectStart.Y + _band._Info.band_point[0][2]); + Cv2.Rectangle(input_cn1, rectStart1, rectEnd1, crossColor, thickness); // 线条粗细为2 + } + SetImage = input_cn1; + } + #endregion + } +} diff --git a/src/PBAnaly/DataProcessForm.resx b/src/PBAnaly/DataProcessForm.resx new file mode 100644 index 0000000..bb187ea --- /dev/null +++ b/src/PBAnaly/DataProcessForm.resx @@ -0,0 +1,429 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + 3f4/vwXOM7HXEWEAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABGdBTUEAALGPC/xhBQAAArZJREFUaEPt + mMtqFkEQhf+FcWNIVDAI6k5NBBfe4sZ3MCr4JhJ1n6jrGFwZ9CFc5aIg+AK6SMSVqBvxgkR0pe130qch + hsykozP/BfqDQ2aqa6qqk56e6nQKhUKh0LeEEE6hW2gFraHvlq6X0U00Yff+gaIm0VOUywt0yY/3DooY + Qg/QbyQ+owV0GY2jfZaup5DGviChZ+bRkMN1FxIfRM+Q+IFm0IiHK8FnFM36GaG/3AEPdwcS6jeflswH + NOmhbHjmDHqrAPAc7fVQ+5BMy0a8Q0ds3jV6Fr1XIJi3uV1IdBFp/WoJnLN5Wxi/Lvl2Wxi/gH4ixTxv + c3uQJK37GZsqsV/wbSW43I2eYcWmdiCB9nmh3Sbnhd3At5Xgohc77U7jNjcPwW/HHOGhTbXYd8cJCNwe + Re8wbVPzEFxfUzFlUy32zZ3A1egdlmxqHoK/iTnCcZtqsW/uBPSxE2s2NQ/B12OOMGzTBtxrt9ktf+1O + 3A9Hc1i3qXkUPOZoZQIj0Ry+2dQ8BH8dc4QTNtVi39wlNBG9w6pNzUPwNl/ia9E7LNrUPARXPy8WbKrF + vrkTeBy9ww2bmofg6c+sD9mozZVE150ngMt+lD5kJ21uBxKkLnTWpkrslzOBe9EzLNvUHiRR85Waudrm + i/GcZk6nOTVzv1Btc9gYJNJJSnxE/9NOH0WpnZ6zuX1Ipj5eh3XxCf3LgeYs6v6BhkRj6JWyQpqElsAd + lPNi64XVmtczQv/B6M6RkkSH0EtlhVV0DN1H6VCvnURd5RWkHUvtgaRrNWvaKr8ioTU/h/Y4fLuQaGvx + hz2ksdPoiQYy0QexOy+sIFll8ZvBro5yGi3ZT72TpOtFpLF29/mtkDCr+L6EYkvxPYFiS/E9gWIHuvjN + X1j9HPPQYKCCXfjgFZ/wJAaz+EKhUOgCnc4fDoTrsg1LNtUAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABGdBTUEAALGPC/xhBQAAApJJREFUaEPt + mE1LVkEcxZ9Ftkm0giSodpUGLXqzTd8hK/CbhNVeq7VJq6Q+RCtfCoK+QC00WkW1iV4Io1Y1/Y5zBkQQ + r96Z5wXmBwfvc+be859H5879XzuVSqVS6VtCCOfQXbSK1tEvS8cr6A6a8On9A5OaRC9QU16ja768dzCJ + IfQY/UPiG1pE19E4OmTpeApp7DsSumYBDTmuu1D4KHqJxG80i0Y8vCOcM4rmfI3QX+6Ih7sDBfWbT0vm + M5r0UGO45gL6oAB4hQ56qDwU07IRH9EJ23tG16JPCoIF22Wh0FWk9aslcMn2viHjCvrjzMu2y0GRtO5n + bbWGrAcxMqzaKgMFtM8L7Ta73rBNIUs3dtqdxm3nh/B7sUZ4YisbZD6N0WHGVn4I19NUTNnKBpk3Y3RY + tpUfwt/HGuG0rWyQqYedWLeVH8I3Yo0wbGsTPk9He09M+/JN+Dwc7bBhKz8KjzWKfIGRaIeftvJD+LtY + I5yxlQ0yJ2J0WLOVH8JL3sS3YnRYspUfwtXPi0Vb2SDzWYwOt23lh/D0Z9aDbNR2a8g6jNKD7KztMlAg + daFztlpD1sMYGVZslYMiar5SM9e6+SJDb3Nq5v6i1s1hIyikNynxBbVpp0+i1E7P2y4PxdTH62VdfEX7 + eaG5iLr/QkOhMfRWVSF9CS2B+2jXG5tzdMNqzesaof9gdOeVkkLH0BtVhTV0Cj1C6aVeO4m6yhtIO5ba + A0nHata0Vf5AQmt+Hh1wfFkotH3yxz2ksfPouQYaogdid25YQbEdJ78VfHWUM2jZ56l3knS8hDRWdp/f + DgUbTb4vYbJ18j2BydbJ9wQmO9CT3/qE1c8xDw0GmrAnPniTT/hLDObkK5VKpQt0Ov8B5C6OuhEACIYA + AAAASUVORK5CYII= + + + \ No newline at end of file diff --git a/src/PBAnaly/GS-Analy.ico b/src/PBAnaly/GS-Analy.ico new file mode 100644 index 0000000..0b62269 Binary files /dev/null and b/src/PBAnaly/GS-Analy.ico differ diff --git a/src/PBAnaly/LaneChartForm.Designer.cs b/src/PBAnaly/LaneChartForm.Designer.cs new file mode 100644 index 0000000..4b42075 --- /dev/null +++ b/src/PBAnaly/LaneChartForm.Designer.cs @@ -0,0 +1,127 @@ +namespace PBAnaly +{ + partial class LaneChartForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea(); + System.Windows.Forms.DataVisualization.Charting.Legend legend2 = new System.Windows.Forms.DataVisualization.Charting.Legend(); + System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series(); + System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint5 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(1D, 5D); + System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint6 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(1.5D, 5D); + System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint7 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(1.9D, 8D); + System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint8 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(0D, 0D); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.文件ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.选项ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.chart1 = new System.Windows.Forms.DataVisualization.Charting.Chart(); + this.menuStrip1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.chart1)).BeginInit(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.文件ToolStripMenuItem, + this.选项ToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(3, 24); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Padding = new System.Windows.Forms.Padding(4, 2, 0, 2); + this.menuStrip1.Size = new System.Drawing.Size(899, 25); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // 文件ToolStripMenuItem + // + this.文件ToolStripMenuItem.Name = "文件ToolStripMenuItem"; + this.文件ToolStripMenuItem.Size = new System.Drawing.Size(44, 21); + this.文件ToolStripMenuItem.Text = "文件"; + // + // 选项ToolStripMenuItem + // + this.选项ToolStripMenuItem.Name = "选项ToolStripMenuItem"; + this.选项ToolStripMenuItem.Size = new System.Drawing.Size(44, 21); + this.选项ToolStripMenuItem.Text = "选项"; + // + // chart1 + // + chartArea2.Name = "ChartArea1"; + this.chart1.ChartAreas.Add(chartArea2); + this.chart1.Dock = System.Windows.Forms.DockStyle.Fill; + legend2.Name = "Legend1"; + this.chart1.Legends.Add(legend2); + this.chart1.Location = new System.Drawing.Point(3, 49); + this.chart1.Margin = new System.Windows.Forms.Padding(2); + this.chart1.Name = "chart1"; + this.chart1.Palette = System.Windows.Forms.DataVisualization.Charting.ChartColorPalette.Bright; + series2.ChartArea = "ChartArea1"; + series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine; + series2.Legend = "Legend1"; + series2.Name = "Series1"; + series2.Points.Add(dataPoint5); + series2.Points.Add(dataPoint6); + series2.Points.Add(dataPoint7); + series2.Points.Add(dataPoint8); + this.chart1.Series.Add(series2); + this.chart1.Size = new System.Drawing.Size(899, 366); + this.chart1.TabIndex = 1; + this.chart1.Text = "chart1"; + this.chart1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart1_MouseDown); + this.chart1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.chart1_MouseUp); + // + // LaneChartForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(905, 418); + this.Controls.Add(this.chart1); + this.Controls.Add(this.menuStrip1); + this.DrawerAutoShow = true; + this.FormStyle = MaterialSkin.Controls.MaterialForm.FormStyles.ActionBar_None; + this.MainMenuStrip = this.menuStrip1; + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "LaneChartForm"; + this.Padding = new System.Windows.Forms.Padding(3, 24, 3, 3); + this.Text = "LaneChartForm"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.LaneChartForm_FormClosing); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.chart1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem 文件ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 选项ToolStripMenuItem; + private System.Windows.Forms.DataVisualization.Charting.Chart chart1; + } +} \ No newline at end of file diff --git a/src/PBAnaly/LaneChartForm.cs b/src/PBAnaly/LaneChartForm.cs new file mode 100644 index 0000000..12d5750 --- /dev/null +++ b/src/PBAnaly/LaneChartForm.cs @@ -0,0 +1,252 @@ +using MaterialSkin.Controls; +using PBBiologyVC; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Windows.Forms.DataVisualization.Charting; +using System.Windows.Markup; +using System.Xml.Linq; +using static PBAnaly.Module.PBAnalyCommMannager; + +namespace PBAnaly +{ + public partial class LaneChartForm : MaterialForm + { + + + public LaneChartForm() + { + InitializeComponent(); + } + + public void Draw(band_infos band_info) + { + chart1.ChartAreas.Clear(); + chart1.Series.Clear(); + chart1.Annotations.Clear(); + ChartArea chartArea = new ChartArea(); + chartArea.AxisX.Minimum = 0; + chartArea.AxisX.Maximum = 1; + + var xdata = band_info._Info.xdata; + var ydata = band_info._Info.ydata; + float maxY = ydata.Max(); + double maxX = xdata[ydata.IndexOf(maxY)]; + curmaxY = maxY; + curmaxX = maxX; + // 显著增加Y轴的显示范围以确保箭头可见 + chartArea.AxisY.Minimum = 0; // 适当设置以显示更低的值 + chartArea.AxisY.Maximum = maxY * 1.3; // 增加额外空间显示箭头 + + chart1.ChartAreas.Add(chartArea); + + Series series = new Series + { + ChartType = SeriesChartType.Line, + BorderWidth = 2 + }; + + for (int i = 0; i < xdata.Count; i++) + { + series.Points.AddXY(xdata[i], ydata[i]); + } + + chart1.Series.Add(series); + + // 确保箭头和标注在可见范围 + chart1.ResetAutoValues(); + + // 创建一个显著可见的箭头注释 + ArrowAnnotation arrow = new ArrowAnnotation(); + arrow.ArrowSize = 2; // 增大箭头大小 + arrow.ArrowStyle = ArrowStyle.Simple; + arrow.LineColor = Color.Black; // 使用红色以增加可见性 + arrow.LineWidth = 2; // 增加线宽 + arrow.AnchorDataPoint = series.Points.FindByValue(maxY); // 直接锚定到最大值点 + arrow.Height = 10; // 增加箭头长度 + arrow.Width = 0; // 宽度为0 + arrow.AllowMoving = false; // 允许移动 + arrow.IsSizeAlwaysRelative = false; // 设置大小不总是相对的,以便可拖动 + + chart1.Annotations.Add(arrow); + + + int x = band_info._Info.band_point[0][1]; + int x1 = band_info._Info.band_point[0][2]; + float curY = ydata[x]; + float curY1 = ydata[x1]; + float curX = xdata[x]; + //// 添加括号的文本注释 + TextAnnotation leftBracket = new TextAnnotation(); + leftBracket.Name = "left"; + leftBracket.Text = "["; + leftBracket.Font = new Font("Arial", 12, FontStyle.Regular); // 设置字体样式 + leftBracket.ForeColor = Color.Black; + var da = series.Points.FindAllByValue(curY); + foreach (var d in da) + { + if (d.XValue == curX) + { + leftBracket.AnchorDataPoint = d; // 直接锚定到最大值点 + break; + } + + } + //leftBracket.AnchorDataPoint = series.Points.FindAllByValue*.FindByValue(curY); // 直接锚定到最大值点 + leftBracket.Height = 1; // 增加箭头长度 + leftBracket.Width =10; // 宽度为0 + + + chart1.Annotations.Add(leftBracket); + + TextAnnotation reghtBracket = new TextAnnotation(); + reghtBracket.Name = "right"; + reghtBracket.Text = "]"; + reghtBracket.Font = new Font("Arial", 12, FontStyle.Regular); // 设置字体样式 + reghtBracket.ForeColor = Color.Black; + reghtBracket.AnchorDataPoint = series.Points.FindByValue(curY1); // 直接锚定到最大值点 + reghtBracket.Height = 1; // 增加箭头长度 + reghtBracket.Width = 10; // 宽度为0 + + + chart1.Annotations.Add(reghtBracket); + + chart1.MouseMove += chart1_MouseMove; + + } + private bool isAnnotationMoving = false; + private Annotation selectedAnnotation = null; + private PointF startLocation; + private float curmaxY = 0; + private double curmaxX = 0; + + private void chart1_MouseMove(object sender, MouseEventArgs e) + { + + + var hit = chart1.HitTest(e.X, e.Y, ChartElementType.Annotation); + + if (hit.ChartElementType == ChartElementType.Annotation) + { + var annotation = hit.Object as Annotation; + if (annotation != null) + { + if (annotation.Name == "left" || annotation.Name == "right") + { + chart1.Cursor = Cursors.SizeWE; + } + } + + } + else + { + chart1.Cursor = Cursors.Default; + } + + + if (isAnnotationMoving && selectedAnnotation != null) + { + double xVal = 0; + try + { + xVal = chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X); + } + catch (Exception) + { + + return; + } + if (selectedAnnotation.Name == "left") + { + if (xVal < 0 || xVal > curmaxX) + { + return; + } + } + else if (selectedAnnotation.Name == "right") + { + if (xVal < curmaxX || xVal> 1) + { + return; + } + } + + + + int index = FindClosestPointIndex(xVal); + + if (index != -1) + { + selectedAnnotation.AnchorDataPoint = chart1.Series[0].Points[index]; + + } + } + + + } + + private int FindClosestPointIndex(double xVal) + { + Series series = chart1.Series[0]; + double minDistance = double.MaxValue; + int closestIndex = -1; + + for (int i = 0; i < series.Points.Count; i++) + { + double distance = Math.Abs(series.Points[i].XValue - xVal); + if (distance < minDistance) + { + minDistance = distance; + closestIndex = i; + } + } + + return closestIndex; + } + + private void chart1_MouseDown(object sender, MouseEventArgs e) + { + var hit = chart1.HitTest(e.X, e.Y, ChartElementType.Annotation); + + if (hit.ChartElementType == ChartElementType.Annotation) + { + var annotation = hit.Object as Annotation; + if (annotation != null) + { + if (annotation.Name == "left" || annotation.Name == "right") + { + chart1.Cursor = Cursors.SizeWE; + isAnnotationMoving = true; + selectedAnnotation = annotation; + startLocation = new PointF(e.X, e.Y); + Console.WriteLine(annotation.Name); + } + + } + + } + } + + private void chart1_MouseUp(object sender, MouseEventArgs e) + { + if (isAnnotationMoving) + { + isAnnotationMoving = false; + selectedAnnotation = null; + + } + } + + private void LaneChartForm_FormClosing(object sender, FormClosingEventArgs e) + { + this.Hide();//窗体只被隐藏不被关闭 + e.Cancel = true; + } + } +} \ No newline at end of file diff --git a/src/PBAnaly/LaneChartForm.resx b/src/PBAnaly/LaneChartForm.resx new file mode 100644 index 0000000..d5494e3 --- /dev/null +++ b/src/PBAnaly/LaneChartForm.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/src/PBAnaly/LogForm.Designer.cs b/src/PBAnaly/LogForm.Designer.cs new file mode 100644 index 0000000..f10c088 --- /dev/null +++ b/src/PBAnaly/LogForm.Designer.cs @@ -0,0 +1,133 @@ +namespace PBAnaly +{ + partial class LogForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); + this.panel1 = new System.Windows.Forms.Panel(); + this.Log_dataGridView = new System.Windows.Forms.DataGridView(); + this.Item = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Description = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Time = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.panel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.Log_dataGridView)).BeginInit(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.Controls.Add(this.Log_dataGridView); + this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel1.Location = new System.Drawing.Point(3, 64); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(670, 349); + this.panel1.TabIndex = 0; + // + // Log_dataGridView + // + this.Log_dataGridView.BackgroundColor = System.Drawing.Color.DimGray; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.ControlDarkDark; + dataGridViewCellStyle1.Font = new System.Drawing.Font("新細明體", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(136))); + dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.ControlDarkDark; + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.Log_dataGridView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; + this.Log_dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.Log_dataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.Item, + this.Description, + this.Time}); + dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.WindowFrame; + dataGridViewCellStyle2.Font = new System.Drawing.Font("新細明體", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(136))); + dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; + dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.ControlLightLight; + dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.Log_dataGridView.DefaultCellStyle = dataGridViewCellStyle2; + this.Log_dataGridView.Dock = System.Windows.Forms.DockStyle.Fill; + this.Log_dataGridView.GridColor = System.Drawing.SystemColors.Control; + this.Log_dataGridView.Location = new System.Drawing.Point(0, 0); + this.Log_dataGridView.Name = "Log_dataGridView"; + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle3.Font = new System.Drawing.Font("新細明體", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(136))); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.Log_dataGridView.RowHeadersDefaultCellStyle = dataGridViewCellStyle3; + this.Log_dataGridView.RowHeadersVisible = false; + this.Log_dataGridView.RowTemplate.Height = 24; + this.Log_dataGridView.Size = new System.Drawing.Size(670, 349); + this.Log_dataGridView.TabIndex = 0; + // + // Item + // + this.Item.HeaderText = "Item"; + this.Item.Name = "Item"; + // + // Description + // + this.Description.HeaderText = "Description"; + this.Description.Name = "Description"; + this.Description.Width = 400; + // + // Time + // + this.Time.HeaderText = "Time"; + this.Time.Name = "Time"; + this.Time.Width = 150; + // + // LogForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoSize = true; + this.ClientSize = new System.Drawing.Size(676, 416); + this.Controls.Add(this.panel1); + this.Name = "LogForm"; + this.Text = "LogForm"; + this.panel1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.Log_dataGridView)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.DataGridView Log_dataGridView; + private System.Windows.Forms.DataGridViewTextBoxColumn Item; + private System.Windows.Forms.DataGridViewTextBoxColumn Description; + private System.Windows.Forms.DataGridViewTextBoxColumn Time; + } +} \ No newline at end of file diff --git a/src/PBAnaly/LogForm.cs b/src/PBAnaly/LogForm.cs new file mode 100644 index 0000000..f9c45bc --- /dev/null +++ b/src/PBAnaly/LogForm.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using MaterialSkin; +using MaterialSkin.Controls; + +namespace PBAnaly +{ + public partial class LogForm : MaterialForm + { + string Inner_UserID; + public LogForm(MaterialSkinManager materialSkinManager,string UserID) + { + InitializeComponent(); + Inner_UserID = UserID; + UIInit(); + LoadLogToList(); + } + + public MaterialSkinManager Inn_materialSkinManager; + + public void UIInit() + { + this.Text = string.Format("Current User : {0}", Inner_UserID); + //this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true); + Inn_materialSkinManager = MaterialSkinManager.Instance; // 初始化 MaterialSkinManager 实例 + //Inn_materialSkinManager.AddFormToManage(this); // 将要应用 Material Design 的窗体添加到管理列表中 + //Inn_materialSkinManager.Theme = MaterialSkinManager.Themes.DARK; // Theme 属性用来设置整体的主题 + //Inn_materialSkinManager.ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.Cyan700, TextShade.WHITE); // ColorScheme 属性来设置配色方案 + + if (Inn_materialSkinManager.Theme == MaterialSkinManager.Themes.DARK) + { + Log_dataGridView.DefaultCellStyle.BackColor = Color.DimGray; + } + else + { + Log_dataGridView.DefaultCellStyle.BackColor = Color.LightGray; + } + } + + private void LoadLogToList() + { + // Save Log Information + Read_Write_Log read_Write_Log = new Read_Write_Log(); + string SaveLogFile = read_Write_Log.LogFile; + + List OldLog = new List(); + if (File.Exists(SaveLogFile)) + { + OldLog = read_Write_Log.ReadCsv(SaveLogFile); + } + + if (OldLog != null && OldLog.Count > 0) + { + int count = 0; + foreach (var item in OldLog) + { + if(Inner_UserID == item.UserID) + { + Log_dataGridView.Rows.Insert(count, item.ITEM, item.Description, item.Time); + count++; + } + } + } + } + } +} diff --git a/src/PBAnaly/LogForm.resx b/src/PBAnaly/LogForm.resx new file mode 100644 index 0000000..1db2e3e --- /dev/null +++ b/src/PBAnaly/LogForm.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + \ No newline at end of file diff --git a/src/PBAnaly/LoginForm.Designer.cs b/src/PBAnaly/LoginForm.Designer.cs new file mode 100644 index 0000000..ffad008 --- /dev/null +++ b/src/PBAnaly/LoginForm.Designer.cs @@ -0,0 +1,181 @@ +namespace PBAnaly +{ + partial class LoginForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.userName_materialTextBox = new MaterialSkin.Controls.MaterialTextBox2(); + this.password_materialTextBox = new MaterialSkin.Controls.MaterialTextBox2(); + this.Login_materialButton = new MaterialSkin.Controls.MaterialButton(); + this.SIGNIN_materialButton = new MaterialSkin.Controls.MaterialButton(); + this.rememberme_materialCheckbox = new MaterialSkin.Controls.MaterialCheckbox(); + this.SuspendLayout(); + // + // userName_materialTextBox + // + this.userName_materialTextBox.AnimateReadOnly = false; + this.userName_materialTextBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.userName_materialTextBox.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal; + this.userName_materialTextBox.Depth = 0; + this.userName_materialTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.userName_materialTextBox.HideSelection = true; + this.userName_materialTextBox.LeadingIcon = null; + this.userName_materialTextBox.Location = new System.Drawing.Point(59, 90); + this.userName_materialTextBox.MaxLength = 32767; + this.userName_materialTextBox.MouseState = MaterialSkin.MouseState.OUT; + this.userName_materialTextBox.Name = "userName_materialTextBox"; + this.userName_materialTextBox.PasswordChar = '\0'; + this.userName_materialTextBox.PrefixSuffixText = null; + this.userName_materialTextBox.ReadOnly = false; + this.userName_materialTextBox.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.userName_materialTextBox.SelectedText = ""; + this.userName_materialTextBox.SelectionLength = 0; + this.userName_materialTextBox.SelectionStart = 0; + this.userName_materialTextBox.ShortcutsEnabled = true; + this.userName_materialTextBox.Size = new System.Drawing.Size(342, 48); + this.userName_materialTextBox.TabIndex = 0; + this.userName_materialTextBox.TabStop = false; + this.userName_materialTextBox.Text = "User Name"; + this.userName_materialTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Left; + this.userName_materialTextBox.TrailingIcon = null; + this.userName_materialTextBox.UseSystemPasswordChar = false; + this.userName_materialTextBox.Click += new System.EventHandler(this.userName_materialTextBox_Click); + // + // password_materialTextBox + // + this.password_materialTextBox.AnimateReadOnly = false; + this.password_materialTextBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.password_materialTextBox.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal; + this.password_materialTextBox.Depth = 0; + this.password_materialTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.password_materialTextBox.HideSelection = true; + this.password_materialTextBox.LeadingIcon = null; + this.password_materialTextBox.Location = new System.Drawing.Point(59, 158); + this.password_materialTextBox.MaxLength = 32767; + this.password_materialTextBox.MouseState = MaterialSkin.MouseState.OUT; + this.password_materialTextBox.Name = "password_materialTextBox"; + this.password_materialTextBox.PasswordChar = '*'; + this.password_materialTextBox.PrefixSuffixText = null; + this.password_materialTextBox.ReadOnly = false; + this.password_materialTextBox.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.password_materialTextBox.SelectedText = ""; + this.password_materialTextBox.SelectionLength = 0; + this.password_materialTextBox.SelectionStart = 0; + this.password_materialTextBox.ShortcutsEnabled = true; + this.password_materialTextBox.Size = new System.Drawing.Size(342, 48); + this.password_materialTextBox.TabIndex = 1; + this.password_materialTextBox.TabStop = false; + this.password_materialTextBox.Text = "Password"; + this.password_materialTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Left; + this.password_materialTextBox.TrailingIcon = null; + this.password_materialTextBox.UseSystemPasswordChar = false; + this.password_materialTextBox.Click += new System.EventHandler(this.password_materialTextBox_Click); + // + // Login_materialButton + // + this.Login_materialButton.AutoSize = false; + this.Login_materialButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.Login_materialButton.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.Login_materialButton.Depth = 0; + this.Login_materialButton.HighEmphasis = true; + this.Login_materialButton.Icon = null; + this.Login_materialButton.Location = new System.Drawing.Point(59, 256); + this.Login_materialButton.Margin = new System.Windows.Forms.Padding(4, 6, 4, 6); + this.Login_materialButton.MouseState = MaterialSkin.MouseState.HOVER; + this.Login_materialButton.Name = "Login_materialButton"; + this.Login_materialButton.NoAccentTextColor = System.Drawing.Color.Empty; + this.Login_materialButton.Size = new System.Drawing.Size(147, 36); + this.Login_materialButton.TabIndex = 2; + this.Login_materialButton.Text = "Login"; + this.Login_materialButton.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.Login_materialButton.UseAccentColor = false; + this.Login_materialButton.UseVisualStyleBackColor = true; + this.Login_materialButton.Click += new System.EventHandler(this.Login_materialButton_Click); + // + // SIGNIN_materialButton + // + this.SIGNIN_materialButton.AutoSize = false; + this.SIGNIN_materialButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.SIGNIN_materialButton.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.SIGNIN_materialButton.Depth = 0; + this.SIGNIN_materialButton.HighEmphasis = true; + this.SIGNIN_materialButton.Icon = null; + this.SIGNIN_materialButton.Location = new System.Drawing.Point(254, 256); + this.SIGNIN_materialButton.Margin = new System.Windows.Forms.Padding(4, 6, 4, 6); + this.SIGNIN_materialButton.MouseState = MaterialSkin.MouseState.HOVER; + this.SIGNIN_materialButton.Name = "SIGNIN_materialButton"; + this.SIGNIN_materialButton.NoAccentTextColor = System.Drawing.Color.Empty; + this.SIGNIN_materialButton.Size = new System.Drawing.Size(147, 36); + this.SIGNIN_materialButton.TabIndex = 3; + this.SIGNIN_materialButton.Text = "Sign In"; + this.SIGNIN_materialButton.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.SIGNIN_materialButton.UseAccentColor = false; + this.SIGNIN_materialButton.UseVisualStyleBackColor = true; + this.SIGNIN_materialButton.Click += new System.EventHandler(this.SIGNIN_materialButton_Click); + // + // rememberme_materialCheckbox + // + this.rememberme_materialCheckbox.AutoSize = true; + this.rememberme_materialCheckbox.Depth = 0; + this.rememberme_materialCheckbox.Location = new System.Drawing.Point(59, 213); + this.rememberme_materialCheckbox.Margin = new System.Windows.Forms.Padding(0); + this.rememberme_materialCheckbox.MouseLocation = new System.Drawing.Point(-1, -1); + this.rememberme_materialCheckbox.MouseState = MaterialSkin.MouseState.HOVER; + this.rememberme_materialCheckbox.Name = "rememberme_materialCheckbox"; + this.rememberme_materialCheckbox.ReadOnly = false; + this.rememberme_materialCheckbox.Ripple = true; + this.rememberme_materialCheckbox.Size = new System.Drawing.Size(137, 37); + this.rememberme_materialCheckbox.TabIndex = 4; + this.rememberme_materialCheckbox.Text = "Remember Me"; + this.rememberme_materialCheckbox.UseVisualStyleBackColor = true; + // + // LoginForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(462, 318); + this.Controls.Add(this.rememberme_materialCheckbox); + this.Controls.Add(this.SIGNIN_materialButton); + this.Controls.Add(this.Login_materialButton); + this.Controls.Add(this.password_materialTextBox); + this.Controls.Add(this.userName_materialTextBox); + this.Name = "LoginForm"; + this.Text = "Login"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private MaterialSkin.Controls.MaterialTextBox2 userName_materialTextBox; + private MaterialSkin.Controls.MaterialTextBox2 password_materialTextBox; + private MaterialSkin.Controls.MaterialButton Login_materialButton; + private MaterialSkin.Controls.MaterialButton SIGNIN_materialButton; + private MaterialSkin.Controls.MaterialCheckbox rememberme_materialCheckbox; + } +} \ No newline at end of file diff --git a/src/PBAnaly/LoginForm.cs b/src/PBAnaly/LoginForm.cs new file mode 100644 index 0000000..fb2b6bc --- /dev/null +++ b/src/PBAnaly/LoginForm.cs @@ -0,0 +1,349 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using MaterialSkin; +using MaterialSkin.Controls; +using Microsoft.VisualBasic.FileIO; + +namespace PBAnaly +{ + public partial class LoginForm : MaterialForm + { + private MaterialSkinManager materialSkinManager; + private SignInForm signInForm; + private MainForm mainForm; + + public LoginForm() + { + InitializeComponent(); + this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true); + materialSkinManager = MaterialSkinManager.Instance; // 初始化 MaterialSkinManager 实例 + materialSkinManager.AddFormToManage(this); // 将要应用 Material Design 的窗体添加到管理列表中 + materialSkinManager.Theme = MaterialSkinManager.Themes.DARK; // Theme 属性用来设置整体的主题 + materialSkinManager.ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.Indigo700, TextShade.WHITE); // ColorScheme 属性来设置配色方案 + + signInForm = null; + mainForm = null; + + string LoginFile = Global.mDataUser + "UserLogin.csv"; + + if (File.Exists(LoginFile)) + ReadCsv_Per(LoginFile); + + this.FormClosing += LoginForm_FormClosing; + } + + private void userName_materialTextBox_Click(object sender, EventArgs e) + { + userName_materialTextBox.Text = ""; + } + + private void password_materialTextBox_Click(object sender, EventArgs e) + { + password_materialTextBox.Text = ""; + password_materialTextBox.PasswordChar = '*'; + password_materialTextBox.UseSystemPasswordChar = true; + } + + private void SIGNIN_materialButton_Click(object sender, EventArgs e) + { + if (signInForm == null) + { + signInForm = new SignInForm(this); + signInForm.FormClosing += SignInForm_FormClosing; + signInForm.TopMost = true; + signInForm?.Show(); + + this.Visible = false; + //this.Close(); + } + } + + private void SignInForm_FormClosing(object sender, FormClosingEventArgs e) + { + signInForm?.Dispose(); + signInForm = null; + } + + private void LoginForm_FormClosing(object sender, FormClosingEventArgs e) + { + this?.Dispose(); + this.Close(); + } + + private void Login_materialButton_Click(object sender, EventArgs e) + { + bool LoginSuccess = true; + + string userName_str = userName_materialTextBox.Text; + string password_str = password_materialTextBox.Text; + + List loginUser = new List(); + + if (string.IsNullOrEmpty(userName_str) || string.IsNullOrEmpty(password_str)) + { + MessageBox.Show("User ID or Password is empty ,Please Check!!", "Login Error"); + LoginSuccess = false; + } + + if (!LoginSuccess) + { + return; + } + else + { + if (userName_str.Equals("admin") && password_str.Equals("000000")) + { + Autholity autholity = Autholity.admin; + if (mainForm == null) + { + mainForm = new MainForm(this, autholity, "admin"); + mainForm.TopMost = true; + mainForm?.Show(); + this.Close(); + } + } + else + { + string FileName = Global.mDataUser + "UserInfo.csv"; + + if (!File.Exists(FileName)) + { + MessageBox.Show("No signin User Data, please sign in first!!", "Login Error"); + LoginSuccess = false; + } + else + { + var GetCurrentUserInfo = ReadCsv(FileName); + + bool Find_Str = false; + bool Find_Password = false; + + string Find_UserID = ""; + Autholity Find_autholity = Autholity.Normal; + + foreach (var item in GetCurrentUserInfo) + { + if (item.UserID.Equals(userName_str)) + { + Find_Str = true; + + if (item.Password.Equals(password_str)) + { + Find_Password = true; + Find_UserID = item.UserID; + Find_autholity = item.autholity; + + loginUser.Add(item); + } + } + + } + + if (!Find_Str && !Find_Password) + { + MessageBox.Show("This User ID hasn't been registered, please sign in first!!", "Login Error"); + LoginSuccess = false; + } + else if (Find_Str && !Find_Password) + { + MessageBox.Show("Wrong ID or Password, please check!!", "Login Error"); + LoginSuccess = false; + } + else if (!Find_Str && Find_Password) + { + MessageBox.Show("Wrong ID or Password, please check!!", "Login Error"); + LoginSuccess = false; + } + else + { + LoginSuccess = true; + } + + if (!LoginSuccess) + { + return; + } + else + { + //Login Success + + //Save Login Information + string LoginFile = Global.mDataUser + "UserLogin.csv"; + if (!File.Exists(FileName)) + { + if (!Directory.Exists(Global.mDataUser)) + { + Directory.CreateDirectory(Global.mDataUser); + } + } + WriteCsv(LoginFile, loginUser, rememberme_materialCheckbox.Checked); + + + // Save Log Information + Read_Write_Log read_Write_Log = new Read_Write_Log(); + string SaveLogFile = read_Write_Log.LogFile; + + + List OldLog = new List(); + if (File.Exists(SaveLogFile)) + { + OldLog = read_Write_Log.ReadCsv(SaveLogFile); + } + + string dateTime = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); + OldLog.Add(new Log() { UserID = Find_UserID, ITEM = "登入", Description = "登入系统", Time = dateTime }); + + read_Write_Log.WriteCsv(SaveLogFile, OldLog); + + if (mainForm == null) + { + mainForm = new MainForm(this, Find_autholity, Find_UserID); + mainForm.TopMost = false; + mainForm?.Show(); + } + } + } + } + } + } + + private List ReadCsv_Per(string FilePath) + { + List returnInfo = new List(); + + using (TextFieldParser parser = new TextFieldParser(FilePath)) + { + parser.TextFieldType = FieldType.Delimited; + parser.SetDelimiters(","); + // Read and parse each line of the CSV file + try + { + while (!parser.EndOfData) + { + string[] fields = parser.ReadFields(); + int count = 0; + Autholity autholity = Autholity.admin; + string UserId = ""; + string Email = ""; + string PassWord = ""; + foreach (var item in fields) + { + if ((count % 5) == 0) + { + Enum.TryParse(item, out autholity); + } + else if ((count % 5) == 1) + { + UserId = item; + } + else if ((count % 5) == 2) + { + Email = item; + } + else if ((count % 5) == 3) + { + PassWord = item; + returnInfo.Add(new UserInfo() { autholity = autholity, UserID = UserId, E_Mail = Email, Password = PassWord }); + } + else + { + bool.TryParse(item, out bool result); + + if (result) + { + userName_materialTextBox.Text = UserId; + password_materialTextBox.Text = PassWord; + + rememberme_materialCheckbox.Checked = true; + } + } + + count++; + } + } + parser.Close(); + return returnInfo; + } + catch + { + return null; + } + + } + } + + private List ReadCsv(string FilePath) + { + List returnInfo = new List(); + + using (TextFieldParser parser = new TextFieldParser(FilePath)) + { + parser.TextFieldType = FieldType.Delimited; + parser.SetDelimiters(","); + // Read and parse each line of the CSV file + try + { + while (!parser.EndOfData) + { + string[] fields = parser.ReadFields(); + int count = 0; + Autholity autholity = Autholity.admin; + string UserId = ""; + string Email = ""; + string PassWord = ""; + foreach (var item in fields) + { + if ((count % 4) == 0) + { + Enum.TryParse(item, out autholity); + } + else if ((count % 4) == 1) + { + UserId = item; + } + else if ((count % 4) == 2) + { + Email = item; + } + else + { + PassWord = item; + returnInfo.Add(new UserInfo() { autholity = autholity, UserID = UserId, E_Mail = Email, Password = PassWord }); + } + + count++; + } + } + parser.Close(); + return returnInfo; + } + catch + { + return null; + } + } + } + + private void WriteCsv(string FilePath, List userInfos, bool RememberOrNot) + { + using (var file = new StreamWriter(FilePath)) + { + foreach (var item in userInfos) + { + file.WriteLineAsync($"{item.autholity},{item.UserID},{item.E_Mail},{item.Password},{RememberOrNot}"); + } + + file.Close(); + } + } + + } +} diff --git a/src/PBAnaly/LoginForm.resx b/src/PBAnaly/LoginForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/src/PBAnaly/LoginForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/PBAnaly/MainForm.Designer.cs b/src/PBAnaly/MainForm.Designer.cs new file mode 100644 index 0000000..15c4993 --- /dev/null +++ b/src/PBAnaly/MainForm.Designer.cs @@ -0,0 +1,714 @@ +namespace PBAnaly +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + this.metroPanel_RightTop = new MetroFramework.Controls.MetroPanel(); + this.materialButton_log = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_setting = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_curveimage = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_analyzedata = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_outimage = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_LoadData = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_forward = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_return = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_save = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_inverse = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_resetImage = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_imageInfo = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_fakeColor = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_imageChange = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_changeFormSize = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_miniAnalyze = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_roiAnalyze = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_dotcounts = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_acidAnalyze = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_correction = new MaterialSkin.Controls.MaterialButton(); + this.materialButton_imageProcess = new MaterialSkin.Controls.MaterialButton(); + this.CompanyIcon_pictureBox = new System.Windows.Forms.PictureBox(); + this.btnStartUpToolTip = new System.Windows.Forms.ToolTip(this.components); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.tl_right_main_view = new System.Windows.Forms.TableLayoutPanel(); + this.DataProcess_panel = new ReaLTaiizor.Controls.Panel(); + this.flowLayoutPanel1 = new AntdUI.In.FlowLayoutPanel(); + this.flowLayoutPanel2 = new AntdUI.In.FlowLayoutPanel(); + this.pl_right = new ReaLTaiizor.Controls.Panel(); + this.metroPanel_RightTop.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.CompanyIcon_pictureBox)).BeginInit(); + this.tableLayoutPanel1.SuspendLayout(); + this.tl_right_main_view.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); + this.flowLayoutPanel2.SuspendLayout(); + this.SuspendLayout(); + // + // metroPanel_RightTop + // + this.metroPanel_RightTop.BackColor = System.Drawing.SystemColors.ButtonShadow; + this.metroPanel_RightTop.Controls.Add(this.materialButton_log); + this.metroPanel_RightTop.Controls.Add(this.materialButton_setting); + this.metroPanel_RightTop.Controls.Add(this.materialButton_curveimage); + this.metroPanel_RightTop.Controls.Add(this.materialButton_analyzedata); + this.metroPanel_RightTop.Controls.Add(this.materialButton_outimage); + this.metroPanel_RightTop.Controls.Add(this.materialButton_LoadData); + this.metroPanel_RightTop.Dock = System.Windows.Forms.DockStyle.Fill; + this.metroPanel_RightTop.HorizontalScrollbarBarColor = true; + this.metroPanel_RightTop.HorizontalScrollbarHighlightOnWheel = false; + this.metroPanel_RightTop.HorizontalScrollbarSize = 7; + this.metroPanel_RightTop.Location = new System.Drawing.Point(210, 0); + this.metroPanel_RightTop.Margin = new System.Windows.Forms.Padding(0); + this.metroPanel_RightTop.Name = "metroPanel_RightTop"; + this.metroPanel_RightTop.Size = new System.Drawing.Size(559, 55); + this.metroPanel_RightTop.TabIndex = 12; + this.metroPanel_RightTop.Theme = MetroFramework.MetroThemeStyle.Dark; + this.metroPanel_RightTop.UseCustomBackColor = true; + this.metroPanel_RightTop.VerticalScrollbarBarColor = true; + this.metroPanel_RightTop.VerticalScrollbarHighlightOnWheel = false; + this.metroPanel_RightTop.VerticalScrollbarSize = 7; + // + // materialButton_log + // + this.materialButton_log.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_log.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_log.Depth = 0; + this.materialButton_log.Dock = System.Windows.Forms.DockStyle.Left; + this.materialButton_log.HighEmphasis = true; + this.materialButton_log.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_log.Icon"))); + this.materialButton_log.Location = new System.Drawing.Point(581, 0); + this.materialButton_log.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.materialButton_log.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_log.Name = "materialButton_log"; + this.materialButton_log.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_log.Size = new System.Drawing.Size(113, 55); + this.materialButton_log.TabIndex = 19; + this.materialButton_log.Text = "操作日志"; + this.materialButton_log.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_log.UseAccentColor = false; + this.materialButton_log.UseVisualStyleBackColor = true; + this.materialButton_log.Click += new System.EventHandler(this.materialButton_log_Click); + // + // materialButton_setting + // + this.materialButton_setting.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_setting.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_setting.Depth = 0; + this.materialButton_setting.Dock = System.Windows.Forms.DockStyle.Left; + this.materialButton_setting.HighEmphasis = true; + this.materialButton_setting.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_setting.Icon"))); + this.materialButton_setting.Location = new System.Drawing.Point(468, 0); + this.materialButton_setting.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.materialButton_setting.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_setting.Name = "materialButton_setting"; + this.materialButton_setting.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_setting.Size = new System.Drawing.Size(113, 55); + this.materialButton_setting.TabIndex = 18; + this.materialButton_setting.Text = "系统设置"; + this.materialButton_setting.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_setting.UseAccentColor = false; + this.materialButton_setting.UseVisualStyleBackColor = true; + this.materialButton_setting.Click += new System.EventHandler(this.materialButton_setting_Click); + // + // materialButton_curveimage + // + this.materialButton_curveimage.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_curveimage.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_curveimage.Depth = 0; + this.materialButton_curveimage.Dock = System.Windows.Forms.DockStyle.Left; + this.materialButton_curveimage.Enabled = false; + this.materialButton_curveimage.HighEmphasis = true; + this.materialButton_curveimage.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_curveimage.Icon"))); + this.materialButton_curveimage.Location = new System.Drawing.Point(339, 0); + this.materialButton_curveimage.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.materialButton_curveimage.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_curveimage.Name = "materialButton_curveimage"; + this.materialButton_curveimage.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_curveimage.Size = new System.Drawing.Size(129, 55); + this.materialButton_curveimage.TabIndex = 17; + this.materialButton_curveimage.Text = "泳道波形图"; + this.materialButton_curveimage.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_curveimage.UseAccentColor = false; + this.materialButton_curveimage.UseVisualStyleBackColor = true; + this.materialButton_curveimage.Click += new System.EventHandler(this.materialButton_curveimage_Click); + // + // materialButton_analyzedata + // + this.materialButton_analyzedata.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_analyzedata.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_analyzedata.Depth = 0; + this.materialButton_analyzedata.Dock = System.Windows.Forms.DockStyle.Left; + this.materialButton_analyzedata.Enabled = false; + this.materialButton_analyzedata.HighEmphasis = true; + this.materialButton_analyzedata.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_analyzedata.Icon"))); + this.materialButton_analyzedata.Location = new System.Drawing.Point(226, 0); + this.materialButton_analyzedata.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.materialButton_analyzedata.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_analyzedata.Name = "materialButton_analyzedata"; + this.materialButton_analyzedata.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_analyzedata.Size = new System.Drawing.Size(113, 55); + this.materialButton_analyzedata.TabIndex = 16; + this.materialButton_analyzedata.Text = "分析数据"; + this.materialButton_analyzedata.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_analyzedata.UseAccentColor = false; + this.materialButton_analyzedata.UseVisualStyleBackColor = true; + this.materialButton_analyzedata.Click += new System.EventHandler(this.materialButton_analyzedata_Click); + // + // materialButton_outimage + // + this.materialButton_outimage.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_outimage.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_outimage.Depth = 0; + this.materialButton_outimage.Dock = System.Windows.Forms.DockStyle.Left; + this.materialButton_outimage.Enabled = false; + this.materialButton_outimage.HighEmphasis = true; + this.materialButton_outimage.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_outimage.Icon"))); + this.materialButton_outimage.Location = new System.Drawing.Point(113, 0); + this.materialButton_outimage.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.materialButton_outimage.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_outimage.Name = "materialButton_outimage"; + this.materialButton_outimage.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_outimage.Size = new System.Drawing.Size(113, 55); + this.materialButton_outimage.TabIndex = 15; + this.materialButton_outimage.Text = "导出图像"; + this.materialButton_outimage.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_outimage.UseAccentColor = false; + this.materialButton_outimage.UseVisualStyleBackColor = true; + this.materialButton_outimage.Click += new System.EventHandler(this.materialButton_outimage_Click); + // + // materialButton_LoadData + // + this.materialButton_LoadData.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_LoadData.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_LoadData.Depth = 0; + this.materialButton_LoadData.Dock = System.Windows.Forms.DockStyle.Left; + this.materialButton_LoadData.Enabled = false; + this.materialButton_LoadData.HighEmphasis = true; + this.materialButton_LoadData.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_LoadData.Icon"))); + this.materialButton_LoadData.Location = new System.Drawing.Point(0, 0); + this.materialButton_LoadData.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.materialButton_LoadData.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_LoadData.Name = "materialButton_LoadData"; + this.materialButton_LoadData.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_LoadData.Size = new System.Drawing.Size(113, 55); + this.materialButton_LoadData.TabIndex = 14; + this.materialButton_LoadData.Text = "加载数据"; + this.materialButton_LoadData.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_LoadData.UseAccentColor = false; + this.materialButton_LoadData.UseVisualStyleBackColor = true; + this.materialButton_LoadData.Click += new System.EventHandler(this.materialButton_LoadData_Click); + // + // materialButton_forward + // + this.materialButton_forward.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_forward.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_forward.Depth = 0; + this.materialButton_forward.HighEmphasis = true; + this.materialButton_forward.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_forward.Icon"))); + this.materialButton_forward.Location = new System.Drawing.Point(448, 0); + this.materialButton_forward.Margin = new System.Windows.Forms.Padding(0); + this.materialButton_forward.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_forward.Name = "materialButton_forward"; + this.materialButton_forward.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_forward.Size = new System.Drawing.Size(64, 36); + this.materialButton_forward.TabIndex = 23; + this.materialButton_forward.Text = " "; + this.materialButton_forward.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Text; + this.materialButton_forward.UseAccentColor = false; + this.materialButton_forward.UseVisualStyleBackColor = true; + this.materialButton_forward.MouseMove += new System.Windows.Forms.MouseEventHandler(this.materialButton_forward_MouseMove); + // + // materialButton_return + // + this.materialButton_return.Anchor = System.Windows.Forms.AnchorStyles.None; + this.materialButton_return.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_return.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_return.Depth = 0; + this.materialButton_return.HighEmphasis = true; + this.materialButton_return.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_return.Icon"))); + this.materialButton_return.Location = new System.Drawing.Point(0, 36); + this.materialButton_return.Margin = new System.Windows.Forms.Padding(0); + this.materialButton_return.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_return.Name = "materialButton_return"; + this.materialButton_return.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_return.Size = new System.Drawing.Size(64, 36); + this.materialButton_return.TabIndex = 22; + this.materialButton_return.Text = " "; + this.materialButton_return.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Text; + this.materialButton_return.UseAccentColor = false; + this.materialButton_return.UseVisualStyleBackColor = true; + this.materialButton_return.MouseMove += new System.Windows.Forms.MouseEventHandler(this.materialButton_return_MouseMove); + // + // materialButton_save + // + this.materialButton_save.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_save.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_save.Depth = 0; + this.materialButton_save.HighEmphasis = true; + this.materialButton_save.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_save.Icon"))); + this.materialButton_save.Location = new System.Drawing.Point(384, 0); + this.materialButton_save.Margin = new System.Windows.Forms.Padding(0); + this.materialButton_save.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_save.Name = "materialButton_save"; + this.materialButton_save.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_save.Size = new System.Drawing.Size(64, 36); + this.materialButton_save.TabIndex = 21; + this.materialButton_save.Text = " "; + this.materialButton_save.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Text; + this.materialButton_save.UseAccentColor = false; + this.materialButton_save.UseVisualStyleBackColor = true; + this.materialButton_save.MouseMove += new System.Windows.Forms.MouseEventHandler(this.materialButton_save_MouseMove); + // + // materialButton_inverse + // + this.materialButton_inverse.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_inverse.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_inverse.Depth = 0; + this.materialButton_inverse.HighEmphasis = true; + this.materialButton_inverse.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_inverse.Icon"))); + this.materialButton_inverse.Location = new System.Drawing.Point(320, 0); + this.materialButton_inverse.Margin = new System.Windows.Forms.Padding(0); + this.materialButton_inverse.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_inverse.Name = "materialButton_inverse"; + this.materialButton_inverse.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_inverse.Size = new System.Drawing.Size(64, 36); + this.materialButton_inverse.TabIndex = 20; + this.materialButton_inverse.Text = " "; + this.materialButton_inverse.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Text; + this.materialButton_inverse.UseAccentColor = false; + this.materialButton_inverse.UseVisualStyleBackColor = true; + this.materialButton_inverse.MouseMove += new System.Windows.Forms.MouseEventHandler(this.materialButton_inverse_MouseMove); + // + // materialButton_resetImage + // + this.materialButton_resetImage.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_resetImage.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_resetImage.Depth = 0; + this.materialButton_resetImage.HighEmphasis = true; + this.materialButton_resetImage.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_resetImage.Icon"))); + this.materialButton_resetImage.Location = new System.Drawing.Point(256, 0); + this.materialButton_resetImage.Margin = new System.Windows.Forms.Padding(0); + this.materialButton_resetImage.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_resetImage.Name = "materialButton_resetImage"; + this.materialButton_resetImage.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_resetImage.Size = new System.Drawing.Size(64, 36); + this.materialButton_resetImage.TabIndex = 19; + this.materialButton_resetImage.Text = " "; + this.materialButton_resetImage.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Text; + this.materialButton_resetImage.UseAccentColor = false; + this.materialButton_resetImage.UseVisualStyleBackColor = true; + this.materialButton_resetImage.MouseMove += new System.Windows.Forms.MouseEventHandler(this.materialButton_resetImage_MouseMove); + // + // materialButton_imageInfo + // + this.materialButton_imageInfo.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_imageInfo.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_imageInfo.Depth = 0; + this.materialButton_imageInfo.HighEmphasis = true; + this.materialButton_imageInfo.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_imageInfo.Icon"))); + this.materialButton_imageInfo.Location = new System.Drawing.Point(192, 0); + this.materialButton_imageInfo.Margin = new System.Windows.Forms.Padding(0); + this.materialButton_imageInfo.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_imageInfo.Name = "materialButton_imageInfo"; + this.materialButton_imageInfo.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_imageInfo.Size = new System.Drawing.Size(64, 36); + this.materialButton_imageInfo.TabIndex = 18; + this.materialButton_imageInfo.Text = " "; + this.materialButton_imageInfo.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Text; + this.materialButton_imageInfo.UseAccentColor = false; + this.materialButton_imageInfo.UseVisualStyleBackColor = true; + this.materialButton_imageInfo.Click += new System.EventHandler(this.materialButton_imageInfo_Click); + this.materialButton_imageInfo.MouseMove += new System.Windows.Forms.MouseEventHandler(this.materialButton_imageInfo_MouseMove); + // + // materialButton_fakeColor + // + this.materialButton_fakeColor.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_fakeColor.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_fakeColor.Depth = 0; + this.materialButton_fakeColor.HighEmphasis = true; + this.materialButton_fakeColor.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_fakeColor.Icon"))); + this.materialButton_fakeColor.Location = new System.Drawing.Point(128, 0); + this.materialButton_fakeColor.Margin = new System.Windows.Forms.Padding(0); + this.materialButton_fakeColor.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_fakeColor.Name = "materialButton_fakeColor"; + this.materialButton_fakeColor.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_fakeColor.Size = new System.Drawing.Size(64, 36); + this.materialButton_fakeColor.TabIndex = 17; + this.materialButton_fakeColor.Text = " "; + this.materialButton_fakeColor.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Text; + this.materialButton_fakeColor.UseAccentColor = false; + this.materialButton_fakeColor.UseVisualStyleBackColor = true; + this.materialButton_fakeColor.MouseMove += new System.Windows.Forms.MouseEventHandler(this.materialButton_fakeColor_MouseMove); + // + // materialButton_imageChange + // + this.materialButton_imageChange.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_imageChange.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_imageChange.Depth = 0; + this.materialButton_imageChange.HighEmphasis = true; + this.materialButton_imageChange.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_imageChange.Icon"))); + this.materialButton_imageChange.Location = new System.Drawing.Point(64, 0); + this.materialButton_imageChange.Margin = new System.Windows.Forms.Padding(0); + this.materialButton_imageChange.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_imageChange.Name = "materialButton_imageChange"; + this.materialButton_imageChange.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_imageChange.Size = new System.Drawing.Size(64, 36); + this.materialButton_imageChange.TabIndex = 16; + this.materialButton_imageChange.Text = " "; + this.materialButton_imageChange.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Text; + this.materialButton_imageChange.UseAccentColor = false; + this.materialButton_imageChange.UseVisualStyleBackColor = true; + this.materialButton_imageChange.MouseMove += new System.Windows.Forms.MouseEventHandler(this.materialButton_imageChange_MouseMove); + // + // materialButton_changeFormSize + // + this.materialButton_changeFormSize.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_changeFormSize.BackColor = System.Drawing.SystemColors.ButtonShadow; + this.materialButton_changeFormSize.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_changeFormSize.Depth = 0; + this.materialButton_changeFormSize.HighEmphasis = true; + this.materialButton_changeFormSize.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_changeFormSize.Icon"))); + this.materialButton_changeFormSize.Location = new System.Drawing.Point(0, 0); + this.materialButton_changeFormSize.Margin = new System.Windows.Forms.Padding(0); + this.materialButton_changeFormSize.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_changeFormSize.Name = "materialButton_changeFormSize"; + this.materialButton_changeFormSize.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_changeFormSize.Size = new System.Drawing.Size(64, 36); + this.materialButton_changeFormSize.TabIndex = 15; + this.materialButton_changeFormSize.Tag = "123"; + this.materialButton_changeFormSize.Text = " "; + this.materialButton_changeFormSize.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Text; + this.materialButton_changeFormSize.UseAccentColor = false; + this.materialButton_changeFormSize.UseVisualStyleBackColor = false; + this.materialButton_changeFormSize.Click += new System.EventHandler(this.materialButton_changeFormSize_Click); + this.materialButton_changeFormSize.MouseMove += new System.Windows.Forms.MouseEventHandler(this.materialButton_changeFormSize_MouseMove); + // + // materialButton_miniAnalyze + // + this.materialButton_miniAnalyze.AutoSize = false; + this.materialButton_miniAnalyze.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_miniAnalyze.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_miniAnalyze.Depth = 0; + this.materialButton_miniAnalyze.HighEmphasis = true; + this.materialButton_miniAnalyze.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_miniAnalyze.Icon"))); + this.materialButton_miniAnalyze.Location = new System.Drawing.Point(4, 186); + this.materialButton_miniAnalyze.Margin = new System.Windows.Forms.Padding(4, 6, 4, 6); + this.materialButton_miniAnalyze.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_miniAnalyze.Name = "materialButton_miniAnalyze"; + this.materialButton_miniAnalyze.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_miniAnalyze.Size = new System.Drawing.Size(200, 48); + this.materialButton_miniAnalyze.TabIndex = 7; + this.materialButton_miniAnalyze.Text = "微孔版分析"; + this.materialButton_miniAnalyze.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_miniAnalyze.UseAccentColor = false; + this.materialButton_miniAnalyze.UseVisualStyleBackColor = true; + // + // materialButton_roiAnalyze + // + this.materialButton_roiAnalyze.AutoSize = false; + this.materialButton_roiAnalyze.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_roiAnalyze.CharacterCasing = MaterialSkin.Controls.MaterialButton.CharacterCasingEnum.Normal; + this.materialButton_roiAnalyze.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_roiAnalyze.Depth = 0; + this.materialButton_roiAnalyze.HighEmphasis = true; + this.materialButton_roiAnalyze.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_roiAnalyze.Icon"))); + this.materialButton_roiAnalyze.Location = new System.Drawing.Point(4, 126); + this.materialButton_roiAnalyze.Margin = new System.Windows.Forms.Padding(4, 6, 4, 6); + this.materialButton_roiAnalyze.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_roiAnalyze.Name = "materialButton_roiAnalyze"; + this.materialButton_roiAnalyze.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_roiAnalyze.Size = new System.Drawing.Size(200, 48); + this.materialButton_roiAnalyze.TabIndex = 6; + this.materialButton_roiAnalyze.Text = "ROIs分析"; + this.materialButton_roiAnalyze.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_roiAnalyze.UseAccentColor = false; + this.materialButton_roiAnalyze.UseVisualStyleBackColor = true; + // + // materialButton_dotcounts + // + this.materialButton_dotcounts.AutoSize = false; + this.materialButton_dotcounts.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_dotcounts.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_dotcounts.Depth = 0; + this.materialButton_dotcounts.HighEmphasis = true; + this.materialButton_dotcounts.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_dotcounts.Icon"))); + this.materialButton_dotcounts.Location = new System.Drawing.Point(4, 246); + this.materialButton_dotcounts.Margin = new System.Windows.Forms.Padding(4, 6, 4, 6); + this.materialButton_dotcounts.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_dotcounts.Name = "materialButton_dotcounts"; + this.materialButton_dotcounts.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_dotcounts.Size = new System.Drawing.Size(200, 48); + this.materialButton_dotcounts.TabIndex = 8; + this.materialButton_dotcounts.Text = "菌落计数"; + this.materialButton_dotcounts.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_dotcounts.UseAccentColor = false; + this.materialButton_dotcounts.UseVisualStyleBackColor = true; + // + // materialButton_acidAnalyze + // + this.materialButton_acidAnalyze.AutoSize = false; + this.materialButton_acidAnalyze.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_acidAnalyze.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_acidAnalyze.Depth = 0; + this.materialButton_acidAnalyze.HighEmphasis = true; + this.materialButton_acidAnalyze.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_acidAnalyze.Icon"))); + this.materialButton_acidAnalyze.Location = new System.Drawing.Point(4, 66); + this.materialButton_acidAnalyze.Margin = new System.Windows.Forms.Padding(4, 6, 4, 6); + this.materialButton_acidAnalyze.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_acidAnalyze.Name = "materialButton_acidAnalyze"; + this.materialButton_acidAnalyze.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_acidAnalyze.Size = new System.Drawing.Size(200, 48); + this.materialButton_acidAnalyze.TabIndex = 5; + this.materialButton_acidAnalyze.Text = "泳道分析"; + this.materialButton_acidAnalyze.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_acidAnalyze.UseAccentColor = false; + this.materialButton_acidAnalyze.UseVisualStyleBackColor = true; + // + // materialButton_correction + // + this.materialButton_correction.AutoSize = false; + this.materialButton_correction.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_correction.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_correction.Depth = 0; + this.materialButton_correction.HighEmphasis = true; + this.materialButton_correction.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_correction.Icon"))); + this.materialButton_correction.Location = new System.Drawing.Point(4, 306); + this.materialButton_correction.Margin = new System.Windows.Forms.Padding(4, 6, 4, 6); + this.materialButton_correction.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_correction.Name = "materialButton_correction"; + this.materialButton_correction.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_correction.Size = new System.Drawing.Size(200, 48); + this.materialButton_correction.TabIndex = 9; + this.materialButton_correction.Text = "蛋白归一化"; + this.materialButton_correction.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_correction.UseAccentColor = false; + this.materialButton_correction.UseVisualStyleBackColor = true; + // + // materialButton_imageProcess + // + this.materialButton_imageProcess.AutoSize = false; + this.materialButton_imageProcess.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.materialButton_imageProcess.BackColor = System.Drawing.SystemColors.Control; + this.materialButton_imageProcess.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.materialButton_imageProcess.Depth = 0; + this.materialButton_imageProcess.Font = new System.Drawing.Font("宋体", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.materialButton_imageProcess.HighEmphasis = true; + this.materialButton_imageProcess.Icon = ((System.Drawing.Image)(resources.GetObject("materialButton_imageProcess.Icon"))); + this.materialButton_imageProcess.Location = new System.Drawing.Point(4, 6); + this.materialButton_imageProcess.Margin = new System.Windows.Forms.Padding(4, 6, 4, 6); + this.materialButton_imageProcess.MouseState = MaterialSkin.MouseState.HOVER; + this.materialButton_imageProcess.Name = "materialButton_imageProcess"; + this.materialButton_imageProcess.NoAccentTextColor = System.Drawing.Color.Empty; + this.materialButton_imageProcess.Size = new System.Drawing.Size(200, 48); + this.materialButton_imageProcess.TabIndex = 4; + this.materialButton_imageProcess.Text = "图像处理"; + this.materialButton_imageProcess.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.materialButton_imageProcess.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.materialButton_imageProcess.UseAccentColor = false; + this.materialButton_imageProcess.UseVisualStyleBackColor = false; + this.materialButton_imageProcess.Click += new System.EventHandler(this.materialButton_imageProcess_Click); + // + // CompanyIcon_pictureBox + // + this.CompanyIcon_pictureBox.BackColor = System.Drawing.Color.Transparent; + this.CompanyIcon_pictureBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.CompanyIcon_pictureBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.CompanyIcon_pictureBox.Image = global::PBAnaly.Properties.Resources.京仪科技定稿_画板_1_副本2; + this.CompanyIcon_pictureBox.Location = new System.Drawing.Point(3, 3); + this.CompanyIcon_pictureBox.Name = "CompanyIcon_pictureBox"; + this.tableLayoutPanel1.SetRowSpan(this.CompanyIcon_pictureBox, 2); + this.CompanyIcon_pictureBox.Size = new System.Drawing.Size(204, 80); + this.CompanyIcon_pictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.CompanyIcon_pictureBox.TabIndex = 16; + this.CompanyIcon_pictureBox.TabStop = false; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 3; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 210F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 328F)); + this.tableLayoutPanel1.Controls.Add(this.tl_right_main_view, 1, 2); + this.tableLayoutPanel1.Controls.Add(this.metroPanel_RightTop, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.CompanyIcon_pictureBox, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel2, 1, 1); + this.tableLayoutPanel1.Controls.Add(this.pl_right, 2, 1); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 24); + this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(2); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 3; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 55F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 31F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(1097, 581); + this.tableLayoutPanel1.TabIndex = 18; + // + // tl_right_main_view + // + this.tl_right_main_view.ColumnCount = 2; + this.tl_right_main_view.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tl_right_main_view.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 324F)); + this.tl_right_main_view.Controls.Add(this.DataProcess_panel, 0, 0); + this.tl_right_main_view.Dock = System.Windows.Forms.DockStyle.Fill; + this.tl_right_main_view.Location = new System.Drawing.Point(210, 86); + this.tl_right_main_view.Margin = new System.Windows.Forms.Padding(0); + this.tl_right_main_view.Name = "tl_right_main_view"; + this.tl_right_main_view.RowCount = 2; + this.tl_right_main_view.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tl_right_main_view.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tl_right_main_view.Size = new System.Drawing.Size(559, 495); + this.tl_right_main_view.TabIndex = 0; + // + // DataProcess_panel + // + this.DataProcess_panel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(39)))), ((int)(((byte)(51)))), ((int)(((byte)(63))))); + this.tl_right_main_view.SetColumnSpan(this.DataProcess_panel, 2); + this.DataProcess_panel.Dock = System.Windows.Forms.DockStyle.Fill; + this.DataProcess_panel.EdgeColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(41)))), ((int)(((byte)(50))))); + this.DataProcess_panel.Location = new System.Drawing.Point(3, 3); + this.DataProcess_panel.Name = "DataProcess_panel"; + this.DataProcess_panel.Padding = new System.Windows.Forms.Padding(5); + this.tl_right_main_view.SetRowSpan(this.DataProcess_panel, 2); + this.DataProcess_panel.Size = new System.Drawing.Size(553, 489); + this.DataProcess_panel.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.DataProcess_panel.TabIndex = 19; + this.DataProcess_panel.Text = "panel1"; + // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.Controls.Add(this.materialButton_imageProcess); + this.flowLayoutPanel1.Controls.Add(this.materialButton_acidAnalyze); + this.flowLayoutPanel1.Controls.Add(this.materialButton_roiAnalyze); + this.flowLayoutPanel1.Controls.Add(this.materialButton_miniAnalyze); + this.flowLayoutPanel1.Controls.Add(this.materialButton_dotcounts); + this.flowLayoutPanel1.Controls.Add(this.materialButton_correction); + this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; + this.flowLayoutPanel1.Location = new System.Drawing.Point(2, 88); + this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(2); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(206, 491); + this.flowLayoutPanel1.TabIndex = 18; + // + // flowLayoutPanel2 + // + this.flowLayoutPanel2.BackColor = System.Drawing.SystemColors.ButtonShadow; + this.flowLayoutPanel2.Controls.Add(this.materialButton_changeFormSize); + this.flowLayoutPanel2.Controls.Add(this.materialButton_imageChange); + this.flowLayoutPanel2.Controls.Add(this.materialButton_fakeColor); + this.flowLayoutPanel2.Controls.Add(this.materialButton_imageInfo); + this.flowLayoutPanel2.Controls.Add(this.materialButton_resetImage); + this.flowLayoutPanel2.Controls.Add(this.materialButton_inverse); + this.flowLayoutPanel2.Controls.Add(this.materialButton_save); + this.flowLayoutPanel2.Controls.Add(this.materialButton_forward); + this.flowLayoutPanel2.Controls.Add(this.materialButton_return); + this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutPanel2.Location = new System.Drawing.Point(210, 55); + this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0); + this.flowLayoutPanel2.Name = "flowLayoutPanel2"; + this.flowLayoutPanel2.Size = new System.Drawing.Size(559, 31); + this.flowLayoutPanel2.TabIndex = 19; + // + // pl_right + // + this.pl_right.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(39)))), ((int)(((byte)(51)))), ((int)(((byte)(63))))); + this.pl_right.Dock = System.Windows.Forms.DockStyle.Fill; + this.pl_right.EdgeColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(41)))), ((int)(((byte)(50))))); + this.pl_right.Location = new System.Drawing.Point(771, 57); + this.pl_right.Margin = new System.Windows.Forms.Padding(2); + this.pl_right.Name = "pl_right"; + this.pl_right.Padding = new System.Windows.Forms.Padding(4); + this.tableLayoutPanel1.SetRowSpan(this.pl_right, 2); + this.pl_right.Size = new System.Drawing.Size(324, 522); + this.pl_right.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.pl_right.TabIndex = 20; + this.pl_right.Text = "panel1"; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoSize = true; + this.AutoValidate = System.Windows.Forms.AutoValidate.EnablePreventFocusChange; + this.ClientSize = new System.Drawing.Size(1103, 608); + this.Controls.Add(this.tableLayoutPanel1); + this.DrawerAutoHide = false; + this.FormStyle = MaterialSkin.Controls.MaterialForm.FormStyles.ActionBar_None; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "MainForm"; + this.Padding = new System.Windows.Forms.Padding(3, 24, 3, 3); + this.Text = "MainForm"; + this.WindowState = System.Windows.Forms.FormWindowState.Maximized; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MainForm_FormClosed); + this.SizeChanged += new System.EventHandler(this.MainForm_SizeChanged); + this.metroPanel_RightTop.ResumeLayout(false); + this.metroPanel_RightTop.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.CompanyIcon_pictureBox)).EndInit(); + this.tableLayoutPanel1.ResumeLayout(false); + this.tl_right_main_view.ResumeLayout(false); + this.flowLayoutPanel1.ResumeLayout(false); + this.flowLayoutPanel2.ResumeLayout(false); + this.flowLayoutPanel2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + private MetroFramework.Controls.MetroPanel metroPanel_RightTop; + private MaterialSkin.Controls.MaterialButton materialButton_LoadData; + private MaterialSkin.Controls.MaterialButton materialButton_log; + private MaterialSkin.Controls.MaterialButton materialButton_setting; + private MaterialSkin.Controls.MaterialButton materialButton_curveimage; + private MaterialSkin.Controls.MaterialButton materialButton_analyzedata; + private MaterialSkin.Controls.MaterialButton materialButton_outimage; + private MaterialSkin.Controls.MaterialButton materialButton_changeFormSize; + private MaterialSkin.Controls.MaterialButton materialButton_forward; + private MaterialSkin.Controls.MaterialButton materialButton_return; + private MaterialSkin.Controls.MaterialButton materialButton_save; + private MaterialSkin.Controls.MaterialButton materialButton_inverse; + private MaterialSkin.Controls.MaterialButton materialButton_resetImage; + private MaterialSkin.Controls.MaterialButton materialButton_imageInfo; + private MaterialSkin.Controls.MaterialButton materialButton_fakeColor; + private MaterialSkin.Controls.MaterialButton materialButton_imageChange; + private MaterialSkin.Controls.MaterialButton materialButton_miniAnalyze; + private MaterialSkin.Controls.MaterialButton materialButton_roiAnalyze; + private MaterialSkin.Controls.MaterialButton materialButton_dotcounts; + private MaterialSkin.Controls.MaterialButton materialButton_acidAnalyze; + private MaterialSkin.Controls.MaterialButton materialButton_correction; + private MaterialSkin.Controls.MaterialButton materialButton_imageProcess; + private System.Windows.Forms.PictureBox CompanyIcon_pictureBox; + private System.Windows.Forms.ToolTip btnStartUpToolTip; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private AntdUI.In.FlowLayoutPanel flowLayoutPanel1; + private AntdUI.In.FlowLayoutPanel flowLayoutPanel2; + private ReaLTaiizor.Controls.Panel pl_right; + private System.Windows.Forms.TableLayoutPanel tl_right_main_view; + private ReaLTaiizor.Controls.Panel DataProcess_panel; + } +} \ No newline at end of file diff --git a/src/PBAnaly/MainForm.cs b/src/PBAnaly/MainForm.cs new file mode 100644 index 0000000..c0d4393 --- /dev/null +++ b/src/PBAnaly/MainForm.cs @@ -0,0 +1,843 @@ +using Aspose.Pdf; +using MaterialSkin; +using MaterialSkin.Controls; +using OpenCvSharp.Flann; +using OpenTK; +using PBAnaly.Module; +using PBAnaly.Properties; +using PBAnaly.UI; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Threading; +using System.Windows.Forms; +using Resources = PBAnaly.Properties.Resources; + +namespace PBAnaly +{ + public partial class MainForm : MaterialForm + { + private MaterialSkinManager materialSkinManager; + private SettingForm settingForm; + private LoginForm loginForm; + private LogForm logForm; + + private int FormGenerate_X; + private int FormGenerate_Y; + + private string InnerUserID = ""; + + private string color_bar = "YellowHot"; + System.Windows.Forms.TableLayoutPanel tlp_main_images; + + + bool isRun = false; + private Thread thread; + private void runThread() + { + //while (isRun) + //{ + + // int index = 0; + // foreach (var item in ImageToolMannage.imageDataPath) + // { + // if (index == 0) + // { + // if (pb_image1.InvokeRequired) + // { + // pb_image1.Invoke(new Action(() => pb_image1.Image = item.Value.pictureBox)); + // } + + + // } + // else if (index == 1) + // { + // if (pb_image2.InvokeRequired) + // { + // pb_image2.Invoke(new Action(() => pb_image2.Image = item.Value.pictureBox)); + // } + // } + // else if (index == 2) + // { + // if (pb_image3.InvokeRequired) + // { + // pb_image3.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // } + // else if (index == 3) + // { + // if (pb_image4.InvokeRequired) + // { + // pb_image4.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // } + // else if (index == 4) + // { + // if (pb_image5.InvokeRequired) + // { + // pb_image5.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // } + // else if (index == 5) + // { + // if (pb_image6.InvokeRequired) + // { + // pb_image6.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // } + // else if (index == 6) + // { + // if (pb_image7.InvokeRequired) + // { + // pb_image7.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // } + // else if (index == 7) + // { + // if (pb_image8.InvokeRequired) + // { + // pb_image8.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // } + // else if (index == 8) + // { + // if (pb_image9.InvokeRequired) + // { + // pb_image9.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // } + // } + // Thread.Sleep(200); + //} + } + public MainForm(LoginForm InnerloginForm, Autholity autholity, string UserID) + { + InitializeComponent(); + //InnerloginForm.Close(); + loginForm = InnerloginForm; + loginForm.Visible = false; + //loginForm.Close(); + loginForm = null; + + + UIInit(); + + InnerUserID = UserID; + FormGenerate_X = 0; + FormGenerate_Y = 0; + // initPanel(); + } + + + + + [System.Runtime.InteropServices.DllImport("user32.dll")] + private static extern int SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParm); + private const int WM_SETREDRAW = 11; + private void BeginUpdate(Control control) + { + SendMessage(control.Handle,WM_SETREDRAW,false,0); + } + private void EndUpdate(Control control) + { + SendMessage(control.Handle, WM_SETREDRAW, true, 0); + control.Refresh(); + } + + public void UIInit() + { + this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true); + materialSkinManager = MaterialSkinManager.Instance; // 初始化 MaterialSkinManager 实例 + materialSkinManager.AddFormToManage(this); // 将要应用 Material Design 的窗体添加到管理列表中 + materialSkinManager.Theme = MaterialSkinManager.Themes.DARK; // Theme 属性用来设置整体的主题 + materialSkinManager.ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.Indigo700, TextShade.WHITE); // ColorScheme 属性来设置配色方案 + } + public void SetPic(Bitmap p) + { + + int index = 0; + + //foreach (var item in ImageToolMannage.imageDataPath) + //{ + // if (index == 0) + // { + // var camera = item.Value.GetImage(); + // pb_image1.Image = util.ConvertRgb24ImageToBitmap(camera); + + // pb_image1.Refresh(); + + // } + // else if (index == 1) + // { + // pb_image2.Invoke(new Action(() => pb_image2.Image = item.Value.pictureBox)); + // } + // else if (index == 2) + // { + // pb_image3.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // else if (index == 3) + // { + // pb_image4.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // else if (index == 4) + // { + // pb_image5.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // else if (index == 5) + // { + // if (pb_image6.InvokeRequired) + // { + // pb_image6.Invoke(new Action(() => pb_image6.Image = item.Value.pictureBox)); + // } + // } + // else if (index == 6) + // { + // pb_image7.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // else if (index == 7) + // { + // pb_image8.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // else if (index == 8) + // { + // pb_image9.Invoke(new Action(() => pb_image9.Image = item.Value.pictureBox)); + // } + // index++; + //} + } + private void initPanel() + { + //BeginUpdate(tl_right_main_view); + + //tl_right_main_view.RowCount = 1; + //tl_right_main_view.ColumnCount = 1; + + //tl_right_main_view.Controls.Clear(); + + + + //if (isGridView) + //{ + // pl_right.Controls.Clear(); + // itpf = new COMMImageToolPaletteForm(this); + // itpf.TopLevel = false; + // itpf.Dock = DockStyle.Fill; + // pb_colorbar = new PictureBox(); + // pb_colorbar.SizeMode = PictureBoxSizeMode.StretchImage; + + // tl_right_main_view.RowCount = 1; + // tl_right_main_view.ColumnCount = 2; + // tl_right_main_view.RowStyles.Clear(); + // tl_right_main_view.ColumnStyles.Clear(); + + // tl_right_main_view.ColumnStyles.Add(new ColumnStyle(SizeType.Percent,100f)); + // tl_right_main_view.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 100f)); + // pb_lists.Clear(); + // tlp_main_images = new TableLayoutPanel(); + // tl_right_main_view.Controls.Add(tlp_main_images,0,0); + // tl_right_main_view.Controls.Add(pb_colorbar, 1,0); + // pb_colorbar.Dock = DockStyle.Fill; + // pl_right.Controls.Add(itpf); + // pb_colorbar.Show(); + // pb_colorbar.Dock = DockStyle.Fill; + // itpf.Show(); + // tlp_main_images.Dock = DockStyle.Fill; + + // int capCount = ImageToolMannage.imageDataPath.Count; + // int rows = (int)Math.Ceiling(Math.Sqrt(capCount)); + // int cols = (int)Math.Ceiling((double)capCount / rows); + // if (capCount == 1) + // { + // rows = 1; + // cols = 0; + // } + // else if (capCount == 2) + // { + // rows = 1; + // cols = 2; + // } + // else if ( capCount == 3) + // { + // rows = 1; + // cols = capCount; + // } + // else if (capCount == 4) + // { + // rows = 2; + // cols = 2; + // } + // else if (capCount > 4 && capCount <= 6) + // { + // rows = 2; + // cols = 3; + // } + // else if (capCount > 6 && capCount <= 9) + // { + // rows = 3; + // cols = 3; + // } + + + // tlp_main_images.RowCount = rows; + // tlp_main_images.ColumnCount = cols; + + // tlp_main_images.RowStyles.Clear(); + // tlp_main_images.ColumnStyles.Clear(); + // for (int i = 0; i < rows; i++) + // { + // tlp_main_images.RowStyles.Add(new RowStyle(SizeType.Percent, 100f / rows)); + // } + // for (int i = 0; i < cols; i++) + // { + // tlp_main_images.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f / cols)); + // } + + // int index = 0; + // int r = 0; + // int c = 0; + // foreach (var item in ImageToolMannage.imageDataPath) + // { + // if (index == 0) + // { + // tlp_main_images.Controls.Add(pb_image1, c, r); + // pb_image1.Dock = DockStyle.Fill; + // pb_image1.Show(); + // } + // else if(index == 1) + // { + // tlp_main_images.Controls.Add(pb_image2, c, r); + // pb_image2.Dock = DockStyle.Fill; + // pb_image2.Show(); + // } + // else if (index == 2) + // { + // tlp_main_images.Controls.Add(pb_image3, c, r); + // pb_image3.Dock = DockStyle.Fill; + // pb_image3.Show(); + // } + // else if (index == 3) + // { + // tlp_main_images.Controls.Add(pb_image4, c, r); + // pb_image4.Dock = DockStyle.Fill; + // pb_image4.Show(); + // } + // else if (index == 4) + // { + // tlp_main_images.Controls.Add(pb_image5, c, r); + // pb_image5.Dock = DockStyle.Fill; + // pb_image5.Show(); + // } + // else if (index == 5) + // { + // tlp_main_images.Controls.Add(pb_image6, c, r); + // pb_image6.Dock = DockStyle.Fill; + // pb_image6.Show(); + // } + // else if (index == 6) + // { + // tlp_main_images.Controls.Add(pb_image7, c, r); + // pb_image7.Dock = DockStyle.Fill; + // pb_image7.Show(); + // } + // else if (index == 7) + // { + // tlp_main_images.Controls.Add(pb_image8, c, r); + // pb_image8.Dock = DockStyle.Fill; + // pb_image8.Show(); + // } + // else if (index == 8) + // { + // tlp_main_images.Controls.Add(pb_image9, c, r); + // pb_image9.Dock = DockStyle.Fill; + // pb_image9.Show(); + // } + // c++; + // if (c >= cols) + // { + // r++; + // c = 0; + // } + // index++; + // } + + // isRun = true; + // thread = new Thread(runThread); + // thread.IsBackground = true; + // thread.Start(); + //} + //else + //{ + // isRun = false; + // tl_right_main_view.Controls.Add(DataProcess_panel); + // DataProcess_panel.Dock = DockStyle.Fill; + + // foreach (var frmEmbed in ImageToolMannage.imageDataPath.Values) + // { + // if (frmEmbed != null) + // { + // frmEmbed.TopLevel = false; + // DataProcess_panel.Controls.Add(frmEmbed); + // //FormGenerate_X = FormGenerate_X + 15; + // //FormGenerate_Y = FormGenerate_Y + 15; + // frmEmbed.Location = new System.Drawing.Point(FormGenerate_X, FormGenerate_Y); + // frmEmbed.Show(); // 显示 + // frmEmbed.BringToFront(); + // frmEmbed.initPicturebox(); + + + + + // } + // } + //} + //EndUpdate(tl_right_main_view); + } + + private void materialButton_changeFormSize_MouseMove(object sender, MouseEventArgs e) + { + if (sender is Button) + { + Button btn = sender as Button; + this.btnStartUpToolTip.SetToolTip(btn, "适配窗口"); + } + } + + private void materialButton_imageChange_MouseMove(object sender, MouseEventArgs e) + { + if (sender is Button) + { + Button btn = sender as Button; + this.btnStartUpToolTip.SetToolTip(btn, "图像变换"); + } + } + + private void materialButton_fakeColor_MouseMove(object sender, MouseEventArgs e) + { + if (sender is Button) + { + Button btn = sender as Button; + this.btnStartUpToolTip.SetToolTip(btn, "伪彩"); + } + } + + private void materialButton_imageInfo_MouseMove(object sender, MouseEventArgs e) + { + if (sender is Button) + { + Button btn = sender as Button; + this.btnStartUpToolTip.SetToolTip(btn, "图像信息"); + } + } + + private void materialButton_resetImage_MouseMove(object sender, MouseEventArgs e) + { + if (sender is Button) + { + Button btn = sender as Button; + this.btnStartUpToolTip.SetToolTip(btn, "重置原图"); + } + } + + private void materialButton_inverse_MouseMove(object sender, MouseEventArgs e) + { + if (sender is Button) + { + Button btn = sender as Button; + this.btnStartUpToolTip.SetToolTip(btn, "反值"); + } + } + + private void materialButton_save_MouseMove(object sender, MouseEventArgs e) + { + if (sender is Button) + { + Button btn = sender as Button; + this.btnStartUpToolTip.SetToolTip(btn, "Ctrl + S 保存"); + } + } + + private void materialButton_return_MouseMove(object sender, MouseEventArgs e) + { + if (sender is Button) + { + Button btn = sender as Button; + this.btnStartUpToolTip.SetToolTip(btn, "Ctrl + Z 撤銷"); + } + } + + private void materialButton_forward_MouseMove(object sender, MouseEventArgs e) + { + if (sender is Button) + { + Button btn = sender as Button; + this.btnStartUpToolTip.SetToolTip(btn, "Ctrl + Y 重做"); + } + } + + private void MainForm_SizeChanged(object sender, EventArgs e) + { + + } + + private void materialButton_LoadData_Click(object sender, EventArgs e) + { + string selectedFilePath = ""; + // 弹出选择图像的框 + #region 打开图片 + OpenFileDialog openFileDialog = new OpenFileDialog(); + openFileDialog.Filter = "TIF Files (*.tif)|*.tif|All files (*.*)|*.*"; // 设置文件筛选器 + openFileDialog.Title = "Select a TIF File"; // 设置对话框标题 + + if (openFileDialog.ShowDialog() == DialogResult.OK) + { + // 获取选中的文件路径 + selectedFilePath = openFileDialog.FileName; + + } + + #endregion + if (selectedFilePath != "") + { + // Save Log Information + Read_Write_Log read_Write_Log = new Read_Write_Log(); + string SaveLogFile = read_Write_Log.LogFile; + + List OldLog = new List(); + if (File.Exists(SaveLogFile)) + { + OldLog = read_Write_Log.ReadCsv(SaveLogFile); + } + + string dateTime = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); + OldLog.Add(new Log() { UserID = InnerUserID, ITEM = "加载数据", Description = "加载数据", Time = dateTime }); + + read_Write_Log.WriteCsv(SaveLogFile, OldLog); + + DataProcessForm frmEmbed = new DataProcessForm(materialSkinManager, selectedFilePath); + + if (frmEmbed != null) + { + //frmEmbed.FormBorderStyle = FormBorderStyle.None; // 无边框 + frmEmbed.TopLevel = false; // 不是最顶层窗体 + DataProcess_panel.Controls.Add(frmEmbed); // 添加到 Panel中 + + FormGenerate_X = FormGenerate_X + 15; + FormGenerate_Y = FormGenerate_Y + 15; + + frmEmbed.Location = new System.Drawing.Point(FormGenerate_X, FormGenerate_Y); + frmEmbed.Show(); // 显示 + PBAnalyCommMannager.processForm = frmEmbed; + } + } + + } + + private void materialButton_setting_Click(object sender, EventArgs e) + { + //if (settingForm != null) + // return; + + //settingForm = new SettingForm(materialSkinManager); + //settingForm.FormClosed += settingForm_FormClosed; + //settingForm.TopMost = true; + //settingForm.Show(); + } + + private void settingForm_FormClosed(object sender, FormClosedEventArgs e) + { + if (settingForm == null) + return; + + settingForm.Dispose(); + settingForm = null; + } + + private void materialButton_curveimage_Click(object sender, EventArgs e) + { + if (PBAnalyCommMannager.processcurveAlg()) + { + // Save Log Information + Read_Write_Log read_Write_Log = new Read_Write_Log(); + string SaveLogFile = read_Write_Log.LogFile; + + List OldLog = new List(); + if (File.Exists(SaveLogFile)) + { + OldLog = read_Write_Log.ReadCsv(SaveLogFile); + } + + string dateTime = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); + OldLog.Add(new Log() { UserID = InnerUserID, ITEM = "泳道波形图", Description = "操作泳道波形图", Time = dateTime }); + + read_Write_Log.WriteCsv(SaveLogFile, OldLog); + } + } + + private void materialButton_analyzedata_Click(object sender, EventArgs e) + { + if (PBAnalyCommMannager.band_info == null) + return; + + // Save Log Information + Read_Write_Log read_Write_Log = new Read_Write_Log(); + string SaveLogFile = read_Write_Log.LogFile; + + List OldLog = new List(); + if (File.Exists(SaveLogFile)) + { + OldLog = read_Write_Log.ReadCsv(SaveLogFile); + } + + string dateTime = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); + OldLog.Add(new Log() { UserID = InnerUserID, ITEM = "分析数据", Description = "分析数据", Time = dateTime }); + + read_Write_Log.WriteCsv(SaveLogFile, OldLog); + + PBAnaly.UI.AnalyzeDataForm analyzeDataForm = new UI.AnalyzeDataForm(PBAnalyCommMannager.band_info); + analyzeDataForm.TopMost = true; + analyzeDataForm.Show(); + } + + + private void materialButton_imageProcess_Click(object sender, EventArgs e) + { + string selectedFilePath = ""; + // 弹出选择图像的框 + #region 打开图片 + OpenFileDialog openFileDialog = new OpenFileDialog(); + openFileDialog.Filter = "TIF Files (*.tif)|*.tif|All files (*.*)|*.*"; // 设置文件筛选器 + openFileDialog.Title = "Select a TIF File"; // 设置对话框标题 + + if (openFileDialog.ShowDialog() == DialogResult.OK) + { + // 获取选中的文件路径 只传入目录 + selectedFilePath = Path.GetDirectoryName(openFileDialog.FileName); + + + } + + #endregion + if (selectedFilePath != "") + { + if (ImageToolMannage.imageDataPath.TryGetValue(selectedFilePath, out var value)) + { + return; + } + + + + ImagePanel frmEmbed = new ImagePanel(selectedFilePath, pl_right); + ImageToolMannage.imageDataPath[selectedFilePath] = frmEmbed; + + if (frmEmbed != null) + { + frmEmbed.TopLevel = false; + DataProcess_panel.Controls.Add(frmEmbed); + FormGenerate_X = FormGenerate_X + 15; + FormGenerate_Y = FormGenerate_Y + 15; + frmEmbed.Location = new System.Drawing.Point(FormGenerate_X, FormGenerate_Y); + frmEmbed.Show(); // 显示 + frmEmbed.BringToFront(); + + //frmEmbed.RefreshUI(); + + + } + initPanel(); + + + } + } + private void materialButton_log_Click(object sender, EventArgs e) + { + if (logForm != null) + return; + + logForm = new LogForm(materialSkinManager,InnerUserID); + logForm.FormClosed += LogForm_FormClosed; + logForm.TopMost = true; + logForm.Show(); + } + + private void LogForm_FormClosed(object sender, FormClosedEventArgs e) + { + if (logForm == null) + return; + + logForm.Dispose(); + logForm = null; + } + + private void materialButton_outimage_Click(object sender, EventArgs e) + { + string datetime = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); + string dir = string.Format(@"./{0}/", "Report"); + if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); + + string savePDF = string.Format("{0}{1}_Report.pdf",dir,datetime); + + // 初始化文檔對象 + Document document = new Document(); + // 添加頁面 + Page page = document.Pages.Add(); + // 向新頁面添加文本 + page.Paragraphs.Add(new Aspose.Pdf.Text.TextFragment("Hello World!")); + // 保存PDF + document.Save(savePDF); + string ReportMesage = string.Format("Report Save at : {0}", savePDF); + MessageBox.Show(ReportMesage); + + // Save Log Information + Read_Write_Log read_Write_Log = new Read_Write_Log(); + string SaveLogFile = read_Write_Log.LogFile; + + List OldLog = new List(); + if (File.Exists(SaveLogFile)) + { + OldLog = read_Write_Log.ReadCsv(SaveLogFile); + } + + string dateTime = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); + OldLog.Add(new Log() { UserID = InnerUserID, ITEM = "导出图像", Description = "导出图像", Time = dateTime }); + + read_Write_Log.WriteCsv(SaveLogFile, OldLog); + } + + private void MainForm_FormClosed(object sender, FormClosedEventArgs e) + { + System.Environment.Exit(0); + } + + private void materialButton_imageInfo_Click(object sender, EventArgs e) + { + + } + bool isGridView = false; + private void materialButton_changeFormSize_Click(object sender, EventArgs e) + { + + //isGridView = isGridView == false ? true : false; + //initPanel(); +#if true + //var forms = ImageToolMannage.imageDataPath.Values.ToList(); + //int formCount = forms.Count; + + //int rows, columns; + + //// 根据窗体数量确定布局 + //if (formCount == 1) + //{ + // rows = 1; + // columns = 1; + //} + //else if (formCount == 2) + //{ + // rows = 1; + // columns = 2; + //} + //else if (formCount == 3) + //{ + // rows = 1; + // columns = 3; + //} + //else if (formCount == 4) + //{ + // rows = 2; + // columns = 2; + //} + //else if (formCount == 5) + //{ + // rows = 2; + // columns = 3; + //} + //else if (formCount == 6) + //{ + // rows = 2; + // columns = 3; + //} + //else // formCount >= 7 + //{ + // rows = (int)Math.Ceiling(formCount / 2.0); + // columns = 2; + //} + + //// 计算每个窗体的大小 + //int formWidth = DataProcess_panel.Width / columns; + //int formHeight = DataProcess_panel.Height / rows; + + //// 清除 DataProcess_panel 中已有的控件 + //DataProcess_panel.Controls.Clear(); + + //// 调整每个窗体的位置和大小 + //for (int i = 0; i < formCount; i++) + //{ + // var form = forms[i]; + // PictureBox pictureBox = new PictureBox(); + // pictureBox.Image = form.GetPseuImage; + + + // int row = i / columns; + // int col = i % columns; + + + // pictureBox.Bounds = new System.Drawing.Rectangle(col * formWidth, row * formHeight, formWidth, formHeight); + + // // 添加窗体到 Panel 中并显示 + // DataProcess_panel.Controls.Add(pictureBox); + // pictureBox.Show(); + //} + //COMMImageToolPaletteForm cOMMImageToolPaletteForm = new COMMImageToolPaletteForm(this); + //cOMMImageToolPaletteForm.TopLevel = false; + //cOMMImageToolPaletteForm.Dock = DockStyle.Fill; + //pl_right.Controls.Clear(); + //pl_right.Controls.Add(cOMMImageToolPaletteForm); + //cOMMImageToolPaletteForm.Show(); + + + int margin = 5; + int formCount = ImageToolMannage.imageDataPath.Count; + if (formCount == 0) return; + + int columns = (int)Math.Ceiling(Math.Sqrt(formCount)); + int rows = (int)Math.Ceiling((double)formCount / columns); + + int formWidth = (DataProcess_panel.Width - (columns + 1) * margin) / columns; + int formHeight = (DataProcess_panel.Height - (rows + 1) * margin) / rows; + + int totalWidth = columns * formWidth + (columns + 1) * margin; + int totalHeight = rows * formHeight + (rows + 1) * margin; + if (totalWidth > DataProcess_panel.Width) + { + formWidth = (DataProcess_panel.Width - (columns + 1) * margin) / columns; + } + if (totalHeight > DataProcess_panel.Height) + { + formHeight = (DataProcess_panel.Height - (rows + 1) * margin) / rows; + } + int index = 0; + foreach (var item in ImageToolMannage.imageDataPath) + { + int row = index / columns; + int col = index % columns; + + int x = margin + col * (formWidth + margin); + int y = margin + row * (formHeight + margin); + + var panel = item.Value; + panel.Size = new Size(formWidth, formHeight); + panel.Location = new System.Drawing.Point(x, y); + panel.TopLevel = false; + panel.FormBorderStyle = FormBorderStyle.None; + panel.Visible = true; + DataProcess_panel.Controls.Add(panel); + panel.Show(); + panel.BringToFront(); + index++; + } +#endif + + } + } +} diff --git a/src/PBAnaly/MainForm.resx b/src/PBAnaly/MainForm.resx new file mode 100644 index 0000000..2af4327 --- /dev/null +++ b/src/PBAnaly/MainForm.resx @@ -0,0 +1,2003 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAABGdBTUEAALGPC/xhBQAACZFJREFUeF7t + nL/KpVcVxg/E8RZC8BYsLCwEIQSSKm1qsfECvIQ0uYbYiLUWSbp0SSWEdEKqgKCtrVUq3ct5jozbtedb + zzn7W/O97/f7wQ8mM/usl/Xs9zn5M0MuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwxHhxufxJP3wU + Yj7PqNH1DP0QKvzocvnXY4UWc2M+z3iYzmfoL6HCY13KqxfOM15P9zP0U1DhMS4lu/CrPON/eRPP0E9D + hVeDC++9lNdd+FWe8ZI39Qz9ElSYwwtvvZTKhV/lGW/uGfplqJAFGLqX4lz4VZ5Rd+czdAQqZAFerV7K + LRd+lWfU3fUMHYMKWYCv+tCl3HPhV3lG3R3P0FGokAU4u7qUHRd+lWfUvfcZOg4VsgAz50vZeeFXeUbd + e56hj0CFLMCV10t5jAu/yjPq3vqM+AwUyQJ8nY954Vd5Rt1bnqGrhwpZgHhudfVQIQsQz62uHipkAeK5 + 1dVDhSxAPLe6eqiQBYjnVlcPFbIA8dzq6qFCFiCeW109VMgCxHOrq4cKWYB4bnX1UCELEM+trh4qZAHi + udXVQ4UsQNOvsd3sHsrq6qFCFqDp1xoFDUTeU/62GgUVsgBNKUgjkfeUv61GQYUsQFMK0kjkPeVvq1FQ + IQvQlII0EnlP+dtqFFTIAjSlII1E3lP+thoFFbIATSlII5H3lL+tRkGFLEBTCtJI5D3lb6tRUCEL0JSC + NBJ5T/nbahRUyAI0pSCNRN5T/rYaBRWyAE0pSCOR95S/rUZBhSxAUwrSSOQ95W+rUVAhC9CUgjQSeU/5 + 22oUVMgCNKUgjUTeU/62GgUVsgBNKUgjkfeUv61GQYUsQFMK0kjkPeVvq1FQIQvQlII0EnlP+dtqFFTI + AjR9sCBx5l41akn2mSOqdZboXHYPZTUKKmQBmlYuNfucY8cznoRaZ8k4Q0E6yQI0pSAb1TpLxhkK0kkW + oCkF2ajWWTLOUJBOsgBNKchGtc6ScYaCdJIFaEpBNqp1lowzFKSTLEBTCrJRrbNknKEgnWQBmlKQjWqd + JeMMBekkC9CUgmxU6ywZZyhIJ1mAphRko1pnyThDQTrJAjSlIBvVOkvGGQrSSRagKQXZqNZZMs5QkE6y + AE0pyEa1zpJxhoJ0kgVoSkE2qnWWjDMUpJMsQFMKslGts2ScoSCdZAGaUpCNap0l4wwF6SQL0JSCbFTr + LBlnKEgnWYCmD768sI/Ie8rfVqOgQhagKQVpJPKe8rfVKKiQBWhKQRqJvKf8bTUKKmQBmlKQRiLvKX9b + jYIKWYCmFKSRyHvK31ajoEIWoCkFaSTynvK31SiokAVoSkEaibyn/G01CipkAZpSkEYi7yl/W42CClmA + phSkkch7yt9Wo6BCFqApBWkk8p7yt9UoqJAFaEpBGom8p/xtNQoqZAGaUpBGIu8pf1uNggpZgKYUpJHI + e8rfVqOgQhagKQVpJPKe8rfVKKiQBWhKQRqJvKf8bTUKKmQBmj5YkOQzrh3PeBJqnSXjDAXpJAvQlIJs + VOssGWcoSCdZgKYUZKNaZ8k4Q0E6yQI0pSAb1TpLxhkK0kkWoCkF2ajWWTLOUJBOsgBNKchGtc6ScYaC + dJIFaEpBNqp1lowzFKSTLEBTCrJRrbNknKEgnWQBmlKQjWqdJeMMBekkC9CUgmxU6ywZZyhIJ1mAphRk + o1pnyThDQTrJAjSlIBvVOkvGGQrSSRagKQXZqNZZMs5QkE6yAE0pyEa1zpJxhoJ0kgVoSkE2qnWWjDMU + pJMsQFMKslGts2ScoSCdZAGaVl7euNS71Kgl2WeOqNZZonPZPZTVKKiQBWj64KXCPiLvKX9bjYIKWYCm + FKSRyHvK31ajoEIWoCkFaSTynvK31SiokAVoSkEaibyn/G01CipkAZpSkEYi7yl/W42CClmAphSkkch7 + yt9Wo6BCFqApBWkk8p7yt9UoqJAFaEpBGom8p/xtNQoqZAGaUpBGIu8pf1uNggpZgKYUpJHIe8rfVqOg + QhagKQVpJPKe8rfVKKiQBWhKQRqJvKf8bTUKKmQBmlKQRiLvKX9bjYIKWYCmFKSRyHvK31ajoEIWoCkF + aSTynvK31SiokAVoSkEaibyn/G01CipkAZpSkEYi7yl/W42CClmAphSkkch7yt9Wo6BCFqApBWkk8p7y + t9UoqJAFaEpBGom8p/xtNQoqZAGaUpBGIu8pf1uNggpZgKYUpJHIe8rfVqOgQhagKQVpJPKe8rfVKKiQ + BWhKQRqJvKf8bTUKKmQBmlKQRiLvKX9bjYIKWYCmFKSRyHvK31ajjs9YJsJ4bNMQDbOZuFBXezOak91D + WY06PtlyeGgpyE6y5fDQUpCdZMvhoaUgO8mWw0NLQXaSLYeHloLsJFsODy0F2Um2HB5aCrKTbDk8tBRk + J9lyeGgpyE6y5fDQUpCdZMvhoaUgO8mWw0NLQXaSLYeHloLsJFsODy0F2Um2HB5aCrKTbDk8tBRkJ9ly + eGgpyE6y5fDQUpCdZMvhoaUgO8mWw0NLQXaSLYeHloLsJFsODy0F2Um2HB5aCrKTbDk8tBRkJ2OZH+bl + 8NB+o6u9mZgxzXT9QaOOz4vL5e/Jgnhc/6GrvZmYMc20jHdKo47PWOjebwt8Yo5rffvl7d7E29lM07v/ + LvZkGMt8MS2Hx/eXul6b+Ow06xa/0Ljj89bl8rtkQTy2X+p6beKz0yzbeKc07viMhT6eF8TjO/494Le6 + 4jLxmWzWDX6skcfnx5fLT5MF8QSO633n5S2XeCebcYvxTmnmORhLfTcviacxvs1fV5Qoxs5/ivhOc8/D + WOqTaUk8l/8c/nn8u8Gnw1/JT+Pn9GvZZ271E71W52Es9f60JOKtvq/X6lyMxb6dFkV0/Vav0/kYf8v9 + dbIwYtl4h/Q6nZOx5Ffz0ohFv9JrdF7GN8BHyeKIDxrvjl6jczOW/WxeHvEBP9Pr8yz4yYvL5W9JCIj/ + Z7wr8c68fHWeCWPx9+YgEBe+p9fmeTG+GX6ThIH4X+Md0evyPNn4h9fwZMa7odfkeTPC+GAOB5+9H+j1 + gGB8W/xihPL9FBI+P7+Pd0GvBbxK/BHmty6X3yeh4TMw7v50f4z9MRhhvTu+Rf44B4jnVHf9rq4fqoxv + lA+Hfxj+dQ4Vj23cqe72Q1033MP4lvnZMP6L1+fDvwzv+t/GYKtxV3Fnn8cdxl3qWuGRGV9A//ld+Z+P + 8OM3HvGJGHcSd6M7AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGjgcvk3xu28sioLImYAAAAASUVORK5C + YII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAABGdBTUEAALGPC/xhBQAAHyVJREFUeF7t + nQuYHUWVxw3rsru6uyruqquiKJEkd8gkOCCCwEZEfIOI4GNRWVQEFQSFyEMQQYUIKqiwPAUBQUWeCsKi + JohgFFghYsJLlPdTkPAKL93fmTkT7lRq7q2uqu6u7lv/7/t/M9+9t/91TvWp7urqqlPPyCiGmTNnTl9z + zTV3HxoaOou/i+GD8G+pEnsX8vdYuBMcVjcyMuKC4Fodfg9aA7FBPING80p1KyMjHATUPEugNZ2Hj4yM + PEtdzMgojjlz5jyTxvETS3C1gvh2Nm5OGfM2I6MgCKLjzKBqG2kkB6i7GRnu4CH8TbaAaiNpJFup2xkZ + TphC4PzBDKQW817xecz1jIw+4O7xDksQtZrcRTZS9zMyeoOAOdkMoAHgYep+RkZvECx3GMEzCLxd3c/I + mBwjIyPPsQTPQLDT6QxpNWRk2EFffMQWPIPAPJqV0RcEynvMwBkg7qXVkJFhhwSJETQDQ+4gJ2g1ZGTY + QaD4vj2/E85JhL+BNhv78ZdaDRkZdhAkFxlB48qLVKJ2DA0NHWWxz4X3qERGhh0Eya1G0LjyWJWoHdiy + m2GbM6dNm/YvKpORMRGrrbbaP9qCxoX03z+rMrUDWza32ejCTqezrspkZEwEXZOOLWhcyLFbqkztCPED + bqMyGRkTQWBtZgkYVyaznHXq1Kn/YLHPidTB/iqTkTERBMeutqBxoQSlyiQBbPqTaaMjT1WJjIyJoO/+ + LUvAuPBWlUgG2HShYaMrr1CJjIyJoIH4Lq9doBLJAJuOMGx05TKVyMiYCILjeiNYXHmMSiQDGvunLXY6 + sdPpvEhlMjLGsNVWW/0dwfGkGSwu5NllrsokA2zyXvRF48qLpzImYnh4+BW2YHHku1QmGRDkkuDOZmtf + 0rg+ojIZGWMgMN5oBoorCcaZKpMM9I5otbcfcWeeymRkjIHA2MEMFFemNsQ7Dmy70bTVkWeqREZVoNLX + hjtzdTqNvw/riRBK9pALuK1/Dq6jP68cctXssqkIb1aJ5IBPvqNyv1OJyjFr1qyXEAefwIYfwEXwAaX8 + L5/tNGPGjP/QnzcfnU7nZUVOFJVzLZy7xhpr/JtKVALKPsO0xZHzVSI5UI/ftNjrRJWoDJS5NTy/24Ye + fISYOqDxqVNxRPr10vptTrrwdE7yO1SuVFDWNUbZTsS+o1QiOWDfzqa9rsSvWSpTGoaHhylqzUPhfePl + FqQk1/iAyjULGL5dlyOhvJsTdhCcqvLRgKbczkOymOyuUsmBq+xbLPYW4eHS5VG5KJCkGFrnlxtleVO6 + xyrfDFAB77M5EomXwO1Cb69U6vbwNkO7MNF4p0omB7mg2Gz2YHBDwZaN0TnR0I3J5IbardA1FbL81OZE + TMrGNbI8dn0t2gmcKJmxe51qBFO6CSqdHEJeflr4KBeDQv1+aVQcsw/H+o6mFeHDlJXccPsKIAD3txhf + NpdQ7lyC9QVqxgqg7uTF2QLjuGCmOsQ7Dmz0nT4zGW+lLt+v8iug0+mszG/GH7if0mOq4mK5KKgp6QED + V4XLugyumk9w8s6Gm49XFA1nFT6XiXuxrqTdTHaIdxzY6DoyVIjU8UI4osXIBWgmnx8G7+3+XQ38lJqU + HgjG8ywG18U7OWdH8/d+4/NoxN+fquvJgjrwncLvRPRP4e8V5uc1cmmvnkRtIFgGLiM6Pic7xDsOAth7 + Vm+DeZy6nwZ0iefNhpGDwN20CpIFDcQ7gUOTybPQa7QK6gcnYV+bkW2nBJ9WQbLQl3FW+1vOK3G//k2B + ZCqJxbhB4OLYL9HKgA67zzdsHxR+WKuhPtAPlw31bca1lfPx+c3qfmPAhWwtbD8dVj30WifvrjURHoES + Y6PLuyyfJUe6U2fjb22zjWOBu94a+HG8zccEGWMjo/p2zqLw0I0uDxcdTtiW/F/KeH0EfkeCatThFoEr + 64upd5nt+4jhbwo8nwvS6BQe/g/eihut6t+wU/DepiEFeR92P0/lRsFnq/LZAfz1zY8bi3/FjlN4wH2F + mtZayLICfP06Pj9q1EGlxIbb9NyvqqaNQuzjs6Xdv/XgxSpXDShQ3ph3L3ry4Y4qtwJ0DtHbqbCz+VvG + G/BePIcra0dNGRjIIiR8PxI+3lUXZVOeh87lPC+f+WADv9mp6xgvck7fq3LlgwJ/aBpQkM5DcDxcvojf + y92q1AlvnKSrqcTXabEDCxrKq6iP6HPWDN5CXX/BdRRQL5hLDI2ivL2SBVZ0O95gKbwQPV/iyOb+sgBL + ll0+Nq4VgX/mZH0c/ZXGiskQUC9bUC9/NOoqhNITOAe+3WdCoVy8urS8iMaBKlceKORaW+EFeLJKeQMb + VoFz0brB0C7KI2UBj8pmGJB3KPpcYKs7J3K8PFvsKz0BlfUGejH2r19d5eIDRz9rKbAIH4694B6bNkL3 + JFjkIVMmMm6iEhl9wMVoFnVWZEnyExxzFnX8Vg6PdmfW56TQB/YLVS4u1LigB3O56qtcdHQt5bzSLNfg + ybNnz36uHpbhCO4AKxPwkvml14tGeU7cO8bdYjKg/5mu8rxInMTPc4Dw982CCvIGgvjvVa5UUAHrcDJl + qrusOhwvX541NtOfZHiC4F+Xeux+NpHnQXkufCNflz73KdID+01RF7oRbP9pKaQoN1W5yiCjFpzMj1L2 + sWuttda/68cZgVhvvfX+iXr9KpxbR71yPmUnX1uMFWGcPeEjtdhzVC4jIwqIKblr2WLNlcuiPA8jFNrn + W8Zt+WUql5ERBTGeiekZnaZyfohhBPyiymVkRAWxtacRa4XJxXsDlSsO+pjftYkWYDVvLzMGEjLoQ4yF + Tphd7PPiUt6Yb2gRK0RuYVupXIZi9uzZq1Ev8u5mGyhXwEPgMVBGCWVG8/9CmcpzHL/7Ghepz/F3W/5u + DKNnlmw6qKdNoTX+XEm97qJyboj0YF7tDMpEQT28EO7ASZCMLzFSIj0Bfy4nlS7wy7WYgQZ1Ebpob2mh + 0TgO+JQhUJj07YZUbuDACZOpMLtQD5eZ9VICF3GH2aPMl3OpQy4Ulnopym+rXG9IS+LHoa/zD1W5gQKB + KsmiZVmrrU5Kp9ylsCH5RBJlAL+DE4fIS1CVmxz8MDTBcL3rgCuGdkc/AH/XVQd183oay0dTT4saE5FS + T/VehsEP1jcO8GH9mSQqAletT+Jv3asfe1HW+39GzW09uChIYnJbPTiTc7q9yk2EXgmvMg8oyDRyEZUM + KvGt+Pp7w/eUKcsCmrE9QCBoJD81fC/KFZaCj0KvhrYDnIlxjc/60QuyAg4/LzD9bhAXtH2dPT6ubvhc + mLSFb6ncGGIsjKdxHK9yrQSVJg/gfzb9biCXSldE3Wol8PFLhs9F+Vfq6Okt6Pjg88YPirLYOHKDIF1P + KusgfPyr4XPTeeicOXOeqW62CjJ7A/9uN/wtRC6Iy+dpyVrvIDECaFfVahW0oi80/W0Rf97WEUdi8t0W + f4vw8dGFdRGSMCz2msuSOKhg2Xjnt4avbeQiYiC9/TQiAN9+afhaiKMXfv4JWgiPyMZqT2ugb2ZDE0I0 + hpzDP9KleKW63xrQ8KfZ/HUldXK1PHxebfvSkaerLa3B1KlT/xW/om3y2RRqI1lxeLPhwLeDTV+LUARC + uhHHqh2tAUHyM4ufZVGe/aT+Zej4JIL0q/z9MjacwP8yuVH2Er8F2o4tgwu0GloDfNrL8LEQRSB0Qt2l + kghZ7Wk0CMqys57/Gu5HA1hPi3QGx4zAPTj+oi69MniSFtloyOADvpxh+FaYUvELbV8U5D0EV6OfRfBh + Z8OnWJRdXw+mnqdrUcGQNSXUt2y3HWN7ABvT3SnWATx74EKU7a8flMA41fjQmwTBvmpjoyCzOG3+BFKm + LMg09H/WYkoB5Uhi57u7yo1Cp5mtCYILx4ewP1am+sXjb4htX/ryQoxcRe1NHtOnT38+NseccChbJxw9 + UmFKU66Yz6bcQ2HM3aNubVKCPZ3NKyszbb74cs9Rcf6Jfau+mUbSiHlZ2BrcT+3inwjWDVW6ckidY0Po + StDlpKGHZf2oCNT5K7A3+jur5YvQqFiZSmH9UQAfQ/cTowUkCuyLsYWcUKahHC4J1VS6NnBSV8YvGQ2L + cjeRHoZKJwntAYUu8LPxXC1i+dh/tCtPN+UqJF0ALSoZSDBjX4whVJnY9kGVTQbY9F5si7H50M0pLrzS + 5RlfMWyNRRlYmZgFniB+KR8GzcnqwWtoKNFGcWKAADrQYqcPt1HJ5IBtWxu2epG6+oJKJgHp+mDTL2y2 + RuDDxOqIFjURfDGTHzxkHBCLj+DUu7WoWqHT+4M3r8Sf96lkshAbsTV0JvIjhEYSb9mxQ/JERx+1Uz5J + ffXe4luG9zDiNsvBsXiEFlUbqIQYz1yNeVeAvx+32F+U+6lcbcCG4EyKPSg7AWyhRfUGFboKjeQnhkBM + Xk5DrCVfrwxdUn73tgg+PEblGgPOp2wHYfPFlfdzzkp9pzMZ5JwRkzL1xmZXDMqeMsV3nqJSQ3eU6sUH + 4Nu0qMqAT/sYdhTlEtmaTOUaA7EZ24vsErUCqbtPq1xloGHI0HVotpJJiU8Tl9cWBVeNDRAps8v1FS2q + ElBeUC5X6qL6TekjgWCTrdSsfjny9ypVCSivrOk/QknKvrUWFQbpciFW5sq6S2RkQosrDfgRulPql1Wq + scCH0KHRYZUqDTLRkOuQ7JFvKz8GF82YMeNVWlw8YHRo96QX7xkeHn6DFlUKKON/jDKL8E8q02jI+5+Q + HgHHzlOpUiB3ORhz++kJxP6jtahyIFMpKOhOs+CILC1/E9r3GWU5k5P2UZVpPPBHJjha/XTgLSoTHdSx + PG/YyoxB6VK9R4sqF5q/t6wu145aTFRw5VjPUpYrb29TBhCdRRDyLmGGSkUFDWRjS1kxWE6Xqg+m4NDn + KDzGdIZuuo1FF0Rg93BsVmeLgE9fNHx0JnX5SZWJCp5Dh2zlhVC6VLVOlcEAebMZbTawXOlVOirQ9l2J + 95S8eVeZ1kBnwNr8deGZKhMVOsPBVp4PHyKW3q/S9UK6XNxNQnOijlJOnMpGha0sF+LXeSrROuCfb1qc + B1QiOixl+bCWLlU/rIRhkqExaJq17DunetFAo0PaXl4/0kCKbc/VIOCfd0ZNAjB8C2ULuOqHvnM7JsXZ + x8uhXS7fB8ClKhMVBLl3lj38aeyLwX7ANdkr0eq3A+eoTFRg0/9ZynJhOl2qfiAgvSYDcty1KhEVaPum + fimtK5EKLD47kWC076MRCOnS2srrR447SyXSBwYfZzrgyFI2/kT3O0Y5rrxMJVoLAsv3pdzBKhEVNLwT + LGW58BKVSB8Y+2PDeFeeoxJRIVcXS1l9yck6RSVaC/z0ep9FnX5XJaIC7cPMshx5vUqkDyrPd7XXiSoR + FQS619R9jit1WkUKwEffafAXqERUEDuS78tWXj/eoRLpA2OvMIx3ZSmpTNGdb5Tjyi+pRGsREJC/VYmo + oMH6vtBtzvMixi42jHeiXM1UIirQvsQsy4UET1JrscsAfu5o+u3IW1UiKtD1XTX4mEqkD4z1XZhTyko9 + dL3eotNADlSJ1oKL0rY23x1YSpcGXd8G8pRKpA+M9d0B9jiViAp0vQYNaCDfVInWAj+9ZvZSN6UMyQ9K + F0vW+Nqc6MeyHtJPsZTlwlIabErAR993RL9RiajwfSbiHN+mEukDg30fissa5j3KUpYLz1eJ1gIfjzB8 + diIB+TOViAq0v2GW5cglKpE+Aq7YZb0o9J3afaNKtBYS6Ba/XXiqSkQFFzPfPVouUon0gZOSG9bmRD9e + pxJRgT0ftJTlxBTy7ZYJfLzL9NmRpeTJQtf3JXMztgPkihSyPqSUyYrY5L2akMbVuk1Kx4FvU20+u5A6 + LWViINq+79CSn6y4Egbui6HJTXfX5NzW8voRnw5QmdYB3z5m89mFw8PDr1aZqMCm9k13lwVTOBZl80vZ + XkxlowJtr0QT+LVQJVoH/Dvd9NeVXMiepTJRYSvLg1cls2CKAIq65JYr02tVOirQ/qFZlivLWuVYJ2QH + LHx73PTVkaUM8cZecksXstZk6VG6VCbR3Fz1owJt71Q3VPRBKtMa4NMuNl8dWUo2zJCVn5MRP4+qvMul + aX8WmMbEIA2klIU4aEvtW8t04H0tG82S5dE3GT46k3P0VtWJCnQ3sZUXgdWtUccJWaZZWuI4WvyWWlR0 + oC87B1nL7Ue54qpM48E5/C+bj66U1KAqFRWdTuc1tvIiMV4u3slAxTY99WjILqjNWW/QB/hyneFbEf5Y + ZUoB+sNcjMpMPRqWzd2GkjMpCitJXk3lyICCrXwncnwj94HvBn6EpB2VO+l7Vao0aPLq02zlR+KiaAMv + GlSxt4kep+wpPk82ZNTiysYUygzZuPNhTt6LVatxoK6fhw/e+YnhQ1XujUJ50pgf6yo/JpfS2MNGuRCQ + 1KI28Ri8jxNW+RbDlPslw45CpE4am0gO+79n+lOQpaz47AXKXBumtYFOBV2qy+GqWlylkIRnhi0+bMz+ + hOPA5g8bPhQmF4eOylUKvfOda9oTkVc4d7n48fqwrC6V8HAtqjZgQ8g+IaPkpG2kcsmD57t1sTl0V98z + VK42YEOZm3g+wDl9pxZlB1cI2aJLhsNsAqFMZhtomc6CPaEvOKUPO0slk4VmTL/fsL0wucKWMveqKAji + kMyd/SjbZW+nRU0EFTCNL73fE/Th9bCUPSV8gT3f7rLPl/fAtVUyOdA41sI+3+nsy0lQnq2SSUBGPLHr + YtPOWMTfbbWoMcyaNeslfBEyutOLP8ShWrYP7gV9zlpq2OpD2WS/lOkxIcCut8EYvYFHow2JRga2HWzY + Go30Dl6nxYwWdJL5gwh8jMApZaOVWKASYmywL5Th6n1Utnbgl4w+xpojt7fKJgnq/S3YGONCZ3Islalu + xxX6AGdShuWS7Xp0Azsv67I7lOcQnKuodOWQssUGw6YQXqPSSUPucNjqmyhkUlKf60iAbGN+EcgL6wyS + osDWDjbHHJj4C9yrysmNsjYDP+SuIWXbbPKhTIUvfcvnWJAZu9gbMpXIxkOkgfiuAV6B3O4aORUDu4Mm + 703CuwjaXctsKNIwKGc3WMaozg5aTKNAnX8I2x81fPHlImkgvmuAu3kPhjV67TY+HGn4FIt3Ujf7z5gx + 4+VaVDDQmwplD5ZShjvRLiVze1XggjcTH6JMeJTAuMr8sCAvbfL8pHHIHCN8+ZXhW2xKCtQ9OX8jWqwz + 5GUfx8ls6ku79Mrg5WUtp60SmofgDMO3wpTWdrXtCxfSSo9Xe1oBmUWKX6EXDFfKyMul1KEktdtvEh4L + fw3Lenlrcsn06dOfr9XRClC/QfMJ5Q7ilYldSOHN2fbKEfj1wli354bxZnkfptXQGnADmGfx1ZkSEEEz + PAmmN6ktrYE8L+CbvP23+txCyvLb1dX91oAGv4bhZyHSuBZKA9nU/KIg/6D2tAqaYSPGAEbq/O3w8PAL + 1O1WAd/ON3wtytENlKbQUkKTde01alHLQOA8G99+bvjaJi4oa3153SCmN7f4W5Rjd1X+8U3uPE55E1/L + +o4qgG+lzfmpkYeoe60E/nlnbVFeqFJxJu7RYk9TuVYC/2TOT8w31XXxL+KLutVK4F9wcpFOp/MalRsD + H37K/FFR8sD+epVrJai0l+FnadOsK+DF4oO600rg46qGzz5ccWmxJE7gC+8hX+WSkRKSTycGeWaTpM9N + upvcj82SkG/KmAvtBX6GZkNZKj0qlZsIxIPS4ig/o3KtBldiWbTjne+3Qp4KX6hmtxr4OafLby/SBnov + 0eBH3zcPKsiHJTGCyrUedCtlNvCJ8ImuOqibj3OiT8C2qWpm6xGpB7S4bwqq4eHhl/LD0PUhJ6vcwED6 + 9gTl1/E9JO9UKO/GhnltmBtXFFwMQpJxjxKNp1cR9gI/3ts8uCidC2sZ5BkM/98FZRnBk+P1USKfoK7P + gptVmIAvKUQahT1F5fpDT/INpkhBLhnUEzYOmVFK4L6DupD3KL+BMbphspBJJjkexEl9C3eu5Nb7Vw3q + IzQBR/HHAg6SRf82sSLcSeUyFAT2OtTLdtoduwDKNhKTkt+fx9+D+ftBjik8Tb7t0Pq0xV4R7q5yxcCB + odkVl8qcJpXLyIgOYix0LfoN3q8mOHh16LtN1yhp4a1aM5KRDoiv4HSq3JU3UTk/IPJlU7Qo5TaochkZ + UaCL20KXHJ+pcv6Q5ZcI3W4IF+VVSLX+LW5GdSCmDjNirCiXRZt2g9jWhnhhciv7mMpVBhnhkXIp/xju + Yo1JRZQ6JFOLDDJQp3PrqNfhOJt9fl7l4gDB0El698+ePfu5KlcqaBiy153kSHqwq3x5idbqWaxVgLpd + l0bRvSRZNrj5PkEr2+dV0kugvNBYvCn6zreIzoBBL76o2KNULjroCj6HBvBJyumXdOHEti4SKhM0jJWp + u0Ngr5Smf4B70lhKW6GIfozeTO9tDnyBeGi/T9LLR83WR6N7HQ6fgK7z9Bh+Lyso56hERh9QXyPU1zXd + ddiH8kL0TI6T7aJXGlMJR6Tn4acXQsVGpJGDy1TOG3K3oGHsAq+16BfhkaKlshkWUEdBq03lYsR52j9G + xhT0Qle+/k0SOahcOaCQ7cxCPWjfpKQPuHVvyLGSiT5WaknhvZxEGUDIo2xdoK5fS92EbBdt8ikaiswK + 2MJnCpKMOHFs0Ds5zvM8lSsXFCbJzKxGOPIe1+cAebCnYnflmCWGRmxeKV0JLXZgob2EI6B0h231FIN3 + cE4PLJKOlWNCs9bfLl00lSsXEkgWA4ryGypnBRX4evhdy3GlEt9O4+o5Tc0YGOg2GDvD0D5+UUrWmG3U + DCuIgzcZxxQmGu9TuWpAoZIW02qMI2VEbMIDO07I/ha78Tf02SKUMlJzIg0lyZ2VYkJH//bFX9lOzlYX + VVG6ul8zL07YF2Nm+cUqVx00sVrouuxRw2kQG/N/6B7epRDbjm/jHUUemglImVEce/OkGPwl9f4huavx + d67l+0LEz5nqdrWgXHnvYDWqAKu+pfvyDB4U11LXGwsCTrZOON7iX4qUF72hibt7duVLRaR1wE3jfALs + zVoFjQF2r43dZ/G3zIfv1Hh37S+FuapuYDFsELi4CdnQtZvyC4v9g8APazXUCwyR1DI2A1tNupjlTFmI + COyUmX1W+1vOK3E/jXdbsp4Xg6ra5CUlJp8DjLvHlha7W096NhNTh9YNrqZ72AxtOY9Q95PFgJ6XFVOH + pgAMCx2vjskbCQ6ZxGj7LhYvUNeTBTYeZ9gcmz+AKe2j8uCkqUPrBgG5icXgKvmQNAq4kZokNs3k88uM + 38XiDVpMsijxAf0aSz3LbO97u35TB9POpIOBoXNmfPgrAuEj9DsnyxE1he8/we8eMI4L5ZOp5/7Cxtjv + meTF4t7U9cpaxATI53wvazZkd6dea0fK4OLkc7FplrtbDMPL4F1QFvDM0KL7QgcToiacTnk6CrbJDllW + uz35oyL+8tuXcmORaSw3GjqlkMa5rhadNjBWhhZjTknv5o/gFlqUF7ibdGCst8mbqmxy0G6Pzeai/AHB + FzSLgPqW6USS5NumH0xpiFpUM0CFbGZzxJM3UAF7cEWKupRTrnBoHwpDGnOyfV5s28KwtRDlIgKjZojX + xW7S3b3cLM+XxIZ7Xt2UgPHrQ9+N+aWveyxXrg1UrjRot9BmgwsPU5nkQCB6T/Tj4vFqlSkNeoeTC1RI + Rvw9Va65oB62xxHXSrgEbkfDqDQpM8HkNcWe485TieRAvR9ts9mFKlEZsHUryi2ybbMMX7dn41hZGUgl + /LeeNMl0/mcob99lsqMs8P80D9Gv0p9XDmyQZxvbiejH61UiOWCb7xbWS1Sicsj8NsrfAX4HyvC8DBvL + rF5ZxSqf7TRtAPc/qR000K9R+bZg6cdkh3qx7VbDVlf+SCUyMsZAUOxoBIkz6a8nt6BKEqPZbHWhXCxU + JiNjDAT5G2zB4si3q0wyIMhDhnh3UJmMjDEQFN77a/OgvqvKJAPskm3grPb2o1wsVCYj42kQHMvMYHFk + crN6Q4Z4YXtGhzLigcDwemdDMP5UJZIBdknybqu9fbhMJTIyJoJu+2mWgHHhTSqRDLBpvmGjK3+nEhkZ + E0FweO+mFT2dfiCwyXfC6OkqkZExEdxBtrUEjBM7nc6QytSOkCFeuosHqUxGxkQQIDJ3zBo4/UjjSiaB + w3DYDkxeicUzBgCaLdIWNH0po0YqUzuwx3sWL41rQ5XJyFgRBMlSM2gceYxK1A5s2d2wzZl0FV+kMhkZ + K4Ku0kJb4DhwgUrUDnzwncWbh3gzeoMg8V31dgeckwh9k1QE7/6V0XJw9d3HEjiDwlO1GjIy7CBI3mME + zcBwaGhof62GjAw7JDmBLXgGhB/QasjIsGM4fqqcxpCLQ1r5bDPSBMGyyAyeAeATqU2XyUgUPKh/yxJA + bed8dT8jozekq2EJoFaTi8L26n5GRn8QNL8yg6jFvF92olLXMzL6g7vIbAJHtqq2BVSryN3jY+p2RoY7 + CJzP2gKqZTxf3c3IKA4C6GAjoFpDLgALR0ZGnqWuZmT4YWho6CO2AGs4j6x9i+SM9kDSohJUUfcWqYPc + Nc6WBVXqVkZGXEhwEWSyMabspLUEPjQefAlStnW4Dp4L95KBB3UjwwnPeMb/A5hknxz+u4GnAAAAAElF + TkSuQmCC + + + + + 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 + rkJggg== + + + + + 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 + /g9U/tB3US9YHgAAAABJRU5ErkJggg== + + + + + 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 + uneO5+g3AwAAAABJRU5ErkJggg== + + + + + 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 + AAAAAElFTkSuQmCC + + + + + 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 + QmCC + + + + + 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 + Y8xOY6+9fghokNfA1CcF5wAAAABJRU5ErkJggg== + + + + + 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 + + + + 17, 17 + + + 113 + + + + AAABAAEAPDwAAAEAIABIOgAAFgAAACgAAAA8AAAAeAAAAAEAIAAAAAAAAAAAACMuAAAjLgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD6zodC+s6Hm/rOh9b6zof2+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh/b6zofW+s6Hm/rOh0IAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+s6HKfrOh7n6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zoe6+s6HKQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD6zodI+s6H8/rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H9frOh1IAAAAAAAAAAAAA + AAAAAAAAAAAAAPrOh076zof7+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh/z6zodOAAAAAAAA + AAAAAAAA+s6HHPrOh+76zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zofv+s6HHAAA + AAAAAAAA+s6Hp/rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6HpwAA + AAD6zoci+s6H/frOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/+i0c//MjlX/tGw6/6FRJv+WQRn/jjYQ/4ox + DP+KMQz/jjYQ/5VAGP+gUCX/s2o5/8uMVP/ns3L/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/frO + hyL6zod7+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H/+28ef/DgUv/m0kf/4MmBP9/IQD/fyEA/38hAP9/IQD/fyEA/38h + AP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP+CJgT/mkce/8J/Sf/sunj/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h3r6zoe9+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//quHb/tW07/4guCv9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38h + AP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP+HLQn/s2o5/+m2dP/6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h736zofc+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+MuE/8F9SP+ILQr/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/gSQD/5A5E/+gTyT/q18w/7Fn + N/+xZzf/q18w/6BQJf+QORP/giUD/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/4csCP++ekX/9smD//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h+b6zof2+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//lsHD/nEog/38hAP9/IQD/fyEA/38hAP9/IQD/hy0J/6hbLf/Nj1b/57Ny//bIgv/6zof/+s6H//rO + h//6zof/+s6H//rOh//2yYP/57Ry/8+RV/+qXS//iC4K/38hAP9/IQD/fyEA/38hAP9/IQD/mkYd/+Kt + bf/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h/v6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/9OX + XP+ILQr/fyEA/38hAP9/IQD/fyEA/401D/+/e0b/7Lp4//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/7bx5/8F+Sf+ONxH/fyEA/38hAP9/IQD/fyEA/4Yq + B//Qklj/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/yopS/4Aj + Av9/IQD/fyEA/38hAP+BJAP/t3A+//DAfP/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//xwn3/unRB/4MmBP9/IQD/fyEA/38h + AP9/IQD/xoVO//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//Ki1P/fyEA/38h + AP9/IQD/fyEA/5M9Fv/dpWf/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/9+pav+WQRn/fyEA/38h + AP9/IQD/fyEA/8aFTv/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/9SZXv+AIwL/fyEA/38h + AP9/IQD/pFUp//DAfP/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//yw3//qFos/38h + AP9/IQD/fyEA/38iAf/RlFn/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/57Ry/4ctCf9/IQD/fyEA/38h + AP+tYTL/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+c2G/61i + M/9/IQD/fyEA/38hAP+FKgf/5K9v//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//4y4T/m0kf/38hAP9/IQD/fyEA/5pI + Hv/quHb/7r16/+y7eP/su3j/7Lt4/+y7eP/su3j/7Lt4/+y7eP/su3j/7Lt4/+y7eP/su3j/7Lt4/+y7 + eP/su3j/7Lp4//HCff/6zof/+s6H//jLhf/su3j/8cF9//rNhv/6zof/+s6H//rOh//6zof/+s6H//nN + hv+nWSv/fyEA/38hAP9/IQD/mEQb//bJg//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//DgUv/fyEA/38hAP9/IQD/fyEA/4Qo + Bv+GKwj/hSoH/4UqB/+FKgf/hSoH/4UqB/+FKgf/hSoH/4UqB/+FKgf/hSoH/4UqB/+FKgf/hSoH/4Uq + B/+FKgf/hywI/+Cqa//6zof/+s6H/7JoOP+FKgf/iC4K/5dDGv+6dEH/7Lp3//rOh//6zof/+s6H//rO + h//zxYD/lD8X/38hAP9/IQD/fyEA/797Rv/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/+28ef+ILQr/fyEA/38hAP+DJwX/uHE+/4Aj + Av9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38h + AP9/IQD/sWc3//rOh//6zof/3KNm/38hAP9/IQD/fyEA/38hAP9/IQD/iS8L/86QV//6zof/+s6H//rO + h//6zof/4atr/4MmBP9/IQD/fyEA/4UqB//ruHb/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/7dwPv9/IQD/fyEA/38hAP+2bjz/+s6H/8uM + U/9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38h + AP+NNA//8MB8//rOh//0xYD/kjwV/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP/MjlX/+s6H//rO + h//6zof/+s6H/7lzQP9/IQD/fyEA/38hAP+zajn/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/8MB8/4guCv9/IQD/fyEA/4oxDP/wwHz/+s6H//rO + h//GhU7/lD8X/5Q/F/+UPxf/lD8X/5Q/F/+UPxf/lD8X/5Q/F/+UPxf/gSQD/38hAP9/IQD/fyEA/38h + AP/OkFb/+s6H//rOh//RlFr/kjsV/5Q/F/+UPxf/jTQP/38hAP9/IQD/fyEA/38hAP+EKAb/57Ny//rO + h//6zof/+s6H//PEf/+NNQ//fyEA/38hAP+FKgf/7r16//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/x4dP/38hAP9/IQD/fyEA/7x2Q//6zof/+s6H//rO + h//6zof/+cyF//nMhf/5zIX/+cyF//nMhf/5zIX/+cyF//nMhf/irG3/giUD/38hAP9/IQD/fyEA/6BP + JP/6zof/+s6H//rOh//2yYP/+MuF//nMhf/5zIX/88WA/86QVv+ILgr/fyEA/38hAP9/IQD/rmM0//rO + h//6zof/+s6H//rOh//BfUj/fyEA/38hAP9/IQD/w4BK//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/nUsh/38hAP9/IQD/hSkG/+y7eP/6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh/+2bz3/fyEA/38hAP9/IQD/gyYE/+Sv + b//6zof/+s2G//TGgf/6zof/+s6H//rOh//6zof/+s6H//rOh//WnGD/gCMC/38hAP9/IQD/iS8L//LC + fv/6zof/+s6H//rOh//vvnv/hywI/38hAP9/IQD/mUYd//rNhv/6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//sunf/hCgF/38hAP9/IQD/pFUp//rOh//6zof/+MuF/+u5 + d//6zYb/+cyF/9yjZv/vvnv/+s6H//rOh//6zof/+s6H//XHgf+ONhD/fyEA/38hAP9/IQD/uXNA//rO + h//6zof/26Jl/+u4dv/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/mkYd/38hAP9/IQD/fyEA/+Gr + a//6zof/+s6H//rOh//6zof/qFsu/38hAP9/IQD/giYE/+i0c//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//Qk1n/fyEA/38hAP9/IQD/yotT//rOh//6zof/5rJx/484 + Ev/zxYD/wn9J/38hAP+YRBv/9smD//rOh//6zof/+s6H/9KWXP9/IQD/fyEA/38hAP+QORP/9MaB//rO + h//vv3v/smk4//jLhP/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/qVwu/38hAP9/IQD/fyEA/9yj + Zv/6zof/+s6H//rOh//6zof/z5JY/38hAP9/IQD/fyEA/8uMVP/6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh/+4cT7/fyEA/38hAP+AIwL/5K9v//rOh//6zof/98qE/+e0 + cv/6zof/pFUo/38hAP+DJwX/98qE//rOh//6zof/+s6H/6ZXKv9/IQD/fyEA/38hAP/UmF3/+s6H//rO + h/+zajn/v3tG//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/lkEZ/38hAP9/IQD/fyIB/+Ot + bv/6zof/+s6H//rOh//6zof/6LRz/4IlA/9/IQD/fyEA/7NqOf/6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh/+lVin/fyEA/38hAP+MMw7/9MaB//rOh//6zof/+s6H//rO + h//MjVT/v3tG/8uMVP+/e0b/xoVO/+q3df/6zof/67h2/4QoBf9/IQD/fyEA/6ZYK//6zof/+s6H/+Ou + bv+CJQP/5bFw//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//MjVT/fyEA/38hAP9/IQD/jjcR//bJ + g//6zof/+s6H//rOh//6zof/+cyF/5E6FP9/IQD/fyEA/6FQJf/6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh/+YRBv/fyEA/38hAP+bSR//+s6H//TFgP/Zn2L/5rJx/8eG + T//IiFD/+s6H//rOh//6zof/n04j/38hAP/uvnr/xoVO/38hAP9/IQD/hioH/+m2dP/6zof/+s6H/51L + If+TPRb/+s2G//rOh//6zof/9MaB//LDf//yw3//67h2/8F9SP+DJgT/fyEA/38hAP9/IQD/sWc3//PF + gP/yw3//8sN///LDf//yw3//88R//51MIf9/IQD/fyEA/5VAGP/6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh/+PNxH/fyEA/38hAP+oWy3/98mD/5tIH/9/IQD/giUD/8B9 + R//6zof/+s6H//rOh//6zof/05dc/6tfMf/ywn7/l0Ma/38hAP9/IQD/wX1I//rOh//6zof/z5JY/38h + AP+8dkP/+s6H//rOh//tvHn/jzgS/4owDP+KMAz/hCgG/38hAP9/IQD/fyEA/38hAP9/IQD/iC0K/4ow + DP+KMAz/ijAM/4owDP+KMAz/ijAM/4MmBP9/IQD/fyEA/442EP/6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh/+LMQ3/fyEA/38hAP+xaDf/57Ny/38hAP9/IQD/fyEA/8B8 + R//6zof/+s6H//rOh//6zof/+s6H//rOh//gqWr/fyEA/38hAP+VQBj/98mD//rOh//ywn7/jTQP/38h + AP/fqWr/+s6H//rOh//NjlX/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38h + AP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/4sxDf/6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh/+LMQ3/fyEA/38hAP+uYzP/9ceB/5I8Ff9/IQD/gSQC/9uj + Zf/6zof/+s6H//rOh//6zof/+s6H//rOh/+yaDj/fyEA/38iAf/bomX/+s6H//rOh/+zajn/fyEA/5I7 + Ff/4y4T/+s6H//rOh/+mWCv/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38h + AP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/4guCv/6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh/+POBL/fyEA/38hAP+mVyr/+s6H/+28ef/LjFT/36hp//rO + h//6zof/+s6H//rOh//6zof/+s6H//PEf/+KMQz/fyEA/65jNP/6zof/+s6H/9+pav+BJAL/fyEA/7Jo + OP/6zof/+s6H//PFgP+ZRh3/jjcR/443Ef+ONxH/jjcR/443Ef+ONxH/jjcR/443Ef+ONxH/jjcR/443 + Ef+ONxH/jjcR/443Ef+ONxH/jjcR/443Ef+ONxH/jjcR/5xKIP/6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh/+YRBz/fyEA/38hAP+bSB//+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H/8+RV/9/IQD/ijAM/+6+ev/6zof/+MuF/5pIHv9/IQD/fyEA/9Wa + Xv/6zof/+s6H//nMhf/0xoH/9ceC//XHgv/1x4L/9ceC//XHgv/1x4L/9ceC//XHgv/1x4L/9ceC//XH + gv/1x4L/9ceC//XHgv/1x4L/9ceC//XHgv/1x4L/9ceC//bJg//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh/+mVyr/fyEA/38hAP+MMw7/9MWA//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H/6BPJP9/IQD/yYlS//rOh//6zof/x4ZP/38hAP9/IQD/ijEM//PE + f//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh/+5ckD/fyEA/38hAP+AIwL/465u//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/6LRz/4AjAv+aRh3/+c2G//rOh//tvHn/iC4K/38hAP9/IQD/p1ks//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/3aVn/9GUWv/RlVv/0ZVb//HB + ff/6zof/+s6H//rOh//6zof/8sJ+/9GVW//RlVv/0ZRa/+WwcP/6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//RlFr/fyEA/38hAP9/IQD/yYlR//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/vHZD/38hAP/gqWr/+s6H//rOh/+rXzH/fyEA/38hAP9/IQD/zY5V//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/pFUo/38hAP9/IQD/fyEA/9uj + Zf/6zof/+s6H//rOh//6zof/zI5V/38hAP9/IQD/fyEA/8mJUv/6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//su3j/hSkG/38hAP9/IQD/olMn//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//3yoT/izIN/69lNf/6zof/+s6H/9mgY/9/IgH/fyEA/38hAP+EKAb/7bx5//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/mEQb/38hAP9/IQD/fyEA/+Gr + bP/6zof/+s6H//rOh//6zof/plcq/38hAP9/IQD/gyYE/+q3df/6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/n04j/38hAP9/IQD/hCgF/+u4dv/6zof/+s6H//rO + h//6zof/+s6H//rOh//Wm1//iC0K//HBff/6zof/9siC/5VAGP9/IQD/fyEA/38hAP+fTiP/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//Sllv/fyIB/38hAP9/IQD/ijEM//LD + f//6zof/+s6H//rOh//tvHn/hSoH/38hAP9/IQD/m0gf//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/yopS/38hAP9/IQD/fyEA/7lyQP/6zof/+s6H//rO + h//6zof/+s6H//rOh/+mVyr/yYlR//rOh//6zof/v3tG/38hAP9/IQD/fyEA/38hAP/Cf0r/9siC//bI + gv/2yIL/9siC//bIgv/2yIL/9siC//bIgv/2yIL/8MB8/8iHUP+GKgf/fyEA/38hAP9/IQD/sWc3//rO + h//6zof/+s6H//rOh/+9eET/fyEA/38hAP9/IQD/xYRN//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/8sJ+/4owDP9/IQD/fyEA/4kvC//uvnr/+s6H//rO + h//6zof/+s6H/+m2dP+pXS//+c2G//rOh//ptnT/hCgG/38hAP9/IQD/fyEA/38hAP+MMw7/jzgS/484 + Ev+POBL/jzgS/484Ev+POBL/jzgS/484Ev+POBL/iS8L/38hAP9/IQD/fyEA/38hAP+GKwj/6bZ0//rO + h//6zof/+s6H//HBff+LMQ3/fyEA/38hAP+HLQn/7797//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/7t1Qv9/IQD/fyEA/38hAP+xaDf/+s6H//rO + h//6zof/+s6H/8qLU//gqWr/+s6H//rOh/+mVyr/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38h + AP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/4AiAf/RlFn/+s6H//rO + h//6zof/+s6H/7VtO/9/IQD/fyEA/38hAP+2bjz/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/++/e/+KMAz/fyEA/38hAP+AIwL/2qFk//rO + h//6zof/9ceC/9mfYv/6zof/+s6H/9GUWf9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38h + AP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/jTUP/9OYXf/6zof/+s6H//rO + h//6zof/3aVn/4EkA/9/IQD/fyEA/4ctCf/tvHn/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//Hhk//fyEA/38hAP9/IQD/jjcR/+++ + e//6zof/9ceB//bJg//6zof/9MWA/5pGHf+ILgr/iS8L/4kvC/+JLwv/iS8L/4kvC/+JLwv/iS8L/4kv + C/+JLwv/iS8L/4kvC/+JLwv/iS8L/4kvC/+JLwv/jTQP/5xKIP/AfEf/7797//rOh//6zof/+s6H//rO + h//xwX3/kDkT/38hAP9/IQD/fyEA/8OASv/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//5zYb/n04j/38hAP9/IQD/fyEA/59O + I//2yIL/+s6H//rOh//6zof/+MuE//DAfP/ywn7/8sJ+//LCfv/ywn7/8sJ+//LCfv/ywn7/8sJ+//LC + fv/ywn7/8sJ+//LCfv/ywn7/8sJ+//LCfv/ywn7/9MWA//rOh//6zof/+s6H//rOh//6zof/+s6H//fK + hP+iUib/fyEA/38hAP9/IQD/m0kf//jLhP/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/6rh2/4owDP9/IQD/fyEA/38h + AP+lVyr/9siC//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/98mD/6hb + Lf9/IQD/fyEA/38hAP+ILQr/6LRz//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/9ifYv+CJQP/fyEA/38h + AP9/IQD/oE8k/+28ef/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//vvnv/olMn/38h + AP9/IQD/fyEA/4EkAv/Vml7/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//PkVf/gCMC/38h + AP9/IQD/fyEA/484Ev/YnmH/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/9qhZP+ROxT/fyEA/38h + AP9/IQD/fyEA/8uMVP/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/z5FX/4Il + A/9/IQD/fyEA/38hAP9/IgH/smk4/+y6eP/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//tvHn/tWw7/4AjAv9/IQD/fyEA/38h + AP+BJAL/y4xU//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/9ie + Yf+LMg3/fyEA/38hAP9/IQD/fyEA/4owDP+5ckD/6LVz//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/6rd1/7t1Qv+LMQ3/fyEA/38hAP9/IQD/fyEA/4kv + C//Vml7/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof2+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//ptnT/oVAl/38hAP9/IQD/fyEA/38hAP9/IQD/hCgF/6JTJ//Hh0//4qxt//LDf//6zof/+s6H//rO + h//6zof/+s6H//rOh//zxH//461u/8mJUf+kVSj/hSkG/38hAP9/IQD/fyEA/38hAP9/IQD/nk0i/+ez + cv/6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h/v6zofc+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s2G/8aFTv+MMw7/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/4syDf+aRx7/pVYp/6pe + MP+rXzD/pVcq/5pIHv+MMw7/fyIB/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/4oxDP/Egkz/+cyF//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h+b6zoe9+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//uvXr/u3ZC/4wzDv9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38h + AP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP+LMQ3/uXJA/+y7eP/6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h736zod7+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//DAfP/KilL/oVAl/4YrCP9/IQD/fyEA/38hAP9/IQD/fyEA/38h + AP9/IQD/fyEA/38hAP9/IQD/fyEA/38hAP+FKgf/n04j/8iIUP/vv3v/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h3r6zoci+s6H/frOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/+y6eP/Sllv/unRB/6dZLP+ZRh3/kDkT/4wz + Dv+MMw7/kDkT/5lFHP+mWCv/uXJA/9GUWf/ruXf/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H/frO + hyIAAAAA+s6HpvrOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6HpgAA + AAAAAAAA+s6HHPrOh+76zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zofu+s6HHAAA + AAAAAAAAAAAAAPrOh036zof6+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh/z6zodOAAAAAAAA + AAAAAAAAAAAAAAAAAAD6zodI+s6H8/rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H9frOh1EAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+s6HKPrOh7f6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zoe4+s6HKQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD6zodA+s6Hm/rOh9b6zof1+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rOh//6zof/+s6H//rO + h//6zof/+s6H//rOh//6zof/+s6H//rOh/X6zofW+s6Hm/rOh0EAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD8AAAAAAAD8PAAAAAAAADw4AAAAAAAAHDAAAAAAAAAMIAAAAAAAAAQgAAAAAAAABAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACAAAAAAAAAEIAAAAAAAAAQwAAAAAAAADDgAAAAAAAAcPAAAAAAAADw/AAAAAAA + A/A= + + + \ No newline at end of file diff --git a/src/PBAnaly/Module/ImageProcess.cs b/src/PBAnaly/Module/ImageProcess.cs new file mode 100644 index 0000000..31461fd --- /dev/null +++ b/src/PBAnaly/Module/ImageProcess.cs @@ -0,0 +1,166 @@ +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Drawing.Drawing2D; +using System.Drawing; +using AntdUI; +using System.Windows.Forms; +using OpenCvSharp; +using SixLabors.ImageSharp.Advanced; +using System.Runtime.InteropServices; +using Sunny.UI.Win32; + + +namespace PBAnaly.Module +{ + public class DataRecordString + { + public int index { get; set; } + public string max { get; set; } + public string min { get; set; } + public string IOD { get; set; } + public string Count { get; set; } + public string AOD { get; set; } + } + public class DataRecord + { + public int index { get; set; } + public int max { get; set; } + public int min { get; set; } + public int IOD { get; set; } + public int Count { get; set; } + public float AOD { get; set; } + }; + public static class ImageProcess + { + + public static (int[] histogram, int minVal, int maxVal) CalculateHistogram(Image image) + { + int[] histogram = new int[65536]; // 16-bit image has values from 0 to 65535 + int minVal = ushort.MaxValue; + int maxVal = ushort.MinValue; + + // 使用MemoryGroup访问像素数据 + var memoryGroup = image.GetPixelMemoryGroup(); + var o = memoryGroup.ToArray().Max(); + + foreach (var memory in memoryGroup) + { + var span = memory.Span; + foreach (var pixel in span) + { + ushort pixelValue = pixel.PackedValue; + histogram[pixelValue]++; // 增加对应亮度值的计数 + + if (pixelValue < minVal) + minVal = pixelValue; // 更新最小值 + + if (pixelValue > maxVal) + maxVal = pixelValue; // 更新最大值 + } + } + + return (histogram, minVal, maxVal); + } + + public static System.Drawing.Point GetRealImageCoordinates(PictureBox pictureBox, System.Drawing.Point mousePoint) + { + if (pictureBox.Image == null) + return mousePoint; + + System.Drawing.Size imageSize = pictureBox.Image.Size; + System.Drawing.Size boxSize = pictureBox.ClientSize; + + float imageAspectRatio = (float)imageSize.Width / imageSize.Height; + float boxAspectRatio = (float)boxSize.Width / boxSize.Height; + + float scaleFactor = (pictureBox.SizeMode == PictureBoxSizeMode.Zoom) ? + (boxAspectRatio > imageAspectRatio ? (float)boxSize.Height / imageSize.Height : (float)boxSize.Width / imageSize.Width) : + (float)boxSize.Width / imageSize.Width; // StretchImage模式 + + // 图像在PictureBox内居中,因此计算起始偏移 + int imageX = (pictureBox.SizeMode == PictureBoxSizeMode.Zoom && boxAspectRatio > imageAspectRatio) ? + (boxSize.Width - (int)(imageSize.Width * scaleFactor)) / 2 : 0; + int imageY = (pictureBox.SizeMode == PictureBoxSizeMode.Zoom && boxAspectRatio < imageAspectRatio) ? + (boxSize.Height - (int)(imageSize.Height * scaleFactor)) / 2 : 0; + + int realX = (int)((mousePoint.X - imageX) / scaleFactor); + int realY = (int)((mousePoint.Y - imageY) / scaleFactor); + + return new System.Drawing.Point(realX, realY); + } + + public static System.Drawing.Rectangle GetRealImageRectangle(PictureBox pictureBox, System.Drawing.Rectangle mouseRectangle) + { + if (pictureBox.Image == null) + return mouseRectangle; + + // 获得矩形的左上角和右下角的坐标 + System.Drawing.Point topLeft = new System.Drawing.Point(mouseRectangle.Left, mouseRectangle.Top); + System.Drawing.Point bottomRight = new System.Drawing.Point(mouseRectangle.Right, mouseRectangle.Bottom); + + // 转换这些坐标 + System.Drawing.Point realTopLeft = GetRealImageCoordinates(pictureBox, topLeft); + System.Drawing.Point realBottomRight = GetRealImageCoordinates(pictureBox, bottomRight); + + // 计算新的矩形的宽度和高度 + int width = realBottomRight.X - realTopLeft.X; + int height = realBottomRight.Y - realTopLeft.Y; + + return new System.Drawing.Rectangle(realTopLeft.X, realTopLeft.Y, width, height); + } + + // 将真实图像坐标转换为PictureBox控件坐标 + public static System.Drawing.Point ConvertRealToPictureBoxCoordinates(PictureBox pictureBox, System.Drawing.Point realPoint) + { + if (pictureBox.Image == null) + return realPoint; + + System.Drawing.Size imageSize = pictureBox.Image.Size; + System.Drawing.Size boxSize = pictureBox.ClientSize; + + float imageAspectRatio = (float)imageSize.Width / imageSize.Height; + float boxAspectRatio = (float)boxSize.Width / boxSize.Height; + + float scaleFactor = (pictureBox.SizeMode == PictureBoxSizeMode.Zoom) ? + (boxAspectRatio > imageAspectRatio ? (float)boxSize.Height / imageSize.Height : (float)boxSize.Width / imageSize.Width) : + 1f; // 默认为1,这里假设是StretchImage模式 + + int imageX = (pictureBox.SizeMode == PictureBoxSizeMode.Zoom && boxAspectRatio > imageAspectRatio) ? + (boxSize.Width - (int)(imageSize.Width * scaleFactor)) / 2 : 0; + int imageY = (pictureBox.SizeMode == PictureBoxSizeMode.Zoom && boxAspectRatio < imageAspectRatio) ? + (boxSize.Height - (int)(imageSize.Height * scaleFactor)) / 2 : 0; + + int pictureBoxX = (int)(realPoint.X * scaleFactor) + imageX; + int pictureBoxY = (int)(realPoint.Y * scaleFactor) + imageY; + + return new System.Drawing.Point(pictureBoxX, pictureBoxY); + } + + // 将真实图像的矩形坐标转换为PictureBox控件的矩形坐标 + public static System.Drawing.Rectangle ConvertRealToPictureBoxRectangle(PictureBox pictureBox, System.Drawing.Rectangle realRectangle) + { + if (pictureBox.Image == null) + return realRectangle; + + System.Drawing.Point realTopLeft = new System.Drawing.Point(realRectangle.Left, realRectangle.Top); + System.Drawing.Point realBottomRight = new System.Drawing.Point(realRectangle.Right, realRectangle.Bottom); + + System.Drawing.Point picBoxTopLeft = ConvertRealToPictureBoxCoordinates(pictureBox, realTopLeft); + System.Drawing.Point picBoxBottomRight = ConvertRealToPictureBoxCoordinates(pictureBox, realBottomRight); + + return new System.Drawing.Rectangle(picBoxTopLeft.X, picBoxTopLeft.Y, + picBoxBottomRight.X - picBoxTopLeft.X, + picBoxBottomRight.Y - picBoxTopLeft.Y); + } + } + + + + + +} \ No newline at end of file diff --git a/src/PBAnaly/Module/ImageToolMannage.cs b/src/PBAnaly/Module/ImageToolMannage.cs new file mode 100644 index 0000000..8b08fb1 --- /dev/null +++ b/src/PBAnaly/Module/ImageToolMannage.cs @@ -0,0 +1,37 @@ + + +using OpenCvSharp.ImgHash; +using PBAnaly.UI; +using System.Collections.Generic; + +namespace PBAnaly.Module +{ + public static class ImageToolMannage + { + #region 变量 + public static bool lineDisON = false; + public static bool rectON = false; + public static bool linepolygonON = false; + public static bool linewandON = false; + public static bool circleON = false; + public static int color_min = 6000; + public static int color_max = 65534; + public static float alpha = 100; + public static ImagePanel imagePanel { get; set; } + public static ImagePanelUser imagePanelUser { get; set; } + public static ReaLTaiizor.Controls.Panel right_panel { get; set; } + public static int beta = 127; + + public static double pixeltomm = 0.0825; + + public static Dictionary imageDataPath = new Dictionary(); + + public static int RoiIndex = 0; + public static int CircleIndex = 0; + public static int Roi_w = 20; + public static int Roi_h = 20; + public static int Roi_r = 10; + + #endregion + } +} diff --git a/src/PBAnaly/Module/PBAnalyCommMannager.cs b/src/PBAnaly/Module/PBAnalyCommMannager.cs new file mode 100644 index 0000000..04c31f4 --- /dev/null +++ b/src/PBAnaly/Module/PBAnalyCommMannager.cs @@ -0,0 +1,144 @@ +using OpenCvSharp; +using OpenCvSharp.Extensions; +using PBBiologyVC; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PBAnaly.Module +{ + public class PBAnalyCommMannager + { + public static LaneChartForm laneChartForm = null; + public static DataProcessForm processForm = null; + public static List proteinRect = null; + public static List<_band_info> band_info = null; + + //public List land_data; + + //public List ydata; + + //public List xdata; + + //public List> band_point; + + //public List Minfo; + public struct band_infos + { + public float startX; // X作为筛选的必要条件 当鼠标进入x的范围就是进入某一个泳道,在根据y的范围判断是否在这个泳道里 + public float endX; + public float startY; + public float endY; + public List xdata; + public List ydata; + public Scalar color; + public int thick; + public _band_info _Info; + } + + public static bool processcurveAlg() + { + + if (processForm == null) return false; + var image = processForm.getImage; + Mat whiteBackgroundImg = new Mat(); + Scalar meanValue = Cv2.Mean(image); + if (meanValue[0] < 10000) + { + Cv2.BitwiseNot(image, whiteBackgroundImg); + } + else + { + whiteBackgroundImg = image.Clone(); + } + + Mat input_cn1 = new Mat(); + whiteBackgroundImg.ConvertTo(input_cn1, MatType.CV_8U, 0.00390625); + + byte[] byte_image = new byte[input_cn1.Width * input_cn1.Height]; + ushort[] whiteBackgroundImg_image = new ushort[whiteBackgroundImg.Width * whiteBackgroundImg.Height]; + int index = 0; + for (int i = 0; i < input_cn1.Rows; i++) + { + for (int j = 0; j < input_cn1.Cols; j++) + { + byte value = input_cn1.At(i, j); // 使用At方法访问数据 + ushort value1 = whiteBackgroundImg.At(i, j); // 使用At方法访问数据 + byte_image[index] = value; + whiteBackgroundImg_image[index++] = value1; + + } + + } + + PBBiology dd = new PBBiology(); + proteinRect = new List(); + band_info = new List<_band_info>(); + + + unsafe + { + fixed (byte* p = byte_image) + { + proteinRect = dd.getProteinRectVC(p, (ushort)input_cn1.Width, (ushort)input_cn1.Height); + } + + byte[] bytes = util.ConvertUShortArrayToByteArrayComplete(whiteBackgroundImg_image); + + + fixed (byte* p = bytes) + { + dd.getProteinBandsVC(p, 16, (ushort)input_cn1.Width, (ushort)input_cn1.Height, proteinRect, ref band_info); + } + dd.adjustBands(band_info, 10); + dd.molecularWeightResult(ref proteinRect, ref band_info); + + } + Mat mat = new Mat(); + if (input_cn1.Channels() == 1) + { + Cv2.CvtColor(input_cn1, mat, ColorConversionCodes.GRAY2BGR); + } + // 随机数生成器 + Random random = new Random(); + + // 定义多个矩形的位置和大小 + (int x, int y, int width, int height)[] rectangles = { + (100, 150, 200, 100), + (300, 200, 150, 90), + (50, 30, 180, 120), + // 添加更多矩形 + }; + List bands = new List(); + index = 0; + foreach (var m in proteinRect) + { + Scalar color = new Scalar(random.Next(256), random.Next(256), random.Next(256)); // 随机RGB值 + OpenCvSharp.Point rectStart = new OpenCvSharp.Point(m.X, m.Y); + OpenCvSharp.Point rectEnd = new OpenCvSharp.Point(m.X + m.Width, m.Y + m.Height); + band_infos _Infos = new band_infos(); + _Infos.startX = rectStart.X; + _Infos.startY = rectStart.Y; + _Infos.endX = rectEnd.X; + _Infos.endY = rectEnd.Y; + _Infos.color = color; + _Infos.thick = 1; + _Infos._Info = band_info[index++]; + bands.Add(_Infos); + } + processForm.SetBands = bands; + processForm.Draw(); + + if (laneChartForm == null) + laneChartForm = new LaneChartForm(); + laneChartForm.TopMost = true; + laneChartForm.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + laneChartForm.Draw(bands[0]); + laneChartForm.Show(); + return true; + } + } +} diff --git a/src/PBAnaly/Module/util.cs b/src/PBAnaly/Module/util.cs new file mode 100644 index 0000000..6ea274d --- /dev/null +++ b/src/PBAnaly/Module/util.cs @@ -0,0 +1,499 @@ +using OpenCvSharp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Formats.Bmp; +using System.IO; +using System.Drawing; +using Image = SixLabors.ImageSharp.Image; +using System.Net.NetworkInformation; +using System.Management; + + + +namespace PBAnaly.Module +{ + public class util + { + /// + /// 将16bit unshort 拆成2 个8bit + /// + /// + /// + public static byte[] ConvertUShortArrayToByteArrayComplete(ushort[] ushortArray) + { + // 创建一个byte数组,长度是ushort数组的两倍 + byte[] byteArray = new byte[ushortArray.Length * 2]; + + for (int i = 0, j = 0; i < ushortArray.Length; i++, j += 2) + { + // 高位byte + byteArray[j + 1] = (byte)(ushortArray[i] >> 8); + // 低位byte + byteArray[j] = (byte)(ushortArray[i] & 0xFF); + } + + return byteArray; + } + + /// + /// 数据转成mat + /// + /// + /// + /// + /// + /// + public static Mat ConvertByteArrayToMat(byte[] imageData, int width, int height, MatType type) + { + Mat image = new Mat(height, width, type); + if (type == MatType.CV_8UC1) + { + Marshal.Copy(imageData, 0, image.Data, width * height); + } + else if (type == MatType.CV_16UC1) + { + Marshal.Copy(imageData, 0, image.Data, width * height * 2); + } + return image; + } + + public static byte[] TiffTo16BitGrayByteArray(string filePath) + { + using (Image image = Image.Load(filePath)) + { + int width = image.Width; + int height = image.Height; + byte[] pixels = new byte[width * height * sizeof(ushort)]; + + int index = 0; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + ushort pixelValue = image[x, y].PackedValue; + BitConverter.GetBytes(pixelValue).CopyTo(pixels, index); + index += sizeof(ushort); + } + } + + return pixels; + } + } + public static Image LoadTiffAsL16(string filePath) + { + // 加载图像并确保其为16位灰度图像 + Image image = Image.Load(filePath); + return image; + } + public static byte[] ConvertL16ImageToByteArray(Image image) + { + int width = image.Width; + int height = image.Height; + byte[] pixels = new byte[width * height * sizeof(ushort)]; + + int index = 0; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + // 直接访问每个像素的值并转换为 byte[] + ushort pixelValue = image[x, y].PackedValue; + BitConverter.GetBytes(pixelValue).CopyTo(pixels, index); + index += sizeof(ushort); + } + } + + return pixels; + } + + public static Bitmap ConvertL16ToBitmap(Image image) + { + using (var ms = new MemoryStream()) + { + // 保存为 BMP 格式的内存流 + image.Save(ms, new BmpEncoder()); + ms.Position = 0; // 重置流的位置 + return new Bitmap(ms); + } + } + public static Image ConvertByteArrayToL16Image(byte[] byteArray, int width, int height, int channels) + { + // 确保输入参数有效 + if (channels != 1) + { + throw new ArgumentException("通道数必须为1,适用于L16格式。"); + } + + // 创建一个新的Image对象 + Image image = new Image(width, height); + + // 填充图像数据 + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + // 计算在字节数组中的位置 + int pixelIndex = (y * width + x) * channels * sizeof(ushort); + + // 确保byteArray足够大 + if (pixelIndex + sizeof(ushort) > byteArray.Length) + { + throw new ArgumentException("字节数组长度不足以填充图像。"); + } + + // 从字节数组中读取16位灰度值 + ushort pixelValue = BitConverter.ToUInt16(byteArray, pixelIndex); + image[x, y] = new L16(pixelValue); + } + } + + return image; + } + public static Image ConvertL8ToL16Image(Image inputImage) + { + int width = inputImage.Width; + int height = inputImage.Height; + + // 创建一个新的 Image 对象 + Image outputImage = new Image(width, height); + + // 遍历每个像素,将 L8 格式转换为 L16 格式 + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + // 获取 L8 格式的像素值 + byte pixelValueL8 = inputImage[x, y].PackedValue; + + // 将 8 位值扩展为 16 位 + ushort pixelValueL16 = (ushort)(pixelValueL8 << 8); // 例如,简单左移 + + // 设置 L16 图像的像素值 + outputImage[x, y] = new L16(pixelValueL16); + } + } + + return outputImage; + } + public static Image ConvertByteArrayToL8Image(byte[] byteArray, int width, int height, int channels) + { + // 验证通道数至少为1 + if (channels < 1) + { + throw new ArgumentException("通道数必须至少为1。"); + } + + // 创建一个新的 Image 对象 + Image image = new Image(Configuration.Default, width, height); + + // 填充图像数据 + int bytesPerSample = 1; // 每个样本(每通道)1字节 + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int baseIndex = (y * width + x) * channels * bytesPerSample; + if (channels == 1) + { + // 单通道灰度 + byte grayValue = byteArray[baseIndex]; + image[x, y] = new L8(grayValue); + } + else if (channels >= 3) + { + // 三通道RGB,计算加权平均灰度值 + float r = byteArray[baseIndex]; + float g = byteArray[baseIndex + 1]; + float b = byteArray[baseIndex + 2]; + byte gray = (byte)(0.299 * r + 0.587 * g + 0.114 * b); + image[x, y] = new L8(gray); + } + } + } + + return image; + } + + public static Image ConvertByteArrayToL16Image(byte[] byteArray, int width, int height) + { + // 确保输入参数有效 + if (byteArray.Length < width * height) + { + throw new ArgumentException("字节数组长度不足以填充图像。"); + } + + // 创建一个新的 Image 对象 + Image image = new Image(width, height); + + // 填充图像数据 + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + // 获取 8 位的像素值 + byte pixelValueL8 = byteArray[y * width + x]; + + // 将 8 位值扩展为 16 位 + ushort pixelValueL16 = (ushort)(pixelValueL8 << 8); // 或者可以直接设置为 (ushort)pixelValueL8 + + // 设置到 L16 图像 + image[x, y] = new L16(pixelValueL16); + } + } + + return image; + } + + public static Bitmap ConvertL8ImageToBitmap(Image image) + { + using (var ms = new MemoryStream()) + { + // 将 Image 保存到内存流中,格式为 BMP + image.Save(ms, new BmpEncoder()); + ms.Position = 0; // 重置流位置 + + // 使用内存流创建 Bitmap + return new Bitmap(ms); + } + } + + public static Image ConvertByteArrayToRgb24Image(byte[] byteArray, int width, int height, int channels) + { + // 验证通道数必须为3(RGB) + if (channels != 3) + { + throw new ArgumentException("通道数必须为3,适用于RGB彩色图像。"); + } + + // 创建一个新的 Image 对象 + Image image = new Image(width, height); + + // 填充图像数据 + int bytesPerPixel = channels; // 每个像素的字节数为3(R、G、B) + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + // 计算当前像素在字节数组中的起始位置 + int baseIndex = (y * width + x) * bytesPerPixel; + + // 确保数组边界 + if (baseIndex + 2 >= byteArray.Length) + { + throw new ArgumentException("字节数组长度不足以填充图像。"); + } + + // 提取 R、G、B 值 + byte r = byteArray[baseIndex]; + byte g = byteArray[baseIndex + 1]; + byte b = byteArray[baseIndex + 2]; + + // 设置图像像素 + image[x, y] = new Rgb24(r, g, b); + } + } + + return image; + } + + public static Bitmap ConvertRgb24ImageToBitmap(Image image) + { + using (var ms = new MemoryStream()) + { + // 将 Image 保存到内存流中,格式为 BMP + image.Save(ms, new BmpEncoder()); + ms.Position = 0; // 重置流位置 + + // 使用内存流创建 Bitmap + return new Bitmap(ms); + } + } + public static Bitmap ConvertRgba64ImageToBitmap(Image image) + { + // 获取图像的宽度和高度 + int width = image.Width; + int height = image.Height; + + // 创建一个新的 Bitmap 对象 + Bitmap bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + + // 使用锁定的像素数据进行高效复制 + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + // 获取当前像素的 RGBA 值 + Rgba64 pixel = image[x, y]; + + // 将 Rgba64 的 16 位值转换为 8 位值 + byte r = (byte)(pixel.R >> 8); // 右移8位,转换为8位 + byte g = (byte)(pixel.G >> 8); + byte b = (byte)(pixel.B >> 8); + byte a = (byte)(pixel.A >> 8); + + // 设置 Bitmap 中对应像素的颜色 + bitmap.SetPixel(x, y, System.Drawing.Color.FromArgb(a, r, g, b)); + } + } + + return bitmap; + } + public static Image ConvertBgrByteArrayToRgb24Image(byte[] byteArray, int width, int height, int channels) + { + // 验证通道数必须为3(BGR) + if (channels != 3) + { + throw new ArgumentException("通道数必须为3,适用于BGR彩色图像。"); + } + + // 创建一个新的 Image 对象 + Image image = new Image(width, height); + + // 填充图像数据 + int bytesPerPixel = channels; // 每个像素的字节数为3(B、G、R) + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + // 计算当前像素在字节数组中的起始位置 + int baseIndex = (y * width + x) * bytesPerPixel; + + // 确保数组边界 + if (baseIndex + 2 >= byteArray.Length) + { + throw new ArgumentException("字节数组长度不足以填充图像。"); + } + + // 提取 B、G、R 值 + byte b = byteArray[baseIndex]; + byte g = byteArray[baseIndex + 1]; + byte r = byteArray[baseIndex + 2]; + + // 设置图像像素(注意转换为 RGB 顺序) + image[x, y] = new Rgb24(r, g, b); + } + } + + return image; + } + + public static Image ConvertByteArrayToRgba64Image(byte[] byteArray, int width, int height, int channels) + { + // 验证通道数必须为4(RGBA) + if (channels != 4) + { + throw new ArgumentException("通道数必须为4,适用于RGBA彩色图像。"); + } + + // 创建一个新的 Image 对象 + Image image = new Image(width, height); + + // 每个通道的字节数为2(因为是16位) + int bytesPerPixel = channels * 2; // 每个像素的字节数(4通道,每个通道2字节) + + // 填充图像数据 + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + // 计算当前像素在字节数组中的起始位置 + int baseIndex = (y * width + x) * bytesPerPixel; + + // 确保数组边界 + if (baseIndex + 7 >= byteArray.Length) + { + throw new ArgumentException("字节数组长度不足以填充图像。"); + } + + // 提取 R、G、B、A 值(每个通道是16位,即2个字节) + ushort r = (ushort)((byteArray[baseIndex] << 8) | byteArray[baseIndex + 1]); + ushort g = (ushort)((byteArray[baseIndex + 2] << 8) | byteArray[baseIndex + 3]); + ushort b = (ushort)((byteArray[baseIndex + 4] << 8) | byteArray[baseIndex + 5]); + ushort a = (ushort)((byteArray[baseIndex + 6] << 8) | byteArray[baseIndex + 7]); + + // 设置图像像素(RGBA顺序) + image[x, y] = new Rgba64(r, g, b, a); + } + } + + return image; + } + + public static Image ConvertByteArrayToRgba64Image(short[] byteArray, int width, int height, int channels) + { + // 验证通道数必须为4(RGBA) + if (channels != 4) + { + throw new ArgumentException("通道数必须为4,适用于RGBA彩色图像。"); + } + + // 创建一个新的 Image 对象 + Image image = new Image(width, height); + + // 填充图像数据 + int totalPixels = width * height; + + // 填充图像数据 + for (int i = 0; i < totalPixels; i++) + { + // 计算当前像素在字节数组中的起始位置 + int baseIndex = i * channels; + + // 确保数组边界 + if (baseIndex + 3 >= byteArray.Length) + { + throw new ArgumentException("字节数组长度不足以填充图像。"); + } + + // 提取 R、G、B、A 值 + ushort r = (ushort)(byteArray[baseIndex] & 0xFFFF); // 读取 R 通道 + ushort g = (ushort)(byteArray[baseIndex + 1] & 0xFFFF); // 读取 G 通道 + ushort b = (ushort)(byteArray[baseIndex + 2] & 0xFFFF); // 读取 B 通道 + ushort a = (ushort)(byteArray[baseIndex + 3] & 0xFFFF); // 读取 A 通道 + + // 设置图像像素(RGBA顺序) + image[i % width, i / width] = new Rgba64(r, g, b, a); + } + + return image; + } + + #region 读取WMIMac地址 + public static string GetMotherboardSerial() + { + string serialNumber = string.Empty; + try + { + ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_BaseBoard"); + foreach (ManagementObject mo in searcher.Get()) + { + serialNumber = mo["SerialNumber"].ToString(); + break; // 只需一个序列号 + } + } + catch (Exception ex) + { + Console.WriteLine("获取主板序列号时发生错误: " + ex.Message); + } + return serialNumber; + } + #endregion + + public static string GetscientificNotation(float diff) + { + int exponent = (int)Math.Floor(Math.Log10(diff)); + float normalized = (float)(diff / Math.Pow(10, exponent)); + + // 以科学计数法格式化输出 + string scientificNotation = $"{normalized}e{exponent}"; + return scientificNotation ; + } + } +} diff --git a/src/PBAnaly/PBAnaly.csproj b/src/PBAnaly/PBAnaly.csproj new file mode 100644 index 0000000..df0ce24 --- /dev/null +++ b/src/PBAnaly/PBAnaly.csproj @@ -0,0 +1,407 @@ + + + + + Debug + AnyCPU + {B9CEF793-3D50-48A7-8B1A-3F121ECABE12} + WinExe + PBAnaly + PBAnaly + v4.8 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + true + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + false + + + GS-Analy.ico + + + + + + + + + + + + + + + + + + + + + Form + + + DataProcessForm.cs + + + Form + + + LaneChartForm.cs + + + Form + + + LogForm.cs + + + Form + + + LoginForm.cs + + + Form + + + MainForm.cs + + + + + + + + + + Form + + + SettingForm.cs + + + Form + + + SignInForm.cs + + + Form + + + AnalyzeDataForm.cs + + + UserControl + + + colorbarControl.cs + + + Form + + + ImagePanel.cs + + + UserControl + + + ImagePanelUser.cs + + + Form + + + ImageToolPaletteForm.cs + + + Component + + + RowMergeView.cs + + + DataProcessForm.cs + + + Form + + + testAlgForm.cs + + + LaneChartForm.cs + + + LogForm.cs + + + LoginForm.cs + + + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingForm.cs + + + SignInForm.cs + + + testAlgForm.cs + + + AnalyzeDataForm.cs + + + colorbarControl.cs + + + ImagePanel.cs + + + ImagePanelUser.cs + + + ImageToolPaletteForm.cs + + + RowMergeView.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + 1.6.14 + + + 24.10.0 + + + 0.2.1 + + + 2.3.1 + + + 1.4.0 + + + 8.0.2 + + + 8.0.2 + + + 1.34.2 + + + 13.0.3 + + + 4.10.0.20240616 + + + 4.10.0.20240616 + + + 4.10.0.20240616 + + + 3.8.0.7 + + + 5.0.43 + + + 5.0.43 + + + 2.1.9 + + + 3.7.0 + + + 8.0.1 + + + 6.0.1 + + + 8.0.0 + + + + + {c1dd8a06-7351-4c8d-bd7f-b2be76bb3903} + PBBiologyVC + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/PBAnaly/Program.cs b/src/PBAnaly/Program.cs new file mode 100644 index 0000000..5612374 --- /dev/null +++ b/src/PBAnaly/Program.cs @@ -0,0 +1,82 @@ +using System; +using System.Threading; +using System.IO; +using System.Windows.Forms; +using PBAnaly.Module; +namespace PBAnaly +{ + public static class Global + { + public static String mDataDirUp = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + public static String mDataParent = Directory.GetParent(mDataDirUp).FullName; + public static String mDataUser = mDataParent + "\\PBAnaly\\UserData\\"; + + //public static String mDataDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\TYRAFOS\\data\\Blood\\"; + + } + + public enum Autholity + { + admin, Normal, Visitor + } + + public class UserInfo + { + //0: Admin //1: Normal User //2 :Visitor + public Autholity autholity{ get; set; } + public string UserID { get; set; } + public string E_Mail { get; set; } + public string Password { get; set; } + } + + public class Log + { + public string UserID { get; set; } + public string ITEM { get; set; } + public string Description { get; set; } + public string Time { get; set; } + } + + internal static class Program + { + private static Mutex mutex; + /// + /// 应用程序的主入口点。 + /// + [STAThread] + static void Main() + { + + + const string appName = "PBAnaly"; + bool createdNew; + + mutex = new Mutex(true, appName, out createdNew); + + // 如果已经有一个实例在运行,退出程序 + if (!createdNew) + { + MessageBox.Show("应用程序已经在运行。", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } +#if true + string macAddress =util.GetMotherboardSerial(); + if (macAddress == "PM00P0209N000037" || macAddress == "07D4822_M81D023244" || macAddress == "YQ1711233HY01423" || macAddress == "S312NXCV0056AZMB" || macAddress == "PM82L0235P000452"|| macAddress == "MP2M55J0" || macAddress == "S936NXCV000SJ2MB"|| macAddress == "S730NXCV009371MB") + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + var login = new LoginForm(); + login.StartPosition = FormStartPosition.CenterScreen; + Application.Run(login); + + } + else + { + MessageBox.Show("你没有权限"); + return; + } +#endif + + } + } +} diff --git a/src/PBAnaly/Properties/AssemblyInfo.cs b/src/PBAnaly/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..458c2bd --- /dev/null +++ b/src/PBAnaly/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("BioProject1")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("BioProject1")] +[assembly: AssemblyCopyright("Copyright © 2024")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("b9cef793-3d50-48a7-8b1a-3f121ecabe12")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/PBAnaly/Properties/Resources.Designer.cs b/src/PBAnaly/Properties/Resources.Designer.cs new file mode 100644 index 0000000..2727968 --- /dev/null +++ b/src/PBAnaly/Properties/Resources.Designer.cs @@ -0,0 +1,623 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace PBAnaly.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PBAnaly.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap _10矩形 { + get { + object obj = ResourceManager.GetObject("10矩形", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Black_Blue_0 { + get { + object obj = ResourceManager.GetObject("Black_Blue_0", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Black_Blue_1 { + get { + object obj = ResourceManager.GetObject("Black_Blue_1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Black_Green_0 { + get { + object obj = ResourceManager.GetObject("Black_Green_0", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Black_Green_1 { + get { + object obj = ResourceManager.GetObject("Black_Green_1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Black_Red_0 { + get { + object obj = ResourceManager.GetObject("Black_Red_0", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Black_Red_1 { + get { + object obj = ResourceManager.GetObject("Black_Red_1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Black_SDS_0 { + get { + object obj = ResourceManager.GetObject("Black_SDS_0", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Black_SDS_1 { + get { + object obj = ResourceManager.GetObject("Black_SDS_1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Black_Yley_0 { + get { + object obj = ResourceManager.GetObject("Black_Yley_0", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Black_Yley_1 { + get { + object obj = ResourceManager.GetObject("Black_Yley_1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap C { + get { + object obj = ResourceManager.GetObject("C", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap EtBr_0 { + get { + object obj = ResourceManager.GetObject("EtBr_0", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap EtBr_1 { + get { + object obj = ResourceManager.GetObject("EtBr_1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Gray { + get { + object obj = ResourceManager.GetObject("Gray", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Pseudo_0 { + get { + object obj = ResourceManager.GetObject("Pseudo_0", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Pseudo_1 { + get { + object obj = ResourceManager.GetObject("Pseudo_1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap roi_select { + get { + object obj = ResourceManager.GetObject("roi-select", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap YellowHot_0 { + get { + object obj = ResourceManager.GetObject("YellowHot_0", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap YellowHot_1 { + get { + object obj = ResourceManager.GetObject("YellowHot_1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap yto_icon_X_transit_time { + get { + object obj = ResourceManager.GetObject("yto-icon-X-transit_time", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap zoom_in { + get { + object obj = ResourceManager.GetObject("zoom-in", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap zoom_out { + get { + object obj = ResourceManager.GetObject("zoom-out", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 主页面_图像编辑_正反片 { + get { + object obj = ResourceManager.GetObject("主页面-图像编辑-正反片", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 京仪科技定稿_画板_1_副本2 { + get { + object obj = ResourceManager.GetObject("京仪科技定稿_画板 1 副本2", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 保存 { + get { + object obj = ResourceManager.GetObject("保存", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 保存1 { + get { + object obj = ResourceManager.GetObject("保存1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 保存图片 { + get { + object obj = ResourceManager.GetObject("保存图片", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 全屏 { + get { + object obj = ResourceManager.GetObject("全屏", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 分析 { + get { + object obj = ResourceManager.GetObject("分析", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 前台 { + get { + object obj = ResourceManager.GetObject("前台", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 图片管理 { + get { + object obj = ResourceManager.GetObject("图片管理", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 圆形 { + get { + object obj = ResourceManager.GetObject("圆形", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 圆形1 { + get { + object obj = ResourceManager.GetObject("圆形1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 圖片_20240731174523 { + get { + object obj = ResourceManager.GetObject("圖片_20240731174523", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 執行日誌紀錄 { + get { + object obj = ResourceManager.GetObject("執行日誌紀錄", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 壁纸 { + get { + object obj = ResourceManager.GetObject("壁纸", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 導出 { + get { + object obj = ResourceManager.GetObject("導出", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 控制窗口 { + get { + object obj = ResourceManager.GetObject("控制窗口", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 放大 { + get { + object obj = ResourceManager.GetObject("放大", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 波形图 { + get { + object obj = ResourceManager.GetObject("波形图", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 波形设置_未选中 { + get { + object obj = ResourceManager.GetObject("波形设置-未选中", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 窗口最大化_操作_jurassic { + get { + object obj = ResourceManager.GetObject("窗口最大化_操作_jurassic", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 线段 { + get { + object obj = ResourceManager.GetObject("线段", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 线段__1_ { + get { + object obj = ResourceManager.GetObject("线段 (1)", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 缩小 { + get { + object obj = ResourceManager.GetObject("缩小", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 胶原蛋白 { + get { + object obj = ResourceManager.GetObject("胶原蛋白", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 蛋白质_01 { + get { + object obj = ResourceManager.GetObject("蛋白质-01", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 计数器 { + get { + object obj = ResourceManager.GetObject("计数器", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 返回前台 { + get { + object obj = ResourceManager.GetObject("返回前台", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 重组蛋白_CAR_T靶点蛋白 { + get { + object obj = ResourceManager.GetObject("重组蛋白-CAR-T靶点蛋白", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 重置 { + get { + object obj = ResourceManager.GetObject("重置", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 风控 { + get { + object obj = ResourceManager.GetObject("风控", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 饼干 { + get { + object obj = ResourceManager.GetObject("饼干", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 魔术棒_魔法_魔术_一键 { + get { + object obj = ResourceManager.GetObject("魔术棒,魔法,魔术,一键", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap 黑白平衡 { + get { + object obj = ResourceManager.GetObject("黑白平衡", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/src/PBAnaly/Properties/Resources.resx b/src/PBAnaly/Properties/Resources.resx new file mode 100644 index 0000000..f5f6e82 --- /dev/null +++ b/src/PBAnaly/Properties/Resources.resx @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\Black_Blue_0.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Black_Yley_1.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\计数器.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\返回前台.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\yto-icon-X-transit_time.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\EtBr_1.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\保存图片.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\线段.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\饼干.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Black_Green_1.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Black_Red_1.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\保存.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\重组蛋白-CAR-T靶点蛋白.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\全屏.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\胶原蛋白.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\波形设置-未选中.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Black_Blue_1.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\zoom-in.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\保存.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\圖片_20240731174523.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\重置.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Black_Red_0.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\京仪科技定稿_画板 1 副本2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\zoom-out.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\roi-select.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\风控.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\分析.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\控制窗口.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Black_SDS_0.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\EtBr_0.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Black_Yley_0.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\窗口最大化_操作_jurassic.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\YellowHot_0.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Pseudo_0.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\C.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\图片管理.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\圆形.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\圆形.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\主页面-图像编辑-正反片.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\缩小.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\黑白平衡.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\導出.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Pseudo_1.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Gray.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\10矩形.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\放大.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Black_Green_0.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\YellowHot_1.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\蛋白质-01.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\壁纸.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\執行日誌紀錄.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Black_SDS_1.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\前台.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\波形图.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\魔术棒,魔法,魔术,一键.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\线段 (1).png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/src/PBAnaly/Properties/Settings.Designer.cs b/src/PBAnaly/Properties/Settings.Designer.cs new file mode 100644 index 0000000..ab13358 --- /dev/null +++ b/src/PBAnaly/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace PBAnaly.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/src/PBAnaly/Properties/Settings.settings b/src/PBAnaly/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/src/PBAnaly/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/PBAnaly/Read_Write_Log.cs b/src/PBAnaly/Read_Write_Log.cs new file mode 100644 index 0000000..cd3f712 --- /dev/null +++ b/src/PBAnaly/Read_Write_Log.cs @@ -0,0 +1,86 @@ +using Microsoft.VisualBasic.FileIO; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PBAnaly +{ + public class Read_Write_Log + { + public Read_Write_Log() + { + + } + + public string LogFile = Global.mDataUser + "Log.csv"; + + public List ReadCsv(string FilePath) + { + List returnInfo = new List(); + + using (TextFieldParser parser = new TextFieldParser(FilePath)) + { + parser.TextFieldType = FieldType.Delimited; + parser.SetDelimiters(","); + // Read and parse each line of the CSV file + try + { + while (!parser.EndOfData) + { + string[] fields = parser.ReadFields(); + int count = 0; + string UserId = ""; + string Item = ""; + string Description = ""; + string Time = ""; + foreach (var item in fields) + { + if ((count % 4) == 0) + { + UserId = item; + } + else if ((count % 4) == 1) + { + Item = item; + } + else if ((count % 4) == 2) + { + Description = item; + } + else + { + Time = item; + returnInfo.Add(new Log() { UserID = UserId, ITEM = Item, Description = Description, Time = Time}); + } + + count++; + } + } + parser.Close(); + return returnInfo; + } + catch + { + return null; + } + } + } + + public void WriteCsv(string FilePath, List LogInfos) + { + using (var file = new StreamWriter(FilePath)) + { + foreach (var item in LogInfos) + { + file.WriteLineAsync($"{item.UserID},{item.ITEM},{item.Description},{item.Time}"); + } + + file.Close(); + } + } + + } +} diff --git a/src/PBAnaly/Resources/10矩形.png b/src/PBAnaly/Resources/10矩形.png new file mode 100644 index 0000000..52ae632 Binary files /dev/null and b/src/PBAnaly/Resources/10矩形.png differ diff --git a/src/PBAnaly/Resources/Black_Blue_0.bmp b/src/PBAnaly/Resources/Black_Blue_0.bmp new file mode 100644 index 0000000..3adf6a0 Binary files /dev/null and b/src/PBAnaly/Resources/Black_Blue_0.bmp differ diff --git a/src/PBAnaly/Resources/Black_Blue_1.bmp b/src/PBAnaly/Resources/Black_Blue_1.bmp new file mode 100644 index 0000000..9e86549 Binary files /dev/null and b/src/PBAnaly/Resources/Black_Blue_1.bmp differ diff --git a/src/PBAnaly/Resources/Black_Green_0.bmp b/src/PBAnaly/Resources/Black_Green_0.bmp new file mode 100644 index 0000000..1dd858f Binary files /dev/null and b/src/PBAnaly/Resources/Black_Green_0.bmp differ diff --git a/src/PBAnaly/Resources/Black_Green_1.bmp b/src/PBAnaly/Resources/Black_Green_1.bmp new file mode 100644 index 0000000..7eb8cbd Binary files /dev/null and b/src/PBAnaly/Resources/Black_Green_1.bmp differ diff --git a/src/PBAnaly/Resources/Black_Red_0.bmp b/src/PBAnaly/Resources/Black_Red_0.bmp new file mode 100644 index 0000000..dbc354b Binary files /dev/null and b/src/PBAnaly/Resources/Black_Red_0.bmp differ diff --git a/src/PBAnaly/Resources/Black_Red_1.bmp b/src/PBAnaly/Resources/Black_Red_1.bmp new file mode 100644 index 0000000..45135e3 Binary files /dev/null and b/src/PBAnaly/Resources/Black_Red_1.bmp differ diff --git a/src/PBAnaly/Resources/Black_SDS_0.bmp b/src/PBAnaly/Resources/Black_SDS_0.bmp new file mode 100644 index 0000000..0e52261 Binary files /dev/null and b/src/PBAnaly/Resources/Black_SDS_0.bmp differ diff --git a/src/PBAnaly/Resources/Black_SDS_1.bmp b/src/PBAnaly/Resources/Black_SDS_1.bmp new file mode 100644 index 0000000..3dfb015 Binary files /dev/null and b/src/PBAnaly/Resources/Black_SDS_1.bmp differ diff --git a/src/PBAnaly/Resources/Black_Yley_0.bmp b/src/PBAnaly/Resources/Black_Yley_0.bmp new file mode 100644 index 0000000..f6c2263 Binary files /dev/null and b/src/PBAnaly/Resources/Black_Yley_0.bmp differ diff --git a/src/PBAnaly/Resources/Black_Yley_1.bmp b/src/PBAnaly/Resources/Black_Yley_1.bmp new file mode 100644 index 0000000..c48fab1 Binary files /dev/null and b/src/PBAnaly/Resources/Black_Yley_1.bmp differ diff --git a/src/PBAnaly/Resources/C.png b/src/PBAnaly/Resources/C.png new file mode 100644 index 0000000..ad8400a Binary files /dev/null and b/src/PBAnaly/Resources/C.png differ diff --git a/src/PBAnaly/Resources/EtBr_0.bmp b/src/PBAnaly/Resources/EtBr_0.bmp new file mode 100644 index 0000000..1213431 Binary files /dev/null and b/src/PBAnaly/Resources/EtBr_0.bmp differ diff --git a/src/PBAnaly/Resources/EtBr_1.bmp b/src/PBAnaly/Resources/EtBr_1.bmp new file mode 100644 index 0000000..0ab3b12 Binary files /dev/null and b/src/PBAnaly/Resources/EtBr_1.bmp differ diff --git a/src/PBAnaly/Resources/GS-Analy.ico b/src/PBAnaly/Resources/GS-Analy.ico new file mode 100644 index 0000000..0b62269 Binary files /dev/null and b/src/PBAnaly/Resources/GS-Analy.ico differ diff --git a/src/PBAnaly/Resources/Gray.png b/src/PBAnaly/Resources/Gray.png new file mode 100644 index 0000000..2068a50 Binary files /dev/null and b/src/PBAnaly/Resources/Gray.png differ diff --git a/src/PBAnaly/Resources/Pseudo_0.bmp b/src/PBAnaly/Resources/Pseudo_0.bmp new file mode 100644 index 0000000..10d72e9 Binary files /dev/null and b/src/PBAnaly/Resources/Pseudo_0.bmp differ diff --git a/src/PBAnaly/Resources/Pseudo_1.bmp b/src/PBAnaly/Resources/Pseudo_1.bmp new file mode 100644 index 0000000..1f3b05f Binary files /dev/null and b/src/PBAnaly/Resources/Pseudo_1.bmp differ diff --git a/src/PBAnaly/Resources/YellowHot_0.bmp b/src/PBAnaly/Resources/YellowHot_0.bmp new file mode 100644 index 0000000..df9c6b1 Binary files /dev/null and b/src/PBAnaly/Resources/YellowHot_0.bmp differ diff --git a/src/PBAnaly/Resources/YellowHot_1.bmp b/src/PBAnaly/Resources/YellowHot_1.bmp new file mode 100644 index 0000000..2efa4ce Binary files /dev/null and b/src/PBAnaly/Resources/YellowHot_1.bmp differ diff --git a/src/PBAnaly/Resources/load.png b/src/PBAnaly/Resources/load.png new file mode 100644 index 0000000..3fce828 Binary files /dev/null and b/src/PBAnaly/Resources/load.png differ diff --git a/src/PBAnaly/Resources/roi-select.png b/src/PBAnaly/Resources/roi-select.png new file mode 100644 index 0000000..27eb7f8 Binary files /dev/null and b/src/PBAnaly/Resources/roi-select.png differ diff --git a/src/PBAnaly/Resources/yto-icon-X-transit_time.png b/src/PBAnaly/Resources/yto-icon-X-transit_time.png new file mode 100644 index 0000000..8ddfe2c Binary files /dev/null and b/src/PBAnaly/Resources/yto-icon-X-transit_time.png differ diff --git a/src/PBAnaly/Resources/zoom-in.png b/src/PBAnaly/Resources/zoom-in.png new file mode 100644 index 0000000..e311db5 Binary files /dev/null and b/src/PBAnaly/Resources/zoom-in.png differ diff --git a/src/PBAnaly/Resources/zoom-out.png b/src/PBAnaly/Resources/zoom-out.png new file mode 100644 index 0000000..246a811 Binary files /dev/null and b/src/PBAnaly/Resources/zoom-out.png differ diff --git a/src/PBAnaly/Resources/主页面-图像编辑-正反片.png b/src/PBAnaly/Resources/主页面-图像编辑-正反片.png new file mode 100644 index 0000000..e49095d Binary files /dev/null and b/src/PBAnaly/Resources/主页面-图像编辑-正反片.png differ diff --git a/src/PBAnaly/Resources/京仪科技定稿_画板 1 副本2.png b/src/PBAnaly/Resources/京仪科技定稿_画板 1 副本2.png new file mode 100644 index 0000000..6277971 Binary files /dev/null and b/src/PBAnaly/Resources/京仪科技定稿_画板 1 副本2.png differ diff --git a/src/PBAnaly/Resources/保存.png b/src/PBAnaly/Resources/保存.png new file mode 100644 index 0000000..f6ae5cf Binary files /dev/null and b/src/PBAnaly/Resources/保存.png differ diff --git a/src/PBAnaly/Resources/保存图片.png b/src/PBAnaly/Resources/保存图片.png new file mode 100644 index 0000000..da182a3 Binary files /dev/null and b/src/PBAnaly/Resources/保存图片.png differ diff --git a/src/PBAnaly/Resources/全屏.png b/src/PBAnaly/Resources/全屏.png new file mode 100644 index 0000000..b734158 Binary files /dev/null and b/src/PBAnaly/Resources/全屏.png differ diff --git a/src/PBAnaly/Resources/分析.png b/src/PBAnaly/Resources/分析.png new file mode 100644 index 0000000..aae94e4 Binary files /dev/null and b/src/PBAnaly/Resources/分析.png differ diff --git a/src/PBAnaly/Resources/前台.png b/src/PBAnaly/Resources/前台.png new file mode 100644 index 0000000..9bb055f Binary files /dev/null and b/src/PBAnaly/Resources/前台.png differ diff --git a/src/PBAnaly/Resources/图片管理.png b/src/PBAnaly/Resources/图片管理.png new file mode 100644 index 0000000..a1c25f6 Binary files /dev/null and b/src/PBAnaly/Resources/图片管理.png differ diff --git a/src/PBAnaly/Resources/圆形.png b/src/PBAnaly/Resources/圆形.png new file mode 100644 index 0000000..d121180 Binary files /dev/null and b/src/PBAnaly/Resources/圆形.png differ diff --git a/src/PBAnaly/Resources/圖片_20240731174523.jpg b/src/PBAnaly/Resources/圖片_20240731174523.jpg new file mode 100644 index 0000000..5cb9081 Binary files /dev/null and b/src/PBAnaly/Resources/圖片_20240731174523.jpg differ diff --git a/src/PBAnaly/Resources/執行日誌紀錄.png b/src/PBAnaly/Resources/執行日誌紀錄.png new file mode 100644 index 0000000..42a9206 Binary files /dev/null and b/src/PBAnaly/Resources/執行日誌紀錄.png differ diff --git a/src/PBAnaly/Resources/壁纸.png b/src/PBAnaly/Resources/壁纸.png new file mode 100644 index 0000000..a094b2b Binary files /dev/null and b/src/PBAnaly/Resources/壁纸.png differ diff --git a/src/PBAnaly/Resources/導出.png b/src/PBAnaly/Resources/導出.png new file mode 100644 index 0000000..6c16eab Binary files /dev/null and b/src/PBAnaly/Resources/導出.png differ diff --git a/src/PBAnaly/Resources/微信图片_20241104230443.jpg b/src/PBAnaly/Resources/微信图片_20241104230443.jpg new file mode 100644 index 0000000..5cb9081 Binary files /dev/null and b/src/PBAnaly/Resources/微信图片_20241104230443.jpg differ diff --git a/src/PBAnaly/Resources/控制窗口.png b/src/PBAnaly/Resources/控制窗口.png new file mode 100644 index 0000000..31e94da Binary files /dev/null and b/src/PBAnaly/Resources/控制窗口.png differ diff --git a/src/PBAnaly/Resources/放大.png b/src/PBAnaly/Resources/放大.png new file mode 100644 index 0000000..8d53d33 Binary files /dev/null and b/src/PBAnaly/Resources/放大.png differ diff --git a/src/PBAnaly/Resources/波形图.png b/src/PBAnaly/Resources/波形图.png new file mode 100644 index 0000000..100e02f Binary files /dev/null and b/src/PBAnaly/Resources/波形图.png differ diff --git a/src/PBAnaly/Resources/波形设置-未选中.png b/src/PBAnaly/Resources/波形设置-未选中.png new file mode 100644 index 0000000..f3a1282 Binary files /dev/null and b/src/PBAnaly/Resources/波形设置-未选中.png differ diff --git a/src/PBAnaly/Resources/窗口最大化_操作_jurassic.png b/src/PBAnaly/Resources/窗口最大化_操作_jurassic.png new file mode 100644 index 0000000..23780f7 Binary files /dev/null and b/src/PBAnaly/Resources/窗口最大化_操作_jurassic.png differ diff --git a/src/PBAnaly/Resources/线段 (1).png b/src/PBAnaly/Resources/线段 (1).png new file mode 100644 index 0000000..a8c1aa3 Binary files /dev/null and b/src/PBAnaly/Resources/线段 (1).png differ diff --git a/src/PBAnaly/Resources/线段.png b/src/PBAnaly/Resources/线段.png new file mode 100644 index 0000000..60851ee Binary files /dev/null and b/src/PBAnaly/Resources/线段.png differ diff --git a/src/PBAnaly/Resources/缩小.png b/src/PBAnaly/Resources/缩小.png new file mode 100644 index 0000000..213d136 Binary files /dev/null and b/src/PBAnaly/Resources/缩小.png differ diff --git a/src/PBAnaly/Resources/胶原蛋白.png b/src/PBAnaly/Resources/胶原蛋白.png new file mode 100644 index 0000000..f103bcb Binary files /dev/null and b/src/PBAnaly/Resources/胶原蛋白.png differ diff --git a/src/PBAnaly/Resources/蛋白质-01.png b/src/PBAnaly/Resources/蛋白质-01.png new file mode 100644 index 0000000..4c2ba09 Binary files /dev/null and b/src/PBAnaly/Resources/蛋白质-01.png differ diff --git a/src/PBAnaly/Resources/计数器.png b/src/PBAnaly/Resources/计数器.png new file mode 100644 index 0000000..6f1099f Binary files /dev/null and b/src/PBAnaly/Resources/计数器.png differ diff --git a/src/PBAnaly/Resources/返回前台.png b/src/PBAnaly/Resources/返回前台.png new file mode 100644 index 0000000..d5db2f3 Binary files /dev/null and b/src/PBAnaly/Resources/返回前台.png differ diff --git a/src/PBAnaly/Resources/重组蛋白-CAR-T靶点蛋白.png b/src/PBAnaly/Resources/重组蛋白-CAR-T靶点蛋白.png new file mode 100644 index 0000000..9548dee Binary files /dev/null and b/src/PBAnaly/Resources/重组蛋白-CAR-T靶点蛋白.png differ diff --git a/src/PBAnaly/Resources/重置.png b/src/PBAnaly/Resources/重置.png new file mode 100644 index 0000000..dfc655d Binary files /dev/null and b/src/PBAnaly/Resources/重置.png differ diff --git a/src/PBAnaly/Resources/风控.png b/src/PBAnaly/Resources/风控.png new file mode 100644 index 0000000..7226822 Binary files /dev/null and b/src/PBAnaly/Resources/风控.png differ diff --git a/src/PBAnaly/Resources/饼干.png b/src/PBAnaly/Resources/饼干.png new file mode 100644 index 0000000..af3f516 Binary files /dev/null and b/src/PBAnaly/Resources/饼干.png differ diff --git a/src/PBAnaly/Resources/魔术棒,魔法,魔术,一键.png b/src/PBAnaly/Resources/魔术棒,魔法,魔术,一键.png new file mode 100644 index 0000000..22acb86 Binary files /dev/null and b/src/PBAnaly/Resources/魔术棒,魔法,魔术,一键.png differ diff --git a/src/PBAnaly/Resources/黑白平衡.png b/src/PBAnaly/Resources/黑白平衡.png new file mode 100644 index 0000000..fb65f20 Binary files /dev/null and b/src/PBAnaly/Resources/黑白平衡.png differ diff --git a/src/PBAnaly/SettingForm.Designer.cs b/src/PBAnaly/SettingForm.Designer.cs new file mode 100644 index 0000000..24cd11f --- /dev/null +++ b/src/PBAnaly/SettingForm.Designer.cs @@ -0,0 +1,80 @@ +namespace PBAnaly +{ + partial class SettingForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.panel1 = new System.Windows.Forms.Panel(); + this.materialSwitch_UI = new MaterialSkin.Controls.MaterialSwitch(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.Controls.Add(this.materialSwitch_UI); + this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel1.Location = new System.Drawing.Point(3, 64); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(421, 232); + this.panel1.TabIndex = 0; + // + // materialSwitch_UI + // + this.materialSwitch_UI.AutoSize = true; + this.materialSwitch_UI.Depth = 0; + this.materialSwitch_UI.Location = new System.Drawing.Point(11, 17); + this.materialSwitch_UI.Margin = new System.Windows.Forms.Padding(0); + this.materialSwitch_UI.MouseLocation = new System.Drawing.Point(-1, -1); + this.materialSwitch_UI.MouseState = MaterialSkin.MouseState.HOVER; + this.materialSwitch_UI.Name = "materialSwitch_UI"; + this.materialSwitch_UI.Ripple = true; + this.materialSwitch_UI.Size = new System.Drawing.Size(195, 37); + this.materialSwitch_UI.TabIndex = 12; + this.materialSwitch_UI.Text = "Dark / Light Theme"; + this.materialSwitch_UI.UseVisualStyleBackColor = true; + this.materialSwitch_UI.CheckedChanged += new System.EventHandler(this.materialSwitch_UI_CheckedChanged); + // + // SettingForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(427, 299); + this.Controls.Add(this.panel1); + this.Name = "SettingForm"; + this.Text = "Setting"; + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private MaterialSkin.Controls.MaterialSwitch materialSwitch_UI; + } +} \ No newline at end of file diff --git a/src/PBAnaly/SettingForm.cs b/src/PBAnaly/SettingForm.cs new file mode 100644 index 0000000..7a34bce --- /dev/null +++ b/src/PBAnaly/SettingForm.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using MaterialSkin; +using MaterialSkin.Controls; + +namespace PBAnaly +{ + public partial class SettingForm : MaterialForm + { + public SettingForm(MaterialSkinManager materialSkinManager) + { + InitializeComponent(); + UIInit(); + Inn_materialSkinManager = materialSkinManager; + } + + public MaterialSkinManager Inn_materialSkinManager; + + public void UIInit() + { + //this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true); + //Inn_materialSkinManager = MaterialSkinManager.Instance; // 初始化 MaterialSkinManager 实例 + //Inn_materialSkinManager.AddFormToManage(this); // 将要应用 Material Design 的窗体添加到管理列表中 + //Inn_materialSkinManager.Theme = MaterialSkinManager.Themes.DARK; // Theme 属性用来设置整体的主题 + //Inn_materialSkinManager.ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.Cyan700, TextShade.WHITE); // ColorScheme 属性来设置配色方案 + } + + private void materialSwitch_UI_CheckedChanged(object sender, EventArgs e) + { + if (materialSwitch_UI.Checked == true) + { + Inn_materialSkinManager.Theme = MaterialSkinManager.Themes.LIGHT; // Theme 属性用来设置整体的主题 + Inn_materialSkinManager.ColorScheme = new ColorScheme(Primary.Purple900, Primary.Purple800, Primary.BlueGrey300, Accent.Purple700, TextShade.WHITE); // ColorScheme 属性来设置配色方案 + } + else + { + Inn_materialSkinManager.Theme = MaterialSkinManager.Themes.DARK; // Theme 属性用来设置整体的主题 + Inn_materialSkinManager.ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.Indigo700, TextShade.WHITE); // ColorScheme 属性来设置配色方案 + } + } + } +} diff --git a/src/PBAnaly/SettingForm.resx b/src/PBAnaly/SettingForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/src/PBAnaly/SettingForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/PBAnaly/SignInForm.Designer.cs b/src/PBAnaly/SignInForm.Designer.cs new file mode 100644 index 0000000..830ed51 --- /dev/null +++ b/src/PBAnaly/SignInForm.Designer.cs @@ -0,0 +1,267 @@ +namespace PBAnaly +{ + partial class SignInForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.userName_materialTextBox = new MaterialSkin.Controls.MaterialTextBox2(); + this.email_materialTextBox = new MaterialSkin.Controls.MaterialTextBox2(); + this.password_materialTextBox = new MaterialSkin.Controls.MaterialTextBox2(); + this.confirmPassword_materialTextBox = new MaterialSkin.Controls.MaterialTextBox2(); + this.signIn_materialButton = new MaterialSkin.Controls.MaterialButton(); + this.materialLabel_ID = new MaterialSkin.Controls.MaterialLabel(); + this.materialLabel_email = new MaterialSkin.Controls.MaterialLabel(); + this.materialLabel_PS = new MaterialSkin.Controls.MaterialLabel(); + this.materialLabel_PW = new MaterialSkin.Controls.MaterialLabel(); + this.SuspendLayout(); + // + // userName_materialTextBox + // + this.userName_materialTextBox.AnimateReadOnly = false; + this.userName_materialTextBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.userName_materialTextBox.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal; + this.userName_materialTextBox.Depth = 0; + this.userName_materialTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.userName_materialTextBox.HideSelection = true; + this.userName_materialTextBox.LeadingIcon = null; + this.userName_materialTextBox.Location = new System.Drawing.Point(39, 92); + this.userName_materialTextBox.MaxLength = 32767; + this.userName_materialTextBox.MouseState = MaterialSkin.MouseState.OUT; + this.userName_materialTextBox.Name = "userName_materialTextBox"; + this.userName_materialTextBox.PasswordChar = '\0'; + this.userName_materialTextBox.PrefixSuffixText = null; + this.userName_materialTextBox.ReadOnly = false; + this.userName_materialTextBox.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.userName_materialTextBox.SelectedText = ""; + this.userName_materialTextBox.SelectionLength = 0; + this.userName_materialTextBox.SelectionStart = 0; + this.userName_materialTextBox.ShortcutsEnabled = true; + this.userName_materialTextBox.Size = new System.Drawing.Size(401, 48); + this.userName_materialTextBox.TabIndex = 1; + this.userName_materialTextBox.TabStop = false; + this.userName_materialTextBox.Text = "UserName Or ID"; + this.userName_materialTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Left; + this.userName_materialTextBox.TrailingIcon = null; + this.userName_materialTextBox.UseSystemPasswordChar = false; + this.userName_materialTextBox.Click += new System.EventHandler(this.userName_materialTextBox_Click); + // + // email_materialTextBox + // + this.email_materialTextBox.AnimateReadOnly = false; + this.email_materialTextBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.email_materialTextBox.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal; + this.email_materialTextBox.Depth = 0; + this.email_materialTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.email_materialTextBox.HideSelection = true; + this.email_materialTextBox.LeadingIcon = null; + this.email_materialTextBox.Location = new System.Drawing.Point(39, 174); + this.email_materialTextBox.MaxLength = 32767; + this.email_materialTextBox.MouseState = MaterialSkin.MouseState.OUT; + this.email_materialTextBox.Name = "email_materialTextBox"; + this.email_materialTextBox.PasswordChar = '\0'; + this.email_materialTextBox.PrefixSuffixText = null; + this.email_materialTextBox.ReadOnly = false; + this.email_materialTextBox.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.email_materialTextBox.SelectedText = ""; + this.email_materialTextBox.SelectionLength = 0; + this.email_materialTextBox.SelectionStart = 0; + this.email_materialTextBox.ShortcutsEnabled = true; + this.email_materialTextBox.Size = new System.Drawing.Size(401, 48); + this.email_materialTextBox.TabIndex = 2; + this.email_materialTextBox.TabStop = false; + this.email_materialTextBox.Text = "E-Mail"; + this.email_materialTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Left; + this.email_materialTextBox.TrailingIcon = null; + this.email_materialTextBox.UseSystemPasswordChar = false; + this.email_materialTextBox.Click += new System.EventHandler(this.email_materialTextBox_Click); + // + // password_materialTextBox + // + this.password_materialTextBox.AnimateReadOnly = false; + this.password_materialTextBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.password_materialTextBox.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal; + this.password_materialTextBox.Depth = 0; + this.password_materialTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.password_materialTextBox.HideSelection = true; + this.password_materialTextBox.LeadingIcon = null; + this.password_materialTextBox.Location = new System.Drawing.Point(39, 256); + this.password_materialTextBox.MaxLength = 32767; + this.password_materialTextBox.MouseState = MaterialSkin.MouseState.OUT; + this.password_materialTextBox.Name = "password_materialTextBox"; + this.password_materialTextBox.PasswordChar = '\0'; + this.password_materialTextBox.PrefixSuffixText = null; + this.password_materialTextBox.ReadOnly = false; + this.password_materialTextBox.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.password_materialTextBox.SelectedText = ""; + this.password_materialTextBox.SelectionLength = 0; + this.password_materialTextBox.SelectionStart = 0; + this.password_materialTextBox.ShortcutsEnabled = true; + this.password_materialTextBox.Size = new System.Drawing.Size(401, 48); + this.password_materialTextBox.TabIndex = 3; + this.password_materialTextBox.TabStop = false; + this.password_materialTextBox.Text = "Password"; + this.password_materialTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Left; + this.password_materialTextBox.TrailingIcon = null; + this.password_materialTextBox.UseSystemPasswordChar = false; + this.password_materialTextBox.Click += new System.EventHandler(this.password_materialTextBox_Click); + // + // confirmPassword_materialTextBox + // + this.confirmPassword_materialTextBox.AnimateReadOnly = false; + this.confirmPassword_materialTextBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.confirmPassword_materialTextBox.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal; + this.confirmPassword_materialTextBox.Depth = 0; + this.confirmPassword_materialTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.confirmPassword_materialTextBox.HideSelection = true; + this.confirmPassword_materialTextBox.LeadingIcon = null; + this.confirmPassword_materialTextBox.Location = new System.Drawing.Point(39, 342); + this.confirmPassword_materialTextBox.MaxLength = 32767; + this.confirmPassword_materialTextBox.MouseState = MaterialSkin.MouseState.OUT; + this.confirmPassword_materialTextBox.Name = "confirmPassword_materialTextBox"; + this.confirmPassword_materialTextBox.PasswordChar = '\0'; + this.confirmPassword_materialTextBox.PrefixSuffixText = null; + this.confirmPassword_materialTextBox.ReadOnly = false; + this.confirmPassword_materialTextBox.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.confirmPassword_materialTextBox.SelectedText = ""; + this.confirmPassword_materialTextBox.SelectionLength = 0; + this.confirmPassword_materialTextBox.SelectionStart = 0; + this.confirmPassword_materialTextBox.ShortcutsEnabled = true; + this.confirmPassword_materialTextBox.Size = new System.Drawing.Size(401, 48); + this.confirmPassword_materialTextBox.TabIndex = 4; + this.confirmPassword_materialTextBox.TabStop = false; + this.confirmPassword_materialTextBox.Text = "Confirm Password"; + this.confirmPassword_materialTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Left; + this.confirmPassword_materialTextBox.TrailingIcon = null; + this.confirmPassword_materialTextBox.UseSystemPasswordChar = false; + this.confirmPassword_materialTextBox.Click += new System.EventHandler(this.confirmPassword_materialTextBox_Click); + this.confirmPassword_materialTextBox.TextChanged += new System.EventHandler(this.confirmPassword_materialTextBox_TextChanged); + // + // signIn_materialButton + // + this.signIn_materialButton.AutoSize = false; + this.signIn_materialButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.signIn_materialButton.Density = MaterialSkin.Controls.MaterialButton.MaterialButtonDensity.Default; + this.signIn_materialButton.Depth = 0; + this.signIn_materialButton.HighEmphasis = true; + this.signIn_materialButton.Icon = null; + this.signIn_materialButton.Location = new System.Drawing.Point(232, 421); + this.signIn_materialButton.Margin = new System.Windows.Forms.Padding(4, 6, 4, 6); + this.signIn_materialButton.MouseState = MaterialSkin.MouseState.HOVER; + this.signIn_materialButton.Name = "signIn_materialButton"; + this.signIn_materialButton.NoAccentTextColor = System.Drawing.Color.Empty; + this.signIn_materialButton.Size = new System.Drawing.Size(208, 36); + this.signIn_materialButton.TabIndex = 5; + this.signIn_materialButton.Text = "SIGN IN"; + this.signIn_materialButton.Type = MaterialSkin.Controls.MaterialButton.MaterialButtonType.Contained; + this.signIn_materialButton.UseAccentColor = false; + this.signIn_materialButton.UseVisualStyleBackColor = true; + this.signIn_materialButton.Click += new System.EventHandler(this.signIn_materialButton_Click); + // + // materialLabel_ID + // + this.materialLabel_ID.AutoSize = true; + this.materialLabel_ID.Depth = 0; + this.materialLabel_ID.Font = new System.Drawing.Font("Roboto", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.materialLabel_ID.Location = new System.Drawing.Point(42, 143); + this.materialLabel_ID.MouseState = MaterialSkin.MouseState.HOVER; + this.materialLabel_ID.Name = "materialLabel_ID"; + this.materialLabel_ID.Size = new System.Drawing.Size(1, 0); + this.materialLabel_ID.TabIndex = 7; + this.materialLabel_ID.UseAccent = true; + // + // materialLabel_email + // + this.materialLabel_email.AutoSize = true; + this.materialLabel_email.BackColor = System.Drawing.Color.Red; + this.materialLabel_email.Depth = 0; + this.materialLabel_email.Font = new System.Drawing.Font("Roboto", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.materialLabel_email.Location = new System.Drawing.Point(41, 225); + this.materialLabel_email.MouseState = MaterialSkin.MouseState.HOVER; + this.materialLabel_email.Name = "materialLabel_email"; + this.materialLabel_email.Size = new System.Drawing.Size(1, 0); + this.materialLabel_email.TabIndex = 8; + this.materialLabel_email.UseAccent = true; + // + // materialLabel_PS + // + this.materialLabel_PS.AutoSize = true; + this.materialLabel_PS.Depth = 0; + this.materialLabel_PS.Font = new System.Drawing.Font("Roboto", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.materialLabel_PS.Location = new System.Drawing.Point(40, 307); + this.materialLabel_PS.MouseState = MaterialSkin.MouseState.HOVER; + this.materialLabel_PS.Name = "materialLabel_PS"; + this.materialLabel_PS.Size = new System.Drawing.Size(1, 0); + this.materialLabel_PS.TabIndex = 9; + this.materialLabel_PS.UseAccent = true; + // + // materialLabel_PW + // + this.materialLabel_PW.AutoSize = true; + this.materialLabel_PW.BackColor = System.Drawing.SystemColors.Control; + this.materialLabel_PW.Depth = 0; + this.materialLabel_PW.Font = new System.Drawing.Font("Roboto", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.materialLabel_PW.Location = new System.Drawing.Point(41, 393); + this.materialLabel_PW.MouseState = MaterialSkin.MouseState.HOVER; + this.materialLabel_PW.Name = "materialLabel_PW"; + this.materialLabel_PW.Size = new System.Drawing.Size(1, 0); + this.materialLabel_PW.TabIndex = 10; + this.materialLabel_PW.UseAccent = true; + // + // SignInForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(484, 486); + this.Controls.Add(this.materialLabel_PW); + this.Controls.Add(this.materialLabel_PS); + this.Controls.Add(this.materialLabel_email); + this.Controls.Add(this.materialLabel_ID); + this.Controls.Add(this.signIn_materialButton); + this.Controls.Add(this.confirmPassword_materialTextBox); + this.Controls.Add(this.password_materialTextBox); + this.Controls.Add(this.email_materialTextBox); + this.Controls.Add(this.userName_materialTextBox); + this.Name = "SignInForm"; + this.Text = "SIGN IN"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private MaterialSkin.Controls.MaterialTextBox2 userName_materialTextBox; + private MaterialSkin.Controls.MaterialTextBox2 email_materialTextBox; + private MaterialSkin.Controls.MaterialTextBox2 password_materialTextBox; + private MaterialSkin.Controls.MaterialTextBox2 confirmPassword_materialTextBox; + private MaterialSkin.Controls.MaterialButton signIn_materialButton; + private MaterialSkin.Controls.MaterialLabel materialLabel_ID; + private MaterialSkin.Controls.MaterialLabel materialLabel_email; + private MaterialSkin.Controls.MaterialLabel materialLabel_PS; + private MaterialSkin.Controls.MaterialLabel materialLabel_PW; + } +} \ No newline at end of file diff --git a/src/PBAnaly/SignInForm.cs b/src/PBAnaly/SignInForm.cs new file mode 100644 index 0000000..79af199 --- /dev/null +++ b/src/PBAnaly/SignInForm.cs @@ -0,0 +1,265 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.IO; +using MaterialSkin; +using MaterialSkin.Controls; +using Microsoft.VisualBasic.FileIO; + +namespace PBAnaly +{ + + public partial class SignInForm : MaterialForm + { + private MaterialSkinManager materialSkinManager; + private LoginForm loginForm; + + bool confirmPCheck = false; + + public SignInForm(LoginForm PassloginForm) + { + InitializeComponent(); + loginForm = PassloginForm; + this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true); + materialSkinManager = MaterialSkinManager.Instance; // 初始化 MaterialSkinManager 实例 + materialSkinManager.AddFormToManage(this); // 将要应用 Material Design 的窗体添加到管理列表中 + materialSkinManager.Theme = MaterialSkinManager.Themes.DARK; // Theme 属性用来设置整体的主题 + materialSkinManager.ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.Red700, TextShade.WHITE); + } + + private void userName_materialTextBox_Click(object sender, EventArgs e) + { + userName_materialTextBox.Text = ""; + } + + private void email_materialTextBox_Click(object sender, EventArgs e) + { + email_materialTextBox.Text = ""; + } + + private void password_materialTextBox_Click(object sender, EventArgs e) + { + password_materialTextBox.Text = ""; + password_materialTextBox.PasswordChar = '*'; + password_materialTextBox.UseSystemPasswordChar = true; + } + + private void confirmPassword_materialTextBox_Click(object sender, EventArgs e) + { + confirmPassword_materialTextBox.Text = ""; + confirmPassword_materialTextBox.PasswordChar = '*'; + confirmPassword_materialTextBox.UseSystemPasswordChar = true; + } + + private void signIn_materialButton_Click(object sender, EventArgs e) + { + bool signInSuccess = true; + + string UserID_str = userName_materialTextBox.Text; + string E_mail_str = email_materialTextBox.Text; + string Password_str = password_materialTextBox.Text; + string Con_Password_str = confirmPassword_materialTextBox.Text; + + List userInfos = new List(); + //Check Is Null Or Not + if (string.IsNullOrEmpty(UserID_str)) + { + materialLabel_ID.Text = "Please Type User Name Or ID!!"; + signInSuccess = false; + } + else + { + materialLabel_ID.Text = ""; + } + + if (string.IsNullOrEmpty(E_mail_str)) + { + materialLabel_email.Text = "Please Type E-Mail Address!!"; + signInSuccess = false; + } + else + { + materialLabel_email.Text = ""; + } + + if (string.IsNullOrEmpty(Password_str)) + { + materialLabel_PS.Text = "Please Type Password!!"; + signInSuccess = false; + } + else + { + materialLabel_PS.Text = ""; + } + + if (string.IsNullOrEmpty(Con_Password_str)) + { + materialLabel_PW.Text = "Please Type Confirm Password!!"; + signInSuccess = false; + } + else + { + materialLabel_PW.Text = ""; + } + + if (!signInSuccess) + { + return; + } + else + { + //Check Format + if (!Password_str.Equals(Con_Password_str)) + { + materialLabel_PW.Text = "*Please Type Same Password!!"; + signInSuccess = false; + } + else + { + materialLabel_PW.Text = ""; + } + + if (!E_mail_str.Contains("@")) + { + materialLabel_email.Text = "*Please Check E-mail Address!!"; + signInSuccess = false; + } + else + { + materialLabel_email.Text = ""; + } + + + if (signInSuccess) + { + //Read UserInfo CSV + string FileName = Global.mDataUser + "UserInfo.csv"; + if (!File.Exists(FileName)) + { + if (!Directory.Exists(Global.mDataUser)) + { + Directory.CreateDirectory(Global.mDataUser); + } + + userInfos.Add(new UserInfo() { autholity = Autholity.Normal, UserID = UserID_str, E_Mail = E_mail_str, Password = Password_str }); + WriteCsv(FileName, userInfos); + } + else + { + var GetCurrentUserInfo = ReadCsv(FileName); + + foreach(var item in GetCurrentUserInfo) + { + if(item.UserID.Equals(UserID_str)) + { + MessageBox.Show("This UserID has been registered, please change another one!!"); + return; + } + } + GetCurrentUserInfo.Add(new UserInfo() { autholity = Autholity.Normal, UserID = UserID_str, E_Mail = E_mail_str, Password = Password_str }); + WriteCsv(FileName, GetCurrentUserInfo); + } + + loginForm.Visible = true; + this.Visible = false; + this.Close(); + } + else + { + return; + } + } + + + + } + + private void WriteCsv(string FilePath, List userInfos) + { + using (var file = new StreamWriter(FilePath)) + { + foreach (var item in userInfos) + { + file.WriteLineAsync($"{item.autholity},{item.UserID},{item.E_Mail},{item.Password}"); + } + + file.Close(); + } + } + + private List ReadCsv(string FilePath) + { + List returnInfo = new List(); + + using (TextFieldParser parser = new TextFieldParser(FilePath)) + { + parser.TextFieldType = FieldType.Delimited; + parser.SetDelimiters(","); + // Read and parse each line of the CSV file + try + { + while (!parser.EndOfData) + { + string[] fields = parser.ReadFields(); + int count = 0; + Autholity autholity = Autholity.admin; + string UserId = ""; + string Email = ""; + string PassWord = ""; + foreach (var item in fields) + { + if ( (count%4) == 0) + { + Enum.TryParse(item, out autholity); + } + else if ((count%4) == 1) + { + UserId = item; + } + else if ((count%4) == 2) + { + Email = item; + } + else + { + PassWord = item; + returnInfo.Add(new UserInfo() { autholity = autholity, UserID = UserId, E_Mail = Email, Password = PassWord }); + } + + count++; + } + } + parser.Close(); + return returnInfo; + } + catch + { + return null; + } + + } + } + + + private void confirmPassword_materialTextBox_TextChanged(object sender, EventArgs e) + { + string Password_str = password_materialTextBox.Text; + string Confirm_Password_str = confirmPassword_materialTextBox.Text; + + if ((Password_str != Confirm_Password_str) && Password_str != null && Confirm_Password_str != null) + { + materialLabel_PW.Text = "*Please Type Same Password!!"; + } + else + { + materialLabel_PW.Text = ""; + } + } + } +} diff --git a/src/PBAnaly/SignInForm.resx b/src/PBAnaly/SignInForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/src/PBAnaly/SignInForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/PBAnaly/UI/AnalyzeDataForm.Designer.cs b/src/PBAnaly/UI/AnalyzeDataForm.Designer.cs new file mode 100644 index 0000000..5691eee --- /dev/null +++ b/src/PBAnaly/UI/AnalyzeDataForm.Designer.cs @@ -0,0 +1,206 @@ +namespace PBAnaly.UI +{ + partial class AnalyzeDataForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.miniToolStrip = new ReaLTaiizor.Controls.CrownMenuStrip(); + this.文件ToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.选项ToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.crownMenuStrip1 = new ReaLTaiizor.Controls.CrownMenuStrip(); + this.metroPanel1 = new ReaLTaiizor.Controls.MetroPanel(); + this.crownLabel1 = new ReaLTaiizor.Controls.CrownLabel(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.panel1 = new ReaLTaiizor.Controls.Panel(); + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + this.crownMenuStrip1.SuspendLayout(); + this.metroPanel1.SuspendLayout(); + this.tableLayoutPanel1.SuspendLayout(); + this.panel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); + this.SuspendLayout(); + // + // miniToolStrip + // + this.miniToolStrip.AccessibleName = "新项选择"; + this.miniToolStrip.AccessibleRole = System.Windows.Forms.AccessibleRole.ComboBox; + this.miniToolStrip.AutoSize = false; + this.miniToolStrip.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(63)))), ((int)(((byte)(65))))); + this.miniToolStrip.Dock = System.Windows.Forms.DockStyle.None; + this.miniToolStrip.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(220)))), ((int)(((byte)(220))))); + this.miniToolStrip.ImageScalingSize = new System.Drawing.Size(20, 20); + this.miniToolStrip.Location = new System.Drawing.Point(91, 3); + this.miniToolStrip.Name = "miniToolStrip"; + this.miniToolStrip.Padding = new System.Windows.Forms.Padding(3, 2, 0, 2); + this.miniToolStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; + this.miniToolStrip.Size = new System.Drawing.Size(872, 25); + this.miniToolStrip.TabIndex = 2; + // + // 文件ToolStripMenuItem1 + // + this.文件ToolStripMenuItem1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(63)))), ((int)(((byte)(65))))); + this.文件ToolStripMenuItem1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(220)))), ((int)(((byte)(220))))); + this.文件ToolStripMenuItem1.Name = "文件ToolStripMenuItem1"; + this.文件ToolStripMenuItem1.Size = new System.Drawing.Size(53, 21); + this.文件ToolStripMenuItem1.Text = "文件"; + // + // 选项ToolStripMenuItem1 + // + this.选项ToolStripMenuItem1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(63)))), ((int)(((byte)(65))))); + this.选项ToolStripMenuItem1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(220)))), ((int)(((byte)(220))))); + this.选项ToolStripMenuItem1.Name = "选项ToolStripMenuItem1"; + this.选项ToolStripMenuItem1.Size = new System.Drawing.Size(53, 21); + this.选项ToolStripMenuItem1.Text = "选项"; + // + // crownMenuStrip1 + // + this.crownMenuStrip1.BackColor = System.Drawing.Color.Gray; + this.crownMenuStrip1.Dock = System.Windows.Forms.DockStyle.Fill; + this.crownMenuStrip1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(220)))), ((int)(((byte)(220))))); + this.crownMenuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); + this.crownMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.文件ToolStripMenuItem1, + this.选项ToolStripMenuItem1}); + this.crownMenuStrip1.Location = new System.Drawing.Point(0, 0); + this.crownMenuStrip1.Name = "crownMenuStrip1"; + this.crownMenuStrip1.Padding = new System.Windows.Forms.Padding(3, 2, 0, 2); + this.crownMenuStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; + this.crownMenuStrip1.Size = new System.Drawing.Size(872, 25); + this.crownMenuStrip1.TabIndex = 2; + // + // metroPanel1 + // + this.metroPanel1.BackgroundColor = System.Drawing.Color.DimGray; + this.metroPanel1.BorderColor = System.Drawing.Color.Gray; + this.metroPanel1.BorderThickness = 1; + this.tableLayoutPanel1.SetColumnSpan(this.metroPanel1, 2); + this.metroPanel1.Controls.Add(this.crownLabel1); + this.metroPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.metroPanel1.IsDerivedStyle = true; + this.metroPanel1.Location = new System.Drawing.Point(0, 31); + this.metroPanel1.Margin = new System.Windows.Forms.Padding(0); + this.metroPanel1.Name = "metroPanel1"; + this.metroPanel1.Size = new System.Drawing.Size(1466, 36); + this.metroPanel1.Style = ReaLTaiizor.Enum.Metro.Style.Custom; + this.metroPanel1.StyleManager = null; + this.metroPanel1.TabIndex = 3; + this.metroPanel1.ThemeAuthor = "Taiizor"; + this.metroPanel1.ThemeName = "MetroDark"; + // + // crownLabel1 + // + this.crownLabel1.AutoSize = true; + this.crownLabel1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(220)))), ((int)(((byte)(220))))); + this.crownLabel1.Location = new System.Drawing.Point(4, 11); + this.crownLabel1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.crownLabel1.Name = "crownLabel1"; + this.crownLabel1.Size = new System.Drawing.Size(37, 15); + this.crownLabel1.TabIndex = 0; + this.crownLabel1.Text = "显示"; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.Controls.Add(this.metroPanel1, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.panel1, 0, 2); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(4, 30); + this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 3; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 31F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 36F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(1466, 1277); + this.tableLayoutPanel1.TabIndex = 3; + // + // panel1 + // + this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(39)))), ((int)(((byte)(51)))), ((int)(((byte)(63))))); + this.tableLayoutPanel1.SetColumnSpan(this.panel1, 2); + this.panel1.Controls.Add(this.dataGridView1); + this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel1.EdgeColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(41)))), ((int)(((byte)(50))))); + this.panel1.Location = new System.Drawing.Point(4, 71); + this.panel1.Margin = new System.Windows.Forms.Padding(4); + this.panel1.Name = "panel1"; + this.panel1.Padding = new System.Windows.Forms.Padding(7, 6, 7, 6); + this.panel1.Size = new System.Drawing.Size(1458, 1202); + this.panel1.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.panel1.TabIndex = 4; + this.panel1.Text = "panel1"; + // + // dataGridView1 + // + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill; + this.dataGridView1.Location = new System.Drawing.Point(7, 6); + this.dataGridView1.Margin = new System.Windows.Forms.Padding(4); + this.dataGridView1.Name = "dataGridView1"; + this.dataGridView1.RowHeadersWidth = 51; + this.dataGridView1.RowTemplate.Height = 23; + this.dataGridView1.Size = new System.Drawing.Size(1444, 1190); + this.dataGridView1.TabIndex = 0; + // + // AnalyzeDataForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1474, 1311); + this.Controls.Add(this.tableLayoutPanel1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D; + this.FormStyle = MaterialSkin.Controls.MaterialForm.FormStyles.ActionBar_None; + this.MainMenuStrip = this.miniToolStrip; + this.Margin = new System.Windows.Forms.Padding(4); + this.Name = "AnalyzeDataForm"; + this.Padding = new System.Windows.Forms.Padding(4, 30, 4, 4); + this.Text = "AnalyzeDataForm"; + this.crownMenuStrip1.ResumeLayout(false); + this.crownMenuStrip1.PerformLayout(); + this.metroPanel1.ResumeLayout(false); + this.metroPanel1.PerformLayout(); + this.tableLayoutPanel1.ResumeLayout(false); + this.panel1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + private ReaLTaiizor.Controls.CrownMenuStrip miniToolStrip; + private System.Windows.Forms.ToolStripMenuItem 文件ToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem 选项ToolStripMenuItem1; + private ReaLTaiizor.Controls.CrownMenuStrip crownMenuStrip1; + private ReaLTaiizor.Controls.MetroPanel metroPanel1; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private ReaLTaiizor.Controls.CrownLabel crownLabel1; + private ReaLTaiizor.Controls.Panel panel1; + private System.Windows.Forms.DataGridView dataGridView1; + } +} \ No newline at end of file diff --git a/src/PBAnaly/UI/AnalyzeDataForm.cs b/src/PBAnaly/UI/AnalyzeDataForm.cs new file mode 100644 index 0000000..5e71a2c --- /dev/null +++ b/src/PBAnaly/UI/AnalyzeDataForm.cs @@ -0,0 +1,200 @@ +using MaterialSkin.Controls; +using PBBiologyVC; +//using ReaLTaiizor.Util; +//using Sunny.UI.Win32; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace PBAnaly.UI +{ + public partial class AnalyzeDataForm : MaterialForm + { + private List<_band_info> band_info; + private List _headers = new List(); + + public struct headInfo + { + public int index; + public List name; + } + public List Headers + { + get { return _headers; } + } + + public struct TopHeader + { + public TopHeader(int index, int span, string text) + { + this.Index = index; + this.Span = span; + this.Text = text; + } + public int Index; + public int Span; + public string Text; + } + + + public AnalyzeDataForm(List<_band_info> _band_info) + { + InitializeComponent(); + band_info = _band_info; + Draw(); + + this.dataGridView1.CellPainting += DataGridView1_CellPainting; + + } + + + public void Draw() + { + this.dataGridView1.Rows.Clear(); + this.dataGridView1.Columns.Clear(); + this.dataGridView1.RowCount = 1; + this.dataGridView1.ColumnCount = band_info.Count*7 + 1; + this.dataGridView1.Columns[0].HeaderText = "行/列"; + int index_c = 0; + for (int i = 1; i < this.dataGridView1.ColumnCount; i=i+7) + { + this.dataGridView1.Columns[i].HeaderText ="分子量"; + this.dataGridView1.Columns[i+1].HeaderText = "条带含量"; + this.dataGridView1.Columns[i+2].HeaderText = "相对含量"; + this.dataGridView1.Columns[i+3].HeaderText = "IOD"; + this.dataGridView1.Columns[i+4].HeaderText = "最大OD"; + this.dataGridView1.Columns[i+5].HeaderText = "百分比"; + this.dataGridView1.Columns[i + 6].HeaderText = "匹配"; + } + _headers = new List(); + int index = 1; + for (int i = 1; i < this.dataGridView1.ColumnCount; i=i+7) + { + + TopHeader topHeader = new TopHeader(i, 7, "泳道" + index++); + _headers.Add(topHeader); + + } + int r_index = 0; + int c_index = 1; + this.dataGridView1.Rows[0].Cells[0].Value = "r1"; + foreach (var _bi in band_info) + { + foreach (var minfo in _bi.Minfo) + { + this.dataGridView1.Rows[r_index].Cells[c_index++].Value = minfo.molecular_weight; + this.dataGridView1.Rows[r_index].Cells[c_index++].Value = minfo.band_content; + this.dataGridView1.Rows[r_index].Cells[c_index++].Value = minfo.relative_content; + this.dataGridView1.Rows[r_index].Cells[c_index++].Value = minfo.IOD; + this.dataGridView1.Rows[r_index].Cells[c_index++].Value = minfo.maxOD; + this.dataGridView1.Rows[r_index].Cells[c_index++].Value = minfo.percentum; + this.dataGridView1.Rows[r_index].Cells[c_index++].Value = minfo.match; + + } + + } + + this.dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing; + this.dataGridView1.ColumnHeadersHeight = 50; + + this.dataGridView1.Refresh(); + } + + int top = 0; + int left = 0; + int height = 0; + int width1 = 0; + private void DataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) + { + #region 重绘datagridview表头 + DataGridView dgv = (DataGridView)(sender); + if (e.RowIndex != -1) return; + foreach (TopHeader item in Headers) + { + if (e.ColumnIndex >= item.Index && e.ColumnIndex < item.Index + item.Span) + { + if (e.ColumnIndex == item.Index) + { + top = e.CellBounds.Top; + left = e.CellBounds.Left; + height = e.CellBounds.Height; + } + int width = 0;//总长度 + for (int i = item.Index; i < item.Span + item.Index; i++) + { + width += dgv.Columns[i].Width; + } + Rectangle rect = new Rectangle(left, top, width, e.CellBounds.Height); + using (Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor)) //Cell背景颜色 + { + //抹去原来的cell背景 + e.Graphics.FillRectangle(backColorBrush, rect); + } + using (Pen gridLinePen = new Pen(dgv.GridColor)) //画笔颜色 + { + e.Graphics.DrawLine(gridLinePen, left, top, left + width, top); + e.Graphics.DrawLine(gridLinePen, left, top + height / 2, left + width, top + height / 2); + e.Graphics.DrawLine(gridLinePen, left, top + height - 1, left + width, top + height - 1); //自定义区域下部横线 + width1 = 0; + e.Graphics.DrawLine(gridLinePen, left - 1, top, left - 1, top + height); + for (int i = item.Index; i < item.Span + item.Index; i++) + { + if (i == 1 || i == 2) + { + width1 += dgv.Columns[i].Width - 1; //分隔区域首列 + } + else + { + width1 += dgv.Columns[i].Width; + } + e.Graphics.DrawLine(gridLinePen, left + width1, top + height / 2, left + width1, top + height); + } + SizeF sf = e.Graphics.MeasureString(item.Text, e.CellStyle.Font); + float lstr = (width - sf.Width) / 2; + float rstr = (height / 2 - sf.Height) / 2; + //画出文本框 + if (item.Text != "") + { + e.Graphics.DrawString(item.Text, e.CellStyle.Font, + new SolidBrush(e.CellStyle.ForeColor), + left + lstr, + top + rstr, + StringFormat.GenericDefault); + } + width = 0; + width1 = 0; + for (int i = item.Index; i < item.Span + item.Index; i++) + { + string columnValue = dgv.Columns[i].HeaderText; + width1 = dgv.Columns[i].Width; + sf = e.Graphics.MeasureString(columnValue, e.CellStyle.Font); + lstr = (width1 - sf.Width) / 2; + rstr = (height / 2 - sf.Height) / 2; + if (columnValue != "") + { + e.Graphics.DrawString(columnValue, e.CellStyle.Font, + new SolidBrush(e.CellStyle.ForeColor), + left + width + lstr, + top + height / 2 + rstr, + StringFormat.GenericDefault); + } + width += dgv.Columns[i].Width; + } + } + e.Handled = true; + } + } + #endregion + + + + + } + } +} diff --git a/src/PBAnaly/UI/AnalyzeDataForm.resx b/src/PBAnaly/UI/AnalyzeDataForm.resx new file mode 100644 index 0000000..d3302bd --- /dev/null +++ b/src/PBAnaly/UI/AnalyzeDataForm.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 191, 17 + + \ No newline at end of file diff --git a/src/PBAnaly/UI/ImagePanel.Designer.cs b/src/PBAnaly/UI/ImagePanel.Designer.cs new file mode 100644 index 0000000..b30022f --- /dev/null +++ b/src/PBAnaly/UI/ImagePanel.Designer.cs @@ -0,0 +1,440 @@ +namespace PBAnaly.UI +{ + partial class ImagePanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.hpb_auto = new ReaLTaiizor.Controls.HopePictureBox(); + this.hhpb_save = new ReaLTaiizor.Controls.HopePictureBox(); + this.hpb_zoom_in = new ReaLTaiizor.Controls.HopePictureBox(); + this.poisonLabel1 = new ReaLTaiizor.Controls.PoisonLabel(); + this.hpb_zoom_out = new ReaLTaiizor.Controls.HopePictureBox(); + this.mcb_mode = new ReaLTaiizor.Controls.MetroComboBox(); + this.cb_scientific = new ReaLTaiizor.Controls.CheckBox(); + this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); + this.tlpanl_image_bar = new System.Windows.Forms.TableLayoutPanel(); + this.pb_coloarbar_image = new System.Windows.Forms.PictureBox(); + this.pl_image = new ReaLTaiizor.Controls.Panel(); + this.pl_bg_image = new ReaLTaiizor.Controls.Panel(); + this.pb_image = new System.Windows.Forms.PictureBox(); + this.lb_wh = new AntdUI.Label(); + this.lb_modename = new AntdUI.Label(); + this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); + this.mlb_bottomLabel = new ReaLTaiizor.Controls.MoonLabel(); + this.tableLayoutPanel1.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_auto)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.hhpb_save)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_zoom_in)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_zoom_out)).BeginInit(); + this.tableLayoutPanel3.SuspendLayout(); + this.tlpanl_image_bar.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pb_coloarbar_image)).BeginInit(); + this.pl_image.SuspendLayout(); + this.pl_bg_image.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pb_image)).BeginInit(); + this.tableLayoutPanel4.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 15F)); + this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel3, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel4, 0, 2); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(2, 19); + this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 3; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 22F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 12F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(363, 311); + this.tableLayoutPanel1.TabIndex = 0; + // + // tableLayoutPanel2 + // + this.tableLayoutPanel2.ColumnCount = 7; + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 28F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 28F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 26F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 43F)); + this.tableLayoutPanel2.Controls.Add(this.hpb_auto, 3, 0); + this.tableLayoutPanel2.Controls.Add(this.hhpb_save, 6, 0); + this.tableLayoutPanel2.Controls.Add(this.hpb_zoom_in, 4, 0); + this.tableLayoutPanel2.Controls.Add(this.poisonLabel1, 0, 0); + this.tableLayoutPanel2.Controls.Add(this.hpb_zoom_out, 5, 0); + this.tableLayoutPanel2.Controls.Add(this.mcb_mode, 1, 0); + this.tableLayoutPanel2.Controls.Add(this.cb_scientific, 2, 0); + this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel2.Location = new System.Drawing.Point(2, 2); + this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(2); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + this.tableLayoutPanel2.RowCount = 1; + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.Size = new System.Drawing.Size(359, 18); + this.tableLayoutPanel2.TabIndex = 1; + // + // hpb_auto + // + this.hpb_auto.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(196)))), ((int)(((byte)(204))))); + this.hpb_auto.Dock = System.Windows.Forms.DockStyle.Fill; + this.hpb_auto.Image = global::PBAnaly.Properties.Resources.全屏; + this.hpb_auto.Location = new System.Drawing.Point(234, 0); + this.hpb_auto.Margin = new System.Windows.Forms.Padding(0); + this.hpb_auto.Name = "hpb_auto"; + this.hpb_auto.PixelOffsetType = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; + this.hpb_auto.Size = new System.Drawing.Size(28, 18); + this.hpb_auto.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.hpb_auto.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.hpb_auto.TabIndex = 4; + this.hpb_auto.TabStop = false; + this.hpb_auto.TextRenderingType = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + this.hpb_auto.Click += new System.EventHandler(this.hpb_auto_Click); + // + // hhpb_save + // + this.hhpb_save.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(196)))), ((int)(((byte)(204))))); + this.hhpb_save.Dock = System.Windows.Forms.DockStyle.Fill; + this.hhpb_save.Image = global::PBAnaly.Properties.Resources.保存图片; + this.hhpb_save.Location = new System.Drawing.Point(316, 0); + this.hhpb_save.Margin = new System.Windows.Forms.Padding(0); + this.hhpb_save.Name = "hhpb_save"; + this.hhpb_save.PixelOffsetType = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; + this.hhpb_save.Size = new System.Drawing.Size(43, 18); + this.hhpb_save.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.hhpb_save.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.hhpb_save.TabIndex = 3; + this.hhpb_save.TabStop = false; + this.hhpb_save.TextRenderingType = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + this.hhpb_save.Click += new System.EventHandler(this.hhpb_save_Click); + // + // hpb_zoom_in + // + this.hpb_zoom_in.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(196)))), ((int)(((byte)(204))))); + this.hpb_zoom_in.Dock = System.Windows.Forms.DockStyle.Fill; + this.hpb_zoom_in.Image = global::PBAnaly.Properties.Resources.放大; + this.hpb_zoom_in.Location = new System.Drawing.Point(262, 0); + this.hpb_zoom_in.Margin = new System.Windows.Forms.Padding(0); + this.hpb_zoom_in.Name = "hpb_zoom_in"; + this.hpb_zoom_in.PixelOffsetType = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; + this.hpb_zoom_in.Size = new System.Drawing.Size(28, 18); + this.hpb_zoom_in.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.hpb_zoom_in.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.hpb_zoom_in.TabIndex = 3; + this.hpb_zoom_in.TabStop = false; + this.hpb_zoom_in.TextRenderingType = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + this.hpb_zoom_in.Click += new System.EventHandler(this.hpb_zoom_in_Click); + // + // poisonLabel1 + // + this.poisonLabel1.AutoSize = true; + this.poisonLabel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.poisonLabel1.Location = new System.Drawing.Point(2, 0); + this.poisonLabel1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.poisonLabel1.Name = "poisonLabel1"; + this.poisonLabel1.Size = new System.Drawing.Size(46, 18); + this.poisonLabel1.TabIndex = 0; + this.poisonLabel1.Text = "模式:"; + this.poisonLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // hpb_zoom_out + // + this.hpb_zoom_out.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(196)))), ((int)(((byte)(204))))); + this.hpb_zoom_out.Dock = System.Windows.Forms.DockStyle.Fill; + this.hpb_zoom_out.Image = global::PBAnaly.Properties.Resources.缩小; + this.hpb_zoom_out.Location = new System.Drawing.Point(290, 0); + this.hpb_zoom_out.Margin = new System.Windows.Forms.Padding(0); + this.hpb_zoom_out.Name = "hpb_zoom_out"; + this.hpb_zoom_out.PixelOffsetType = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; + this.hpb_zoom_out.Size = new System.Drawing.Size(26, 18); + this.hpb_zoom_out.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.hpb_zoom_out.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.hpb_zoom_out.TabIndex = 2; + this.hpb_zoom_out.TabStop = false; + this.hpb_zoom_out.TextRenderingType = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + this.hpb_zoom_out.Click += new System.EventHandler(this.hpb_zoom_out_Click); + // + // mcb_mode + // + this.mcb_mode.AllowDrop = true; + this.mcb_mode.ArrowColor = System.Drawing.Color.FromArgb(((int)(((byte)(150)))), ((int)(((byte)(150)))), ((int)(((byte)(150))))); + this.mcb_mode.BackColor = System.Drawing.Color.Transparent; + this.mcb_mode.BackgroundColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(238)))), ((int)(((byte)(238))))); + this.mcb_mode.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(150)))), ((int)(((byte)(150)))), ((int)(((byte)(150))))); + this.mcb_mode.CausesValidation = false; + this.mcb_mode.DisabledBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204))))); + this.mcb_mode.DisabledBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(155)))), ((int)(((byte)(155)))), ((int)(((byte)(155))))); + this.mcb_mode.DisabledForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(136)))), ((int)(((byte)(136)))), ((int)(((byte)(136))))); + this.mcb_mode.Dock = System.Windows.Forms.DockStyle.Fill; + this.mcb_mode.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; + this.mcb_mode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.mcb_mode.Font = new System.Drawing.Font("Microsoft Sans Serif", 11F); + this.mcb_mode.FormattingEnabled = true; + this.mcb_mode.IsDerivedStyle = true; + this.mcb_mode.ItemHeight = 20; + this.mcb_mode.Items.AddRange(new object[] { + "merge", + "mark", + "pseudocolor"}); + this.mcb_mode.Location = new System.Drawing.Point(52, 2); + this.mcb_mode.Margin = new System.Windows.Forms.Padding(2); + this.mcb_mode.Name = "mcb_mode"; + this.mcb_mode.SelectedItemBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(65)))), ((int)(((byte)(177)))), ((int)(((byte)(225))))); + this.mcb_mode.SelectedItemForeColor = System.Drawing.Color.White; + this.mcb_mode.Size = new System.Drawing.Size(76, 26); + this.mcb_mode.Style = ReaLTaiizor.Enum.Metro.Style.Light; + this.mcb_mode.StyleManager = null; + this.mcb_mode.TabIndex = 1; + this.mcb_mode.ThemeAuthor = "Taiizor"; + this.mcb_mode.ThemeName = "MetroLight"; + this.mcb_mode.SelectedIndexChanged += new System.EventHandler(this.mcb_mode_SelectedIndexChanged); + // + // cb_scientific + // + this.cb_scientific.Checked = false; + this.cb_scientific.CheckedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(66)))), ((int)(((byte)(76)))), ((int)(((byte)(85))))); + this.cb_scientific.CheckedBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(66)))), ((int)(((byte)(76)))), ((int)(((byte)(85))))); + this.cb_scientific.CheckedDisabledColor = System.Drawing.Color.Gray; + this.cb_scientific.CheckedEnabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(34)))), ((int)(((byte)(37))))); + this.cb_scientific.Cursor = System.Windows.Forms.Cursors.Hand; + this.cb_scientific.Dock = System.Windows.Forms.DockStyle.Fill; + this.cb_scientific.Enable = true; + this.cb_scientific.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F); + this.cb_scientific.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(116)))), ((int)(((byte)(125)))), ((int)(((byte)(132))))); + this.cb_scientific.Location = new System.Drawing.Point(133, 3); + this.cb_scientific.Name = "cb_scientific"; + this.cb_scientific.Size = new System.Drawing.Size(98, 16); + this.cb_scientific.TabIndex = 5; + this.cb_scientific.Text = "光子数"; + this.cb_scientific.CheckedChanged += new ReaLTaiizor.Controls.CheckBox.CheckedChangedEventHandler(this.cb_scientific_CheckedChanged); + // + // tableLayoutPanel3 + // + this.tableLayoutPanel3.ColumnCount = 2; + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 86.27969F)); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 13.72032F)); + this.tableLayoutPanel3.Controls.Add(this.tlpanl_image_bar, 0, 0); + this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel3.Location = new System.Drawing.Point(2, 24); + this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(2); + this.tableLayoutPanel3.Name = "tableLayoutPanel3"; + this.tableLayoutPanel3.RowCount = 1; + this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel3.Size = new System.Drawing.Size(359, 273); + this.tableLayoutPanel3.TabIndex = 2; + // + // tlpanl_image_bar + // + this.tlpanl_image_bar.ColumnCount = 2; + this.tableLayoutPanel3.SetColumnSpan(this.tlpanl_image_bar, 2); + this.tlpanl_image_bar.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 83.56546F)); + this.tlpanl_image_bar.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.43454F)); + this.tlpanl_image_bar.Controls.Add(this.pb_coloarbar_image, 1, 1); + this.tlpanl_image_bar.Controls.Add(this.pl_image, 0, 0); + this.tlpanl_image_bar.Controls.Add(this.lb_wh, 1, 2); + this.tlpanl_image_bar.Controls.Add(this.lb_modename, 1, 0); + this.tlpanl_image_bar.Dock = System.Windows.Forms.DockStyle.Fill; + this.tlpanl_image_bar.Location = new System.Drawing.Point(0, 0); + this.tlpanl_image_bar.Margin = new System.Windows.Forms.Padding(0); + this.tlpanl_image_bar.Name = "tlpanl_image_bar"; + this.tlpanl_image_bar.RowCount = 3; + this.tlpanl_image_bar.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F)); + this.tlpanl_image_bar.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tlpanl_image_bar.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 97F)); + this.tlpanl_image_bar.Size = new System.Drawing.Size(359, 273); + this.tlpanl_image_bar.TabIndex = 2; + // + // pb_coloarbar_image + // + this.pb_coloarbar_image.Dock = System.Windows.Forms.DockStyle.Fill; + this.pb_coloarbar_image.Location = new System.Drawing.Point(300, 26); + this.pb_coloarbar_image.Margin = new System.Windows.Forms.Padding(0); + this.pb_coloarbar_image.Name = "pb_coloarbar_image"; + this.pb_coloarbar_image.Size = new System.Drawing.Size(59, 150); + this.pb_coloarbar_image.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pb_coloarbar_image.TabIndex = 1; + this.pb_coloarbar_image.TabStop = false; + // + // pl_image + // + this.pl_image.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(39)))), ((int)(((byte)(51)))), ((int)(((byte)(63))))); + this.pl_image.Controls.Add(this.pl_bg_image); + this.pl_image.Dock = System.Windows.Forms.DockStyle.Fill; + this.pl_image.EdgeColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(41)))), ((int)(((byte)(50))))); + this.pl_image.Location = new System.Drawing.Point(2, 2); + this.pl_image.Margin = new System.Windows.Forms.Padding(2); + this.pl_image.Name = "pl_image"; + this.pl_image.Padding = new System.Windows.Forms.Padding(4); + this.tlpanl_image_bar.SetRowSpan(this.pl_image, 3); + this.pl_image.Size = new System.Drawing.Size(296, 269); + this.pl_image.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.pl_image.TabIndex = 0; + this.pl_image.Text = "panel1"; + // + // pl_bg_image + // + this.pl_bg_image.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(39)))), ((int)(((byte)(51)))), ((int)(((byte)(63))))); + this.pl_bg_image.Controls.Add(this.pb_image); + this.pl_bg_image.Dock = System.Windows.Forms.DockStyle.Fill; + this.pl_bg_image.EdgeColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(41)))), ((int)(((byte)(50))))); + this.pl_bg_image.Location = new System.Drawing.Point(4, 4); + this.pl_bg_image.Margin = new System.Windows.Forms.Padding(0); + this.pl_bg_image.Name = "pl_bg_image"; + this.pl_bg_image.Padding = new System.Windows.Forms.Padding(5); + this.pl_bg_image.Size = new System.Drawing.Size(288, 261); + this.pl_bg_image.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.pl_bg_image.TabIndex = 1; + this.pl_bg_image.Text = "panel1"; + // + // pb_image + // + this.pb_image.Dock = System.Windows.Forms.DockStyle.Fill; + this.pb_image.Location = new System.Drawing.Point(5, 5); + this.pb_image.Margin = new System.Windows.Forms.Padding(0); + this.pb_image.Name = "pb_image"; + this.pb_image.Size = new System.Drawing.Size(278, 251); + this.pb_image.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pb_image.TabIndex = 0; + this.pb_image.TabStop = false; + // + // lb_wh + // + this.lb_wh.Dock = System.Windows.Forms.DockStyle.Fill; + this.lb_wh.Font = new System.Drawing.Font("隶书", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lb_wh.Location = new System.Drawing.Point(303, 179); + this.lb_wh.Name = "lb_wh"; + this.lb_wh.Size = new System.Drawing.Size(53, 91); + this.lb_wh.TabIndex = 2; + this.lb_wh.Text = "Color Scale\r\nMin = 1\r\nMax= 2"; + this.lb_wh.TextAlign = System.Drawing.ContentAlignment.TopCenter; + // + // lb_modename + // + this.lb_modename.Dock = System.Windows.Forms.DockStyle.Fill; + this.lb_modename.Location = new System.Drawing.Point(303, 3); + this.lb_modename.Name = "lb_modename"; + this.lb_modename.Size = new System.Drawing.Size(53, 20); + this.lb_modename.TabIndex = 3; + this.lb_modename.Text = ""; + // + // tableLayoutPanel4 + // + this.tableLayoutPanel4.ColumnCount = 2; + this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 80.93587F)); + this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 19.06413F)); + this.tableLayoutPanel4.Controls.Add(this.mlb_bottomLabel, 0, 0); + this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 299); + this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); + this.tableLayoutPanel4.Name = "tableLayoutPanel4"; + this.tableLayoutPanel4.RowCount = 1; + this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel4.Size = new System.Drawing.Size(363, 12); + this.tableLayoutPanel4.TabIndex = 3; + // + // mlb_bottomLabel + // + this.mlb_bottomLabel.AutoSize = true; + this.mlb_bottomLabel.BackColor = System.Drawing.Color.Transparent; + this.mlb_bottomLabel.Dock = System.Windows.Forms.DockStyle.Fill; + this.mlb_bottomLabel.ForeColor = System.Drawing.Color.Gray; + this.mlb_bottomLabel.Location = new System.Drawing.Point(2, 0); + this.mlb_bottomLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.mlb_bottomLabel.Name = "mlb_bottomLabel"; + this.mlb_bottomLabel.Size = new System.Drawing.Size(289, 12); + this.mlb_bottomLabel.TabIndex = 0; + this.mlb_bottomLabel.Text = "1920x1080 "; + this.mlb_bottomLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // ImagePanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.SystemColors.ButtonHighlight; + this.ClientSize = new System.Drawing.Size(367, 332); + this.Controls.Add(this.tableLayoutPanel1); + this.ForeColor = System.Drawing.SystemColors.ControlText; + this.FormStyle = MaterialSkin.Controls.MaterialForm.FormStyles.ActionBar_None; + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "ImagePanel"; + this.Padding = new System.Windows.Forms.Padding(2, 19, 2, 2); + this.Text = "ImagePanel"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ImagePanel_FormClosing); + this.Enter += new System.EventHandler(this.ImagePanel_Enter); + this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ImagePanel_MouseDown); + this.Resize += new System.EventHandler(this.ImagePanel_Resize); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel2.ResumeLayout(false); + this.tableLayoutPanel2.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_auto)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.hhpb_save)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_zoom_in)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_zoom_out)).EndInit(); + this.tableLayoutPanel3.ResumeLayout(false); + this.tlpanl_image_bar.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pb_coloarbar_image)).EndInit(); + this.pl_image.ResumeLayout(false); + this.pl_bg_image.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pb_image)).EndInit(); + this.tableLayoutPanel4.ResumeLayout(false); + this.tableLayoutPanel4.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; + private ReaLTaiizor.Controls.PoisonLabel poisonLabel1; + private ReaLTaiizor.Controls.MetroComboBox mcb_mode; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; + private ReaLTaiizor.Controls.Panel pl_image; + private System.Windows.Forms.PictureBox pb_image; + private ReaLTaiizor.Controls.HopePictureBox hpb_zoom_out; + private ReaLTaiizor.Controls.HopePictureBox hpb_zoom_in; + private ReaLTaiizor.Controls.HopePictureBox hhpb_save; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4; + private ReaLTaiizor.Controls.MoonLabel mlb_bottomLabel; + private ReaLTaiizor.Controls.HopePictureBox hpb_auto; + private System.Windows.Forms.TableLayoutPanel tlpanl_image_bar; + private ReaLTaiizor.Controls.Panel pl_bg_image; + private System.Windows.Forms.PictureBox pb_coloarbar_image; + private AntdUI.Label lb_wh; + private AntdUI.Label lb_modename; + private ReaLTaiizor.Controls.CheckBox cb_scientific; + } +} \ No newline at end of file diff --git a/src/PBAnaly/UI/ImagePanel.cs b/src/PBAnaly/UI/ImagePanel.cs new file mode 100644 index 0000000..38dd608 --- /dev/null +++ b/src/PBAnaly/UI/ImagePanel.cs @@ -0,0 +1,1592 @@ +using MaterialSkin; +using MaterialSkin.Controls; +using OpenCvSharp; +using OpenCvSharp.Extensions; +using PBAnaly.Module; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp; +using System; +using System.Diagnostics.Eventing.Reader; +using System.Drawing; +using System.IO; +using System.Web.UI; +using System.Windows.Forms; +using Control = System.Windows.Forms.Control; +using System.Threading.Tasks; +using SixLabors.ImageSharp.Metadata; +using Aspose.Pdf.Drawing; +using System.Data.SqlTypes; +using System.Net.PeerToPeer.Collaboration; +using ScottPlot.Panels; +using ScottPlot; +using static Aspose.Pdf.CollectionItem; +using System.Collections.Generic; +using PBBiologyVC; +using System.Threading; +using AntdUI; +using Sunny.UI; +using System.Linq; +using MiniExcelLibs; +using ScottPlot.Colormaps; +using ReaLTaiizor.Extension; +using OpenTK.Graphics.ES11; + +namespace PBAnaly.UI +{ + public partial class ImagePanel : MaterialForm + { + #region 变量 + private MaterialSkinManager Inn_materialSkinManager; // 风格 + private string path; + private string markFilePath; + private string stnFilePath; + private bool scientificON = false; + public ImageToolPaletteForm paletteForm = null; + public ReaLTaiizor.Controls.Panel main_panel = null; + + PBBiologyVC.PBImageProcessVC pbpvc = new PBBiologyVC.PBImageProcessVC(); + + private Image pseu_rgb24_image = null; + private Image pseu_and_mark__rgb24_image = null; + + private Image pseu_L16_image = null; + private Image mark_L16_image = null; + + private Image colorbar_rgb24_image = null; + private byte[] colorbarimage = null; + private byte[] pseu_16_byte = null; + private byte[] pseu_8bit_3_byte = null; + private byte[] pseu_and_mark_8bit_3_byte = null; + private byte[] mark_L16_byte = null; + + private int colorbarWW = 200, colorh_onecolor = 10; + private int colorbarW = 600, colorbarH = 2600; + private int[] mark_h = null; + public int mark_max; + public int mark_min; + + private Bitmap curBitmap = null; + + private const float ZoomFactor = 1.2f; + private float currentZoom = 1.0f; + // 鼠标拖动相关变量 + private bool isDragging = false; + private System.Drawing.Point mouseDownPosition; + private System.Drawing.Point pictureBoxStartPosition; + + private bool drawLine = false; + private bool drawRect = false; + private bool drawCircle = false; + private bool drawpolygon = false; + private System.Drawing.Point startPoint = new System.Drawing.Point(-10,0); + private System.Drawing.Point endPoint = new System.Drawing.Point(-10, 0); + private System.Drawing.Point startRectPoint = new System.Drawing.Point(-10, 0); + private System.Drawing.Point startCirclePoint = new System.Drawing.Point(-10, 0); + private struct RectAndInfo + { + public System.Drawing.Rectangle rectangles; + public Pseudo_infoVC pdinfovc; + } + private List rectAndInfoList = new List(); + private System.Drawing.Rectangle curRectangle = new System.Drawing.Rectangle(0,0,0,0); + private System.Drawing.Point curRectanglePoint; + private System.Drawing.Point originalMousePosition; + private RectAndInfo movingRectangle; + private int curRectIndex = -1; + private Pseudo_infoVC curpdinfovc = null; + private struct CirceAndInfo + { + public System.Drawing.Point center; + public System.Drawing.Point Radius { get; set; } + public Pseudo_infoVC pdinfovc; + } + private List CircleAndInfoList = new List(); + private System.Drawing.Point curCirRadioPoint = new System.Drawing.Point( 0, 0); + private System.Drawing.Point curCirCenterPoint = new System.Drawing.Point(0, 0); + private System.Drawing.Point curCirPoint = new System.Drawing.Point(0, 0); + private System.Drawing.Point cirMousePosition; + private System.Drawing.Point cirRadioMousePosition; + private int curCircleIndex = -1; + private struct PolygonAndInfo + { + public List points ; + public Pseudo_infoVC pdinfovc; + } + private List PolygonAndInfoList = new List(); + private PolygonAndInfo curPolygonAndInfoList = new PolygonAndInfo(); + private System.Drawing.Point curStartPolygonPoint = new System.Drawing.Point(0, 0); + private System.Drawing.Point curPolygonPoint = new System.Drawing.Point(0, 0); + + private bool isStartCircleDragged, isEndCircleDragged,isEndRectDragged,isCircleFragged; + private bool isLineDragged; + private System.Drawing.Point previousMousePosition; // 记录鼠标的前一个位置 + private const int CircleRadius = 5; // 圆圈半径 + private string _colorValue; + private int _colorIndex; + public string colorValue + { + set { + + _colorValue = value; + } + } + public int colorIndex + { + set + { + _colorIndex = value; + + } + } + #endregion + public ImagePanel(string filePath, ReaLTaiizor.Controls.Panel _main_panel) + { + InitializeComponent(); + path = filePath; + pl_bg_image.Dock = DockStyle.None; + main_panel = _main_panel; + RefreshUI(); + Init(); + CenterPictureBox(); + + pb_image.MouseDown += pb_image_MouseDown; + pb_image.DoubleClick += Pb_image_DoubleClick; + pb_image.MouseMove += pb_image_MouseMove; + pb_image.MouseUp += pb_image_MouseUp; + pb_image.Paint += Pb_image_Paint; + + pl_image.MouseWheel += Pl_image_MouseWheel; + pl_image.Focus(); + + // 使用反射设置双缓冲 + System.Reflection.PropertyInfo property = typeof(Control).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + SetDoubleBuffering(pb_image,true); + + // ImageProcess.DrawRuler(pictureBox1); + } + + + + + #region 方法 + public void RefreshUI() + { + ImageToolMannage.imagePanel = this; + main_panel.Controls.Clear(); + if(paletteForm == null) + paletteForm = new ImageToolPaletteForm(); + paletteForm.TopLevel = false; + main_panel.Controls.Add(paletteForm); + paletteForm.Dock = DockStyle.Fill; + paletteForm.Show(); + } + private void SetDoubleBuffering(Control control, bool value) + { + // 使用反射设置双缓冲 + System.Reflection.PropertyInfo property = typeof(Control).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + property.SetValue(control, value, null); + } + public void Init() + { + string[] tifFiles = Directory.GetFiles(path, "*.tif", SearchOption.TopDirectoryOnly); + + foreach (string tifFile in tifFiles) + { + if (tifFile.ToUpper().Contains("MARKER")) + { + markFilePath = tifFile; + mark_L16_image = util.LoadTiffAsL16(markFilePath); + mark_L16_byte = util.ConvertL16ImageToByteArray(mark_L16_image); + (mark_h, mark_min,mark_max) = ImageProcess.CalculateHistogram(mark_L16_image); + + } + else + { + stnFilePath = tifFile; + pseu_L16_image = util.LoadTiffAsL16(stnFilePath); + } + } + + if (mark_L16_image == null || pseu_L16_image == null) + { + MessageBox.Show("图片格式加载不正确"); + return; + } + mlb_bottomLabel.Text = pseu_L16_image.Width.ToString() + "x" + pseu_L16_image.Height.ToString(); + pseu_16_byte = util.ConvertL16ImageToByteArray(pseu_L16_image); + pseu_8bit_3_byte = new byte[pseu_L16_image.Width * pseu_L16_image.Height * 3]; + pseu_and_mark_8bit_3_byte = new byte[pseu_L16_image.Width * pseu_L16_image.Height * 3]; + + colorbarimage = new byte[colorbarW* colorbarH * 3]; + colorbar_rgb24_image = util.ConvertByteArrayToRgb24Image(colorbarimage, colorbarW , colorbarH , 3); + int colorIndex = paletteForm.colorbarIndex; + float _max = paletteForm.ColorMax; + float _min = paletteForm.ColorMin; + + double opactity = paletteForm.opacity; + int brightness = paletteForm.brightness; + unsafe + { + fixed (byte* pseu_16_byte_src = pseu_16_byte) + { + fixed (byte* pseu_8bit_3_byte_src = pseu_8bit_3_byte) + { + fixed (byte* pseu_and_mark_8bit_3_byte_src= pseu_and_mark_8bit_3_byte) + { + fixed (byte* mark_L16_byte_src = mark_L16_byte) + { + fixed (byte* colorbarimage_src = colorbarimage) + { + var ret = pbpvc.render_process(pseu_16_byte_src, mark_L16_byte_src, pseu_8bit_3_byte_src, + pseu_and_mark_8bit_3_byte_src, colorbarimage_src, colorIndex, (ushort)(colorbarW), (ushort)colorbarH, 16, (ushort)pseu_L16_image.Width, (ushort)pseu_L16_image.Height, + 1,_max, _min,scientificON == true?1:0, false, (ushort)colorbarWW, (ushort)colorh_onecolor, brightness, 1.0, opactity); + if (ret != -1) + { + if (colorIndex != 7) // 不为gray表 + { + pseu_rgb24_image = util.ConvertByteArrayToRgb24Image(pseu_8bit_3_byte, pseu_L16_image.Width, (ushort)pseu_L16_image.Height, 3); + pseu_and_mark__rgb24_image = util.ConvertByteArrayToRgb24Image(pseu_and_mark_8bit_3_byte, pseu_L16_image.Width, (ushort)pseu_L16_image.Height, 3); + colorbar_rgb24_image = util.ConvertByteArrayToRgb24Image(colorbarimage, colorbarW, colorbarH, 3); + } + } + } + + + } + + } + + } + } + } + + mcb_mode.SelectedIndex = 0; + } + private void CenterPictureBox() + { + // 设置 pl_bg_image 的位置,使其在 pl_image 中居中 + pl_bg_image.Left = (pl_image.ClientSize.Width - pl_bg_image.Width) / 2; + pl_bg_image.Top = (pl_image.ClientSize.Height - pl_bg_image.Height) / 2; + + //// 确保Panel的AutoScroll属性为true以便在放大后查看整个图片 + pl_image.AutoScroll = true; + + //// 防止图片超过panel的边界 + if (pl_bg_image.Left < 0) pl_bg_image.Left = 0; + if (pl_bg_image.Top < 0) pl_bg_image.Top = 0; + } + private void ZoomPictureBox(float factor) + { + // 按照缩放倍数调整图片的宽度和高度 + //pl_bg_image.Width = (int)(pl_bg_image.Width * factor); + //pl_bg_image.Height = (int)(pl_bg_image.Height * factor); + currentZoom *= factor; + + // 按照缩放比例调整pl_bg_image的宽度和高度 + pl_bg_image.Width = (int)(pl_bg_image.Width * factor); + pl_bg_image.Height = (int)(pl_bg_image.Height * factor); + // 调用方法使PB_image在pl_image中居中 + CenterPictureBox(); + } + private bool IsImageLargerThanPanel() + { + return pl_bg_image.Width > pl_image.ClientSize.Width || pl_bg_image.Height > pl_image.ClientSize.Height; + } + private DateTime lastExecutionTime = DateTime.MinValue; + private int throttleTime = 150; // 设置节流时间间隔(毫秒) + public async void ThisRefresh() + { + if ((DateTime.Now - lastExecutionTime).TotalMilliseconds < throttleTime) + { + return; // 如果距离上次调用时间间隔小于节流时间,则不执行 + } + + lastExecutionTime = DateTime.Now; + if (mcb_mode.SelectedIndex == 0) + { + await Task.Run(() => + { + // 渲染操作在异步任务中执行 + + byte[] colorbarimage = new byte[colorbarW * colorbarH * 3]; + int colorIndex = paletteForm.colorbarIndex; + float _max = paletteForm.ColorMax; + float _min = paletteForm.ColorMin; + + double opactity = paletteForm.opacity; + int brightness = paletteForm.brightness; + unsafe + { + + fixed (byte* pseu_16_byte_src = pseu_16_byte) + { + fixed (byte* pseu_8bit_3_byte_src = pseu_8bit_3_byte) + { + fixed (byte* pseu_and_mark_8bit_3_byte_src = pseu_and_mark_8bit_3_byte) + { + fixed (byte* mark_L16_byte_src = mark_L16_byte) + { + fixed (byte* colorbarimage_src = colorbarimage) + { + var ret = pbpvc.render_process(pseu_16_byte_src, mark_L16_byte_src, pseu_8bit_3_byte_src, + pseu_and_mark_8bit_3_byte_src, colorbarimage_src, colorIndex, (ushort)(colorbarW), (ushort)colorbarH, 16, (ushort)pseu_L16_image.Width, (ushort)pseu_L16_image.Height, + 1, _max, _min, scientificON == true ? 1 : 0, false, (ushort)colorbarWW, (ushort)colorh_onecolor, brightness, 1.0, opactity); + if (ret != -1) + { + pseu_rgb24_image = util.ConvertByteArrayToRgb24Image(pseu_8bit_3_byte, pseu_L16_image.Width, (ushort)pseu_L16_image.Height, 3); + pseu_and_mark__rgb24_image = util.ConvertByteArrayToRgb24Image(pseu_and_mark_8bit_3_byte, pseu_L16_image.Width, (ushort)pseu_L16_image.Height, 3); + colorbar_rgb24_image = util.ConvertByteArrayToRgb24Image(colorbarimage, colorbarW, colorbarH, 3); + } + } + } + + } + + } + } + + } + + // 更新 PictureBox 图像 + //Action updateImageAction = () => + //{ + // pb_image.Image = util.ConvertRgb24ImageToBitmap(pseu_and_mark__rgb24_image); + // curBitmap = (Bitmap)pb_image.Image; + // pb_coloarbar_image.Image = util.ConvertRgb24ImageToBitmap(colorbar_rgb24_image); + // pb_image.Refresh(); + // lb_wh.Text = "color scale\n min=" + _min.ToString() + "\n max=" + _max.ToString(); + //}; + + // 检查是否需要在 UI 线程上更新 + if (pb_image.InvokeRequired) + { + pb_image.Invoke((Action)(() => UpdateImages(_min, _max))); + } + else + { + UpdateImages(_min, _max); + } + }); + } + + } + private void UpdateImages(float _min, float _max) + { + pb_image.Image = util.ConvertRgb24ImageToBitmap(pseu_and_mark__rgb24_image); + curBitmap = (Bitmap)pb_image.Image; + pb_coloarbar_image.Image = util.ConvertRgb24ImageToBitmap(colorbar_rgb24_image); + pb_image.Refresh(); + if (scientificON) + { + + lb_wh.Text = "Radiance (p/sec/cm²/sr)\n color scale\n min=" + util.GetscientificNotation(_min) + "\n max=" + util.GetscientificNotation(_max); + } + else + { + lb_wh.Text = "Radiance (p/sec/cm²/sr)\n color scale\n min=" + _min.ToString() + "\n max=" + _max.ToString(); + } + + } + public void SampleOneSize() + { + var _w = paletteForm.ROI_W; + var _h = paletteForm.ROI_H; + for (int i = 0; i < rectAndInfoList.Count; i++) + { + RectAndInfo raif = new RectAndInfo(); + System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(rectAndInfoList[i].rectangles.X, rectAndInfoList[i].rectangles.Y, _w, _h); + Pseudo_infoVC pivc = rectAndInfoList[i].pdinfovc; + raif.pdinfovc = pivc; + rectAndInfoList[i] = raif; + } + var _r = paletteForm.CIRCLE_R; + + for (int i = 0; i < CircleAndInfoList.Count; i++) + { + CirceAndInfo raif = new CirceAndInfo(); + double angleInRadians = 90 * Math.PI / 180; // Convert degrees to radians + double x = CircleAndInfoList[i].center.X + paletteForm.CIRCLE_R * Math.Cos(angleInRadians); + double y = CircleAndInfoList[i].center.Y + paletteForm.CIRCLE_R * Math.Sin(angleInRadians); + + raif.Radius = new System.Drawing.Point((int)x, (int)y); + + Pseudo_infoVC pivc = rectAndInfoList[i].pdinfovc; + raif.pdinfovc = pivc; + raif.center = CircleAndInfoList[i].center; + CircleAndInfoList[i] = raif; + } + + pb_image.Invalidate(); + } + + public void updateBrightness() + { + + //Mat mat = curBitmap.ToMat(); + //int beta = ImageToolMannage.beta - 127; + //Cv2.ConvertScaleAbs(mat,mat,1,beta); + //pb_image.Image = mat.ToBitmap(); + + } + private bool IsPointInRectangleCorner(System.Drawing.Point point, System.Drawing.Rectangle rect) + { + const int cornerDistance = 10; // 角落拖动区域的距离 + + // 计算矩形四个角落的位置 + System.Drawing.Point[] corners = new System.Drawing.Point[] + { + new System.Drawing.Point(rect.Left, rect.Top), // 左上角 + new System.Drawing.Point(rect.Right, rect.Top), // 右上角 + new System.Drawing.Point(rect.Left, rect.Bottom), // 左下角 + new System.Drawing.Point(rect.Right, rect.Bottom) // 右下角 + }; + + // 判断鼠标是否在某个角落的拖动区域内 + foreach (var corner in corners) + { + if (Math.Abs(corner.X - point.X) <= cornerDistance && Math.Abs(corner.Y - point.Y) <= cornerDistance) + { + return true; + } + } + + return false; + } + // 判断点是否在矩形里 + private bool IsPointInRectangles(System.Drawing.Point point, List rectangles) + { + foreach (var rect in rectangles) + { + if (rect.rectangles.Contains(point)) + return true; + } + return false; + } + + private bool IsPointInRectangles(System.Drawing.Point point, System.Drawing.Rectangle rectangles) + { + return rectangles.Contains(point); + } + // 判断点是否在圆圈内 + private bool IsPointInCircle(System.Drawing.Point point, List circleCenter) + { + foreach (var circle in circleCenter) + { + int radius = (int)Math.Sqrt(Math.Pow(circle.center.X - circle.Radius.X, 2) + Math.Pow(circle.center.Y - circle.Radius.Y, 2)); + double distance = Math.Sqrt(Math.Pow(point.X - circle.center.X, 2) + Math.Pow(point.Y - circle.center.Y, 2)); + if (distance <= radius) return true; + } + + return false; + } + private bool IsPointInCircle(System.Drawing.Point point, System.Drawing.Point circle) + { + double distance = Math.Sqrt(Math.Pow(point.X - circle.X, 2) + Math.Pow(point.Y - circle.Y, 2)); + return distance <= CircleRadius; + } + + private bool IsPointInPolygon(System.Drawing.Point testPoint, PolygonAndInfo polygon) + { + if (polygon.points == null) return false; ; + var points = polygon.points; + bool result = false; + int j = points.Count - 1; // The last vertex is the 'previous' one to the first + + for (int i = 0; i < points.Count; i++) + { + if (points[i].Y < testPoint.Y && points[j].Y >= testPoint.Y || points[j].Y < testPoint.Y && points[i].Y >= testPoint.Y) + { + if (points[i].X + (testPoint.Y - points[i].Y) / (points[j].Y - points[i].Y) * (points[j].X - points[i].X) < testPoint.X) + { + result = !result; + } + } + j = i; // j is previous vertex to i + } + + return result; + } + // 绘制圆圈的帮助方法 + private void DrawCircle(Graphics g, System.Drawing.Point center, int radius, Pen pen, Brush brush) + { + System.Drawing.Rectangle rect = new System.Drawing.Rectangle(center.X - radius, center.Y - radius, radius * 2, radius * 2); + g.FillEllipse(brush, rect); + g.DrawEllipse(pen, rect); + } + private bool IsPointOnLine(System.Drawing.Point point) + { + System.Drawing.Point readLoction = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, point); + // 使用线段的最小距离判断点是否在线段上 + double distance = DistanceToLine(readLoction, startPoint, endPoint); + return distance <= CircleRadius; // 如果距离小于等于圆圈半径,认为在线段上 + } + private double DistanceToLine(System.Drawing.Point p, System.Drawing.Point p1, System.Drawing.Point p2) + { + double A = p.X - p1.X; + double B = p.Y - p1.Y; + double C = p2.X - p1.X; + double D = p2.Y - p1.Y; + + double dot = A * C + B * D; + double lenSq = C * C + D * D; + double param = (lenSq != 0) ? dot / lenSq : -1; + + double xx, yy; + + if (param < 0) + { + xx = p1.X; + yy = p1.Y; + } + else if (param > 1) + { + xx = p2.X; + yy = p2.Y; + } + else + { + xx = p1.X + param * C; + yy = p1.Y + param * D; + } + + double dx = p.X - xx; + double dy = p.Y - yy; + return Math.Sqrt(dx * dx + dy * dy); + } + #endregion + + #region 事件 + private void Pb_image_Paint(object sender, PaintEventArgs e) + { + Graphics g = e.Graphics; + + // 绘制直线 + if (startPoint != System.Drawing.Point.Empty && endPoint != System.Drawing.Point.Empty) + { + g.DrawLine(Pens.Red, startPoint, endPoint); + + // 绘制起点和终点的圆圈 + DrawCircle(g, startPoint, CircleRadius, Pens.Blue, Brushes.LightBlue); + DrawCircle(g, endPoint, CircleRadius, Pens.Blue, Brushes.LightBlue); + } + int labelIndex = 1; + foreach (var rect in rectAndInfoList) + { + var rectangles = ImageProcess.ConvertRealToPictureBoxRectangle(pb_image, rect.rectangles); + + g.DrawRectangle(Pens.Red, rectangles); + System.Drawing.Point[] corners = new System.Drawing.Point[] + { + new System.Drawing.Point(rectangles.Left, rectangles.Top), // 左上角 + new System.Drawing.Point(rectangles.Right, rectangles.Top), // 右上角 + new System.Drawing.Point(rectangles.Left, rectangles.Bottom), // 左下角 + new System.Drawing.Point(rectangles.Right, rectangles.Bottom) // 右下角 + }; + foreach (var item in corners) + { + + DrawCircle(g, new System.Drawing.Point(item.X, item.Y), CircleRadius, Pens.Blue, Brushes.LightBlue); + } + + // 指向线的起点在矩形的顶部中心 + System.Drawing.Point centerTopPoint = new System.Drawing.Point( + rectangles.Left + rectangles.Width / 2, + rectangles.Top + ); + + // 指向线的终点在矩形上方10像素 + System.Drawing.Point labelPoint = new System.Drawing.Point( + centerTopPoint.X, + centerTopPoint.Y - 10 + ); + // 画垂直的指向线 + g.DrawLine(Pens.Red, centerTopPoint, labelPoint); + // 画标签 + if (rect.pdinfovc != null) + { + string labelText = ""; + if (scientificON) + { + + + labelText = $"ROI:{labelIndex++},AOD:{util.GetscientificNotation(rect.pdinfovc.AOD) },IOD:{util.GetscientificNotation(rect.pdinfovc.IOD) }," + + $"\r\nmaxOD:{util.GetscientificNotation(rect.pdinfovc.maxOD)},minOD:{util.GetscientificNotation(rect.pdinfovc.minOD)},Count:{util.GetscientificNotation(rect.pdinfovc.Count)}"; + } + else + { + labelText = $"ROI:{labelIndex++},AOD:{rect.pdinfovc.AOD},IOD:{rect.pdinfovc.IOD}," + + $"\r\nmaxOD:{rect.pdinfovc.maxOD},minOD:{rect.pdinfovc.minOD},Count:{rect.pdinfovc.Count}"; // 标签编号 + } + + Font font = new Font("Arial", 8); // 字体 + Brush brush = Brushes.Red; // 字体颜色 + g.DrawString(labelText, font, brush, labelPoint.X - 10, labelPoint.Y - 15); + } + + + } + if (drawRect) + { + g.DrawRectangle(Pens.Red, curRectangle); + } + else if (isEndRectDragged) + { + var rectangles = ImageProcess.ConvertRealToPictureBoxRectangle(pb_image, movingRectangle.rectangles); + g.DrawRectangle(Pens.Red, rectangles); + } + labelIndex = 0; + foreach (var item in CircleAndInfoList) + { + var centerPoint = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, item.center); + var radiusPoint = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, item.Radius); + int radius = (int)Math.Sqrt(Math.Pow(centerPoint.X - radiusPoint.X, 2) + Math.Pow(centerPoint.Y - radiusPoint.Y, 2)); + e.Graphics.DrawEllipse(Pens.Red, centerPoint.X - radius, centerPoint.Y - radius, radius * 2, radius * 2); + DrawCircle(g, new System.Drawing.Point(radiusPoint.X, radiusPoint.Y), CircleRadius, Pens.Blue, Brushes.LightBlue); + + + // 指向线的终点在矩形上方10像素 + System.Drawing.Point labelPoint = new System.Drawing.Point( + centerPoint.X, + centerPoint.Y - radius-10 + ); + // 画垂直的指向线 + g.DrawLine(Pens.Red, centerPoint, labelPoint); + // 画标签 + if (item.pdinfovc != null) + { + + string labelText = ""; + if (scientificON) + { + + + labelText = $"ROI:{labelIndex++},AOD:{util.GetscientificNotation(item.pdinfovc.AOD)},IOD:{util.GetscientificNotation(item.pdinfovc.IOD)}," + + $"\r\nmaxOD:{util.GetscientificNotation(item.pdinfovc.maxOD)},minOD:{util.GetscientificNotation(item.pdinfovc.minOD)},Count:{util.GetscientificNotation(item.pdinfovc.Count)}"; + } + else + { + labelText = $"ROI:{labelIndex++},AOD:{item.pdinfovc.AOD},IOD:{item.pdinfovc.IOD}," + + $"\r\nmaxOD:{item.pdinfovc.maxOD},minOD:{item.pdinfovc.minOD},Count:{item.pdinfovc.Count}"; // 标签编号 + } + Font font = new Font("Arial", 8); // 字体 + Brush brush = Brushes.Red; // 字体颜色 + g.DrawString(labelText, font, brush, labelPoint.X - 10, labelPoint.Y - 15); + } + } + if (drawCircle) + { + int radius = (int)Math.Sqrt(Math.Pow(curCirCenterPoint.X - curCirRadioPoint.X, 2) + Math.Pow(curCirCenterPoint.Y - curCirRadioPoint.Y, 2)); + e.Graphics.DrawEllipse(Pens.Red, curCirCenterPoint.X - radius, curCirCenterPoint.Y - radius, radius * 2, radius * 2); + DrawCircle(g, new System.Drawing.Point(curCirRadioPoint.X, curCirRadioPoint.Y), CircleRadius, Pens.Blue, Brushes.LightBlue); + } + else if (isCircleFragged) + { + var centerPoint = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, cirMousePosition); + var radiusPoint = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, cirRadioMousePosition); + int radius = (int)Math.Sqrt(Math.Pow(centerPoint.X - radiusPoint.X, 2) + Math.Pow(centerPoint.Y - radiusPoint.Y, 2)); + e.Graphics.DrawEllipse(Pens.Red, centerPoint.X - radius, centerPoint.Y - radius, radius * 2, radius * 2); + + } + if (PolygonAndInfoList != null) + { + int isStart = 0; + System.Drawing.Point point = new System.Drawing.Point(); + foreach (var item1 in PolygonAndInfoList) + { + foreach (var item in item1.points) + { + if (isStart == 0) + { + point = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, item); + } + System.Drawing.Point curpoint = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, item); + DrawCircle(g, curpoint, CircleRadius, Pens.Blue, Brushes.LightBlue); + g.DrawLine(Pens.Red, curpoint, point); + point = curpoint; + isStart++; + } + + } + + if (drawpolygon) + { + + point = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, curPolygonAndInfoList.points[curPolygonAndInfoList.points.Count-1]); + g.DrawLine(Pens.Red, curPolygonPoint, point); + foreach (var item in curPolygonAndInfoList.points) + { + if (isStart == 0) + { + point = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, item); + } + System.Drawing.Point curpoint = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, item); + DrawCircle(g, curpoint, CircleRadius, Pens.Blue, Brushes.LightBlue); + g.DrawLine(Pens.Red, curpoint, point); + point = curpoint; + isStart++; + } + } + else + { + if (curPolygonAndInfoList.pdinfovc != null) + { + + string labelText = ""; + if (scientificON) + { + + + labelText = $"ROI:{labelIndex++},AOD:{util.GetscientificNotation(curPolygonAndInfoList.pdinfovc.AOD)},IOD:{util.GetscientificNotation(curPolygonAndInfoList.pdinfovc.IOD)}," + + $"\r\nmaxOD:{util.GetscientificNotation(curPolygonAndInfoList.pdinfovc.maxOD)},minOD:{util.GetscientificNotation(curPolygonAndInfoList.pdinfovc.minOD)},Count:{util.GetscientificNotation(curPolygonAndInfoList.pdinfovc.Count)}"; + } + else + { + labelText = $"ROI:{labelIndex++},AOD:{curPolygonAndInfoList.pdinfovc.AOD},IOD:{curPolygonAndInfoList.pdinfovc.IOD}," + + $"\r\nmaxOD:{curPolygonAndInfoList.pdinfovc.maxOD},minOD:{curPolygonAndInfoList.pdinfovc.minOD},Count:{curPolygonAndInfoList.pdinfovc.Count}"; // 标签编号 + } + Font font = new Font("Arial", 8); // 字体 + Brush brush = Brushes.Red; // 字体颜色 + System.Drawing.Point curpoint = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, curPolygonAndInfoList.points[0]); + g.DrawString(labelText, font, brush, curpoint.X - 10, curpoint.Y - 15); + } + } + } + + } + + private void Pl_image_MouseWheel(object sender, MouseEventArgs e) + { + if (e.Delta > 0) + { + // 滚轮向上,放大图片 + ZoomPictureBox(ZoomFactor); + } + else if (e.Delta < 0) + { + ZoomPictureBox(1 / ZoomFactor); + // 滚轮向下,缩小图片,但不能缩小到小于pl_image的尺寸 + //if (pl_bg_image.Width > pl_bg_image.Width / ZoomFactor && pl_bg_image.Height > pl_bg_image.Height / ZoomFactor) + //{ + // ZoomPictureBox(1 / ZoomFactor); + //} + } + } + + + private void pb_image_MouseDown(object sender, MouseEventArgs e) + { + System.Drawing.Point readLoction = ImageProcess.GetRealImageCoordinates(pb_image, e.Location); + if (ImageToolMannage.lineDisON && e.Button == MouseButtons.Left) + { + drawLine = true; + startPoint = e.Location; + } + else if (ImageToolMannage.rectON && e.Button == MouseButtons.Left) + { + drawRect = true; + startRectPoint = e.Location; + curRectangle = new System.Drawing.Rectangle(e.Location, new System.Drawing.Size(0, 0)); + } + else if (ImageToolMannage.circleON && e.Button == MouseButtons.Left) + { + drawCircle = true; + startCirclePoint = e.Location; + curCirCenterPoint = e.Location; + curCirRadioPoint = e.Location; + } + else if (ImageToolMannage.linepolygonON && e.Button == MouseButtons.Left) + { + drawpolygon = true; + if (curPolygonAndInfoList.points == null) + { + curPolygonAndInfoList.points = new List(); + } + System.Drawing.Point curPoint = ImageProcess.GetRealImageCoordinates(pb_image, e.Location); + curPolygonAndInfoList.points.Add(curPoint); + } + else if (IsPointInCircle(readLoction, startPoint) && e.Button == MouseButtons.Left) + { + isStartCircleDragged = true; + } + else if (IsPointInCircle(readLoction, endPoint) && e.Button == MouseButtons.Left) + { + isEndCircleDragged = true; + } + else if (IsPointInCircle(readLoction, CircleAndInfoList) && e.Button == MouseButtons.Left) + { + int index = 0; + foreach (var circle in CircleAndInfoList) + { + int radius = (int)Math.Sqrt(Math.Pow(circle.center.X - circle.Radius.X, 2) + Math.Pow(circle.center.Y - circle.Radius.Y, 2)); + double distance = Math.Sqrt(Math.Pow(readLoction.X - circle.center.X, 2) + Math.Pow(readLoction.Y - circle.center.Y, 2)); + if (distance <= radius) + { + curCirPoint = readLoction; + + curCircleIndex = index; + cirMousePosition =circle.center; + cirRadioMousePosition = circle.Radius; + isCircleFragged = true; + break; + } + index++; + } + } + else if (IsPointInRectangles(readLoction, rectAndInfoList) && e.Button == MouseButtons.Left) + { + int index = 0; + foreach (var rect in rectAndInfoList) + { + if (rect.rectangles.Contains(readLoction)) + { + isEndRectDragged = true; + movingRectangle = rect; + curRectanglePoint = readLoction; + curRectIndex = index; + break; + } + index++; + } + + } + else if (e.Button == MouseButtons.Left && IsImageLargerThanPanel()) + { + isDragging = true; + mouseDownPosition = e.Location; + pictureBoxStartPosition = pl_bg_image.Location; + pl_bg_image.Cursor = Cursors.Hand; + + } + } + private void Pb_image_DoubleClick(object sender, EventArgs e) + { + if (ImageToolMannage.linepolygonON && drawpolygon == true) + { + + if (curPolygonAndInfoList.points != null) + { + System.Drawing.Point firstPoint = curPolygonAndInfoList.points[0]; + System.Drawing.Point lastPoint = curPolygonAndInfoList.points[curPolygonAndInfoList.points.Count - 1]; + firstPoint = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, firstPoint); + lastPoint = ImageProcess.ConvertRealToPictureBoxCoordinates(pb_image, lastPoint); + double deltaX = lastPoint.X - firstPoint.X; + double deltaY = lastPoint.Y - firstPoint.Y; + var value = Math.Sqrt(deltaX * deltaX + deltaY * deltaY); + if (value <= 5) + { + lastPoint = firstPoint; + drawpolygon = false; + ImageToolMannage.linepolygonON = false; + pb_image.Invalidate(); + + // 计算光子量 + + float _max = paletteForm.ColorMax; + float _min = paletteForm.ColorMin; + List curVclist = new List(); + + foreach (var item in curPolygonAndInfoList.points) + { + Point_VC pvc = new Point_VC(item.X,item.Y); + curVclist.Add(pvc); + + } + unsafe + { + fixed (byte* pseu_16_byte_src = pseu_16_byte) + { + curpdinfovc = pbpvc.get_pseudo_info_polygon_vc(pseu_16_byte_src, 16, (ushort)pseu_L16_image.Width, (ushort)pseu_L16_image.Height, _max, _min, curVclist); + + } + } + curPolygonAndInfoList.pdinfovc = curpdinfovc; + + PolygonAndInfoList.Add(curPolygonAndInfoList); + } + + + } + + + } + } + private void pb_image_MouseMove(object sender, MouseEventArgs e) + { + System.Drawing.Point readLoction = ImageProcess.GetRealImageCoordinates(pb_image, e.Location); + if (ImageToolMannage.lineDisON && drawLine) + { + endPoint = e.Location; // 更新终点位置 + pb_image.Invalidate(); // 触发重绘 + } + else if (ImageToolMannage.rectON && drawRect) + { + curRectangle.Width = Math.Abs(e.X - startRectPoint.X); + curRectangle.Height = Math.Abs(e.Y - startRectPoint.Y); + + // 处理矩形位置,以确保其起点是左上角 + curRectangle.X = Math.Min(startRectPoint.X, e.X); + curRectangle.Y = Math.Min(startRectPoint.Y, e.Y); + pb_image.Invalidate(); + } + else if (ImageToolMannage.circleON && drawCircle) + { + curCirRadioPoint = e.Location; + pb_image.Invalidate(); + } + else if (ImageToolMannage.linepolygonON && drawpolygon) + { + curPolygonPoint = e.Location; + pb_image.Invalidate(); + } + else if (IsPointInCircle(readLoction, startPoint) || IsPointInCircle(readLoction, endPoint)) + { + pb_image.Cursor = Cursors.Hand; + } + else if (IsPointInRectangles(readLoction, rectAndInfoList)) + { + pb_image.Cursor = Cursors.Hand; + + } + else if (IsPointInCircle(readLoction, CircleAndInfoList)) + { + pb_image.Cursor = Cursors.Hand; + } + else if (isStartCircleDragged) + { + + // 拖动起始点 + startPoint = e.Location; + pb_image.Invalidate(); + } + else if (isEndCircleDragged) + { + // 拖动终点 + endPoint = e.Location; + pb_image.Invalidate(); + } + + else if (isDragging) + { + int deltaX = e.X - mouseDownPosition.X; + int deltaY = e.Y - mouseDownPosition.Y; + + // 仅当鼠标移动时调整位置,减少频繁重绘 + if (Math.Abs(deltaX) > 1 || Math.Abs(deltaY) > 1) + { + pl_bg_image.Left = pictureBoxStartPosition.X + deltaX; + pl_bg_image.Top = pictureBoxStartPosition.Y + deltaY; + + // 防止 pl_bg_image 拖动超出 pl_image 的范围 + if (pl_bg_image.Left > 0) pl_bg_image.Left = 0; + if (pl_bg_image.Top > 0) pl_bg_image.Top = 0; + if (pl_bg_image.Right < pl_image.ClientSize.Width) + pl_bg_image.Left = pl_image.ClientSize.Width - pl_bg_image.Width; + if (pl_bg_image.Bottom < pl_image.ClientSize.Height) + pl_bg_image.Top = pl_image.ClientSize.Height - pl_bg_image.Height; + } + + + } + else if (isEndRectDragged) + { + if (rectAndInfoList.Count > 0) + { + int _xvalue = readLoction.X - curRectanglePoint.X; + int _yvalue = readLoction.Y - curRectanglePoint.Y; + movingRectangle.rectangles.X += _xvalue; movingRectangle.rectangles.Y += _yvalue; + curRectanglePoint = readLoction; + pb_image.Invalidate(); + + rectAndInfoList[curRectIndex] = movingRectangle; + } + + } + else if (isCircleFragged) + { + + if (CircleAndInfoList.Count > 0) + { + int _xvalue = readLoction.X - curCirPoint.X; + int _yvalue = readLoction.Y - curCirPoint.Y; + + cirMousePosition.X += _xvalue; cirMousePosition.Y += _yvalue; + cirRadioMousePosition.X += _xvalue; + cirRadioMousePosition.Y += _yvalue; + curCirPoint = readLoction; + + CirceAndInfo caif = new CirceAndInfo(); + caif.center = cirMousePosition; + caif.Radius = cirRadioMousePosition; + caif.pdinfovc = CircleAndInfoList[curCircleIndex].pdinfovc; + CircleAndInfoList[curCircleIndex] = caif; + pb_image.Invalidate(); + } + + } + else if (IsPointInRectangles(e.Location, rectAndInfoList)) + { + pb_image.Cursor = Cursors.Hand; + } + else + { + pb_image.Cursor = Cursors.Default; + } + } + private void pb_image_MouseUp(object sender, MouseEventArgs e) + { + System.Drawing.Point readLoction = ImageProcess.GetRealImageCoordinates(pb_image, e.Location); + isDragging = false; + if (e.Button == MouseButtons.Left) + { + drawLine = false; + if (drawRect) + { + RectAndInfo rai = new RectAndInfo(); + rai.rectangles = ImageProcess.GetRealImageRectangle(pb_image,curRectangle); + if (ImageToolMannage.RoiIndex == 0) + { + ImageToolMannage.Roi_w = rai.rectangles.Width; + ImageToolMannage.Roi_h = rai.rectangles.Height; + + paletteForm.ROI_W = rai.rectangles.Width; + paletteForm.ROI_H = rai.rectangles.Height; + } + else + { + rai.rectangles.Width = ImageToolMannage.Roi_w; + rai.rectangles.Height = ImageToolMannage.Roi_h; + paletteForm.ROI_W = ImageToolMannage.Roi_w; + paletteForm.ROI_H = ImageToolMannage.Roi_h; + } + ImageToolMannage.RoiIndex++; + System.Drawing.Point curPoint = ImageProcess.GetRealImageCoordinates(pb_image,new System.Drawing.Point( curRectangle.X,curRectangle.Y)); + // 计算光子数并展示出来 + float _max = paletteForm.ColorMax; + float _min = paletteForm.ColorMin; + + unsafe + { + fixed (byte* pseu_16_byte_src = pseu_16_byte) + { + curpdinfovc = pbpvc.get_pseudo_info_rect_vc(pseu_16_byte_src, 16, (ushort)pseu_L16_image.Width, (ushort)pseu_L16_image.Height, _max, _min, curPoint.X, curPoint.Y, curRectangle.Width, curRectangle.Height); + + } + } + rai.pdinfovc = curpdinfovc; + rectAndInfoList.Add(rai); + drawRect = false; + + + + } + if (drawCircle) + { + CirceAndInfo circeAndInfo = new CirceAndInfo(); + + circeAndInfo.Radius = ImageProcess.GetRealImageCoordinates(pb_image, curCirRadioPoint); + circeAndInfo.center = ImageProcess.GetRealImageCoordinates(pb_image, curCirCenterPoint); + if (ImageToolMannage.CircleIndex == 0) + { + paletteForm.CIRCLE_R = (int)Math.Sqrt(Math.Pow(circeAndInfo.center.X - circeAndInfo.Radius.X, 2) + Math.Pow(circeAndInfo.center.Y - circeAndInfo.Radius.Y, 2)); + ImageToolMannage.Roi_r = paletteForm.CIRCLE_R; + } + else + { + paletteForm.CIRCLE_R = ImageToolMannage.Roi_r; + double angleInRadians = 90 * Math.PI / 180; // Convert degrees to radians + double x = circeAndInfo.center.X + paletteForm.CIRCLE_R * Math.Cos(angleInRadians); + double y = circeAndInfo.center.Y + paletteForm.CIRCLE_R * Math.Sin(angleInRadians); + + circeAndInfo.Radius = new System.Drawing.Point((int)x, (int)y); + } + ImageToolMannage.CircleIndex++; + + float _max = paletteForm.ColorMax; + float _min = paletteForm.ColorMin; + int radius = (int)Math.Sqrt(Math.Pow(circeAndInfo.center.X - circeAndInfo.Radius.X, 2) + Math.Pow(circeAndInfo.center.Y - circeAndInfo.Radius.Y, 2)); + unsafe + { + fixed (byte* pseu_16_byte_src = pseu_16_byte) + { + curpdinfovc = pbpvc.get_pseudo_info_circle_vc(pseu_16_byte_src, 16, (ushort)pseu_L16_image.Width, (ushort)pseu_L16_image.Height, _max, _min, circeAndInfo.center.X, circeAndInfo.center.Y, radius); + + } + } + circeAndInfo.pdinfovc = curpdinfovc; + + CircleAndInfoList.Add(circeAndInfo); + drawCircle = false; + } + ImageToolMannage.rectON = false; + ImageToolMannage.circleON = false; + if (isEndRectDragged) + { + RectAndInfo rai = new RectAndInfo(); + rai.rectangles = movingRectangle.rectangles; + + rai.rectangles.Width = paletteForm.ROI_W; + rai.rectangles.Height = paletteForm.ROI_H; + + + // 计算光子数并展示出来 + float _max = paletteForm.ColorMax; + float _min = paletteForm.ColorMin; + + unsafe + { + fixed (byte* pseu_16_byte_src = pseu_16_byte) + { + curpdinfovc = pbpvc.get_pseudo_info_rect_vc(pseu_16_byte_src, 16, (ushort)pseu_L16_image.Width, (ushort)pseu_L16_image.Height, _max, _min, rai.rectangles.X, rai.rectangles.Y, curRectangle.Width, curRectangle.Height); + + } + } + rai.pdinfovc = curpdinfovc; + rectAndInfoList[curRectIndex] = rai; + isEndRectDragged = false; + } + if (isCircleFragged) + { + CirceAndInfo circeAndInfo = new CirceAndInfo(); + + circeAndInfo.Radius = cirRadioMousePosition; + circeAndInfo.center = cirMousePosition; + + float _max = paletteForm.ColorMax; + float _min = paletteForm.ColorMin; + int radius = (int)Math.Sqrt(Math.Pow(circeAndInfo.center.X - circeAndInfo.Radius.X, 2) + Math.Pow(circeAndInfo.center.Y - circeAndInfo.Radius.Y, 2)); + unsafe + { + fixed (byte* pseu_16_byte_src = pseu_16_byte) + { + curpdinfovc = pbpvc.get_pseudo_info_circle_vc(pseu_16_byte_src, 16, (ushort)pseu_L16_image.Width, (ushort)pseu_L16_image.Height, _max, _min, circeAndInfo.center.X, circeAndInfo.center.Y, radius); + + } + } + circeAndInfo.pdinfovc = curpdinfovc; + + CircleAndInfoList[curCircleIndex] = circeAndInfo; + isCircleFragged = false; + curCircleIndex = -1; + } + pb_image.Invalidate(); + if (isStartCircleDragged || isEndCircleDragged || ImageToolMannage.lineDisON) + { + System.Drawing.Point curEndPoint = ImageProcess.GetRealImageCoordinates(pb_image, endPoint); + System.Drawing.Point curStartPoint = ImageProcess.GetRealImageCoordinates(pb_image, startPoint); + // 计算距离 + double deltaX = curEndPoint.X - curStartPoint.X; + double deltaY = curEndPoint.Y - curStartPoint.Y; + var value = Math.Sqrt(deltaX * deltaX + deltaY * deltaY); + paletteForm.SetactMM(value.ToString() + " mm"); + + + } + isStartCircleDragged = false; + isEndCircleDragged = false; + ImageToolMannage.lineDisON = false; + + + } + else if (e.Button == MouseButtons.Right) + { + if (IsPointOnLine(readLoction)) + { + startPoint = new System.Drawing.Point(-10, 0); + endPoint = new System.Drawing.Point(-10, 0); + pb_image.Invalidate(); + paletteForm.SetactMM("0"); + } + else if (IsPointInRectangles(readLoction, rectAndInfoList)) + { + int _index = -1; + foreach (var rect in rectAndInfoList) + { + _index++; + if (rect.rectangles.Contains(readLoction)) + break; + } + if (_index >= 0) + { + rectAndInfoList.RemoveAt(_index); + ImageToolMannage.RoiIndex--; + pb_image.Invalidate(); + } + } + else if (IsPointInCircle(readLoction, CircleAndInfoList)) + { + int _index = -1; + foreach (var rect in CircleAndInfoList) + { + _index++; + if (rect.center.X == readLoction.X && rect.center.Y == readLoction.Y) + break; + } + if (_index >= 0) + { + CircleAndInfoList.RemoveAt(_index); + ImageToolMannage.CircleIndex--; + pb_image.Invalidate(); + } + } + else if (IsPointInPolygon(readLoction, curPolygonAndInfoList)) + { + PolygonAndInfoList.Clear(); + curPolygonAndInfoList.points.Clear(); + curPolygonAndInfoList.pdinfovc = null; + pb_image.Invalidate(); + } + else if (ImageToolMannage.linewandON) + { + //RectAndInfo rai = new RectAndInfo(); + //rai.rectangles = ImageProcess.GetRealImageRectangle(pb_image, ); + + //System.Drawing.Point curPoint = ImageProcess.GetRealImageCoordinates(pb_image, new System.Drawing.Point(curRectangle.X, curRectangle.Y)); + //// 计算光子数并展示出来 + //float _max = paletteForm.ColorMax; + //float _min = paletteForm.ColorMin; + + //unsafe + //{ + // fixed (byte* pseu_16_byte_src = pseu_16_byte) + // { + // curpdinfovc = pbpvc.get_pseudo_info_wand_vc(pseu_16_byte_src, 16, (ushort)pseu_L16_image.Width, (ushort)pseu_L16_image.Height, _max, _min, curPoint.X, curPoint.Y, curRectangle.Width, curRectangle.Height); + + // } + //} + //rai.pdinfovc = curpdinfovc; + //rectAndInfoList.Add(rai); + //drawRect = false; + //pb_image.Invalidate(); + } + } + + + + } + private void hpb_zoom_in_Click(object sender, System.EventArgs e) + { + ZoomPictureBox(ZoomFactor); + } + + private void hpb_zoom_out_Click(object sender, System.EventArgs e) + { + ZoomPictureBox(1 / ZoomFactor); + } + private void hpb_auto_Click(object sender, EventArgs e) + { + if (pb_image.Image == null) return; + + + // 设置PictureBox的宽度和高度 + pb_image.Location = new System.Drawing.Point(pl_image.Location.X,pl_image.Location.Y); + pb_image.Width = pl_image.Width; + pb_image.Height = pl_image.Height; + + + } + private void mcb_mode_SelectedIndexChanged(object sender, System.EventArgs e) + { + + lb_modename.Text = mcb_mode.Text; + float _max = paletteForm.ColorMax; + float _min = paletteForm.ColorMin; + if (scientificON) + { + lb_wh.Text = "Radiance (p/sec/cm²/sr)\n color scale\n min=" + util.GetscientificNotation(_min) + "\n max=" + util.GetscientificNotation(_max); + } + else + { + lb_wh.Text = "Radiance (p/sec/cm²/sr)\n color scale\n min=" + _min.ToString() + "\n max=" + _max.ToString(); + } + + if (colorbar_rgb24_image != null) + { + pb_coloarbar_image.Image = util.ConvertRgb24ImageToBitmap(colorbar_rgb24_image); + } + if (mcb_mode.SelectedIndex == 0) + { + + pb_image.Image = util.ConvertRgb24ImageToBitmap(pseu_and_mark__rgb24_image); + + } + else if (mcb_mode.SelectedIndex == 1) + { + + pb_image.Image =util.ConvertL16ToBitmap(mark_L16_image); + + + + } + else if (mcb_mode.SelectedIndex == 2) + { + pb_image.Image = util.ConvertRgb24ImageToBitmap(pseu_rgb24_image); + + } + + curBitmap = (Bitmap)pb_image.Image; + } + + + + + + private void ImagePanel_Enter(object sender, EventArgs e) + { + this.BringToFront(); + RefreshUI(); + + + } + private void ImagePanel_FormClosing(object sender, FormClosingEventArgs e) + { + ImageToolMannage.imageDataPath.Remove(path); + paletteForm.Invalidate(); + paletteForm.Dispose(); + paletteForm = null; + } + + private void ImagePanel_Resize(object sender, EventArgs e) + { + if (pb_image.Image == null) return; + + + // 设置PictureBox的宽度和高度 + pb_image.Location = new System.Drawing.Point(pl_image.Location.X, pl_image.Location.Y); + pb_image.Width = pl_image.Width; + pb_image.Height = pl_image.Height; + + CenterPictureBox(); + } + + private void hhpb_save_Click(object sender, EventArgs e) + { + + // 创建一个位图,其大小与panel相同 + Bitmap bitmap = new Bitmap(tlpanl_image_bar.Width, tlpanl_image_bar.Height); + + // 将panel的视图渲染到位图上 + tlpanl_image_bar.DrawToBitmap(bitmap, new System.Drawing.Rectangle(0, 0, tlpanl_image_bar.Width, tlpanl_image_bar.Height)); + + // 弹出保存文件对话框 + using (SaveFileDialog saveFileDialog = new SaveFileDialog()) + { + saveFileDialog.Title = "保存Panel图像"; + saveFileDialog.Filter = "PNG 图片|*.png|JPEG 图片|*.jpg|BMP 图片|*.bmp"; + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + // 根据文件扩展名选择格式 + System.Drawing.Imaging.ImageFormat format = System.Drawing.Imaging.ImageFormat.Bmp; + switch (System.IO.Path.GetExtension(saveFileDialog.FileName).ToLower()) + { + case ".jpg": + format = System.Drawing.Imaging.ImageFormat.Jpeg; + break; + case ".bmp": + format = System.Drawing.Imaging.ImageFormat.Bmp; + break; + } + bitmap.Save(saveFileDialog.FileName, format); // 保存图像到文件 + +#if true //保存报告 + if (scientificON) + { + var records = new List(); + + // 目前只保存矩形下的光子数 + int index = 0; + foreach (var item in rectAndInfoList) + { + index++; + + DataRecordString dr = new DataRecordString(); + dr.index = index; + + dr.IOD =util.GetscientificNotation( item.pdinfovc.IOD); + dr.AOD = util.GetscientificNotation(item.pdinfovc.AOD); + dr.max = util.GetscientificNotation(item.pdinfovc.maxOD); + dr.min = util.GetscientificNotation(item.pdinfovc.minOD); + dr.Count = util.GetscientificNotation(item.pdinfovc.Count); + records.Add(dr); + } + foreach (var item in CircleAndInfoList) + { + index++; + + DataRecordString dr = new DataRecordString(); + dr.index = index; + + dr.IOD = util.GetscientificNotation(item.pdinfovc.IOD); + dr.AOD = util.GetscientificNotation(item.pdinfovc.AOD); + dr.max = util.GetscientificNotation(item.pdinfovc.maxOD); + dr.min = util.GetscientificNotation(item.pdinfovc.minOD); + dr.Count = util.GetscientificNotation(item.pdinfovc.Count); + records.Add(dr); + } + foreach (var item in PolygonAndInfoList) + { + index++; + + DataRecordString dr = new DataRecordString(); + dr.index = index; + + dr.IOD = util.GetscientificNotation(item.pdinfovc.IOD); + dr.AOD = util.GetscientificNotation(item.pdinfovc.AOD); + dr.max = util.GetscientificNotation(item.pdinfovc.maxOD); + dr.min = util.GetscientificNotation(item.pdinfovc.minOD); + dr.Count = util.GetscientificNotation(item.pdinfovc.Count); + records.Add(dr); + } + if (records.Count > 0) + { + string directoryPath = System.IO.Path.GetDirectoryName(saveFileDialog.FileName); + string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(saveFileDialog.FileName); + string path = directoryPath + "\\" + fileNameWithoutExtension + ".xlsx"; + if (File.Exists(path)) + { + try + { + File.Delete(path); + } + catch (Exception) + { + + MessageBox.Show("文件被占用,无法删除!!!"); + return; + } + } + MiniExcel.SaveAs(path, records); + } + } + else + { + var records = new List(); + + // 目前只保存矩形下的光子数 + int index = 0; + foreach (var item in rectAndInfoList) + { + index++; + + DataRecord dr = new DataRecord(); + dr.index = index; + dr.IOD = item.pdinfovc.IOD; + dr.AOD = item.pdinfovc.AOD; + dr.max = item.pdinfovc.maxOD; + dr.min = item.pdinfovc.minOD; + dr.Count = item.pdinfovc.Count; + records.Add(dr); + } + foreach (var item in CircleAndInfoList) + { + index++; + + DataRecord dr = new DataRecord(); + dr.index = index; + dr.IOD = item.pdinfovc.IOD; + dr.AOD = item.pdinfovc.AOD; + dr.max = item.pdinfovc.maxOD; + dr.min = item.pdinfovc.minOD; + dr.Count = item.pdinfovc.Count; + records.Add(dr); + } + foreach (var item in PolygonAndInfoList) + { + index++; + + DataRecord dr = new DataRecord(); + dr.index = index; + dr.IOD = item.pdinfovc.IOD; + dr.AOD = item.pdinfovc.AOD; + dr.max = item.pdinfovc.maxOD; + dr.min = item.pdinfovc.minOD; + dr.Count = item.pdinfovc.Count; + records.Add(dr); + } + if (records.Count > 0) + { + string directoryPath = System.IO.Path.GetDirectoryName(saveFileDialog.FileName); + string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(saveFileDialog.FileName); + string path = directoryPath + "\\" + fileNameWithoutExtension + ".xlsx"; + if (File.Exists(path)) + { + try + { + File.Delete(path); + } + catch (Exception) + { + + MessageBox.Show("文件被占用,无法删除!!!"); + return; + } + } + MiniExcel.SaveAs(path, records); + } + } + +#endif + } + } + + // 清理资源 + bitmap.Dispose(); + + + } + private void ImagePanel_MouseDown(object sender, MouseEventArgs e) + { + this.BringToFront(); + RefreshUI(); + } +#endregion + + #region 对外接口 + public Bitmap GetPseuImage + { + get + { + return util.ConvertRgb24ImageToBitmap(pseu_rgb24_image); + } + } + + + + private void cb_scientific_CheckedChanged(object sender) + { + scientificON = cb_scientific.Checked; + ThisRefresh(); + } + + public Bitmap GetMarkImage + { + get + { + return util.ConvertL16ToBitmap(mark_L16_image); + } + } + public Bitmap GetpseuAndMark + { + get + { + return util.ConvertRgb24ImageToBitmap(pseu_and_mark__rgb24_image); + } + } + public Bitmap pictureBox + { + get { return (Bitmap)pb_image.Image; } + } + public void initPicturebox() + { + pl_bg_image.Controls.Clear(); + pl_bg_image.Controls.Add(pb_image); + } + + public Image GetImage() + { + mcb_mode.SelectedIndex = 0; + pb_image.SaveToImage("2.bmp",System.Drawing.Imaging.ImageFormat.Bmp); + return pseu_and_mark__rgb24_image; + } + #endregion + } +} diff --git a/src/PBAnaly/UI/ImagePanel.resx b/src/PBAnaly/UI/ImagePanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/src/PBAnaly/UI/ImagePanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/PBAnaly/UI/ImagePanelUser.Designer.cs b/src/PBAnaly/UI/ImagePanelUser.Designer.cs new file mode 100644 index 0000000..39ad816 --- /dev/null +++ b/src/PBAnaly/UI/ImagePanelUser.Designer.cs @@ -0,0 +1,199 @@ +namespace PBAnaly.UI +{ + partial class ImagePanelUser + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); + this.tlpanl_image_bar = new System.Windows.Forms.TableLayoutPanel(); + this.pl_image = new ReaLTaiizor.Controls.Panel(); + this.pl_bg_image = new ReaLTaiizor.Controls.Panel(); + this.pb_image = new System.Windows.Forms.PictureBox(); + this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); + this.mlb_bottomLabel = new ReaLTaiizor.Controls.MoonLabel(); + this.tableLayoutPanel1.SuspendLayout(); + this.tableLayoutPanel3.SuspendLayout(); + this.tlpanl_image_bar.SuspendLayout(); + this.pl_image.SuspendLayout(); + this.pl_bg_image.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pb_image)).BeginInit(); + this.tableLayoutPanel4.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 15F)); + this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel3, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel4, 0, 2); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 3; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 22F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 12F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(456, 341); + this.tableLayoutPanel1.TabIndex = 1; + // + // tableLayoutPanel3 + // + this.tableLayoutPanel3.ColumnCount = 2; + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 86.27969F)); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 13.72032F)); + this.tableLayoutPanel3.Controls.Add(this.tlpanl_image_bar, 0, 0); + this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel3.Location = new System.Drawing.Point(2, 24); + this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(2); + this.tableLayoutPanel3.Name = "tableLayoutPanel3"; + this.tableLayoutPanel3.RowCount = 1; + this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel3.Size = new System.Drawing.Size(452, 303); + this.tableLayoutPanel3.TabIndex = 2; + // + // tlpanl_image_bar + // + this.tlpanl_image_bar.ColumnCount = 2; + this.tableLayoutPanel3.SetColumnSpan(this.tlpanl_image_bar, 2); + this.tlpanl_image_bar.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 86.62952F)); + this.tlpanl_image_bar.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 13.37047F)); + this.tlpanl_image_bar.Controls.Add(this.pl_image, 0, 0); + this.tlpanl_image_bar.Dock = System.Windows.Forms.DockStyle.Fill; + this.tlpanl_image_bar.Location = new System.Drawing.Point(0, 0); + this.tlpanl_image_bar.Margin = new System.Windows.Forms.Padding(0); + this.tlpanl_image_bar.Name = "tlpanl_image_bar"; + this.tlpanl_image_bar.RowCount = 2; + this.tlpanl_image_bar.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tlpanl_image_bar.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tlpanl_image_bar.Size = new System.Drawing.Size(452, 303); + this.tlpanl_image_bar.TabIndex = 2; + // + // pl_image + // + this.pl_image.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(39)))), ((int)(((byte)(51)))), ((int)(((byte)(63))))); + this.pl_image.Controls.Add(this.pl_bg_image); + this.pl_image.Dock = System.Windows.Forms.DockStyle.Fill; + this.pl_image.EdgeColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(41)))), ((int)(((byte)(50))))); + this.pl_image.Location = new System.Drawing.Point(2, 2); + this.pl_image.Margin = new System.Windows.Forms.Padding(2); + this.pl_image.Name = "pl_image"; + this.pl_image.Padding = new System.Windows.Forms.Padding(4); + this.tlpanl_image_bar.SetRowSpan(this.pl_image, 2); + this.pl_image.Size = new System.Drawing.Size(387, 299); + this.pl_image.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.pl_image.TabIndex = 0; + this.pl_image.Text = "panel1"; + // + // pl_bg_image + // + this.pl_bg_image.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(39)))), ((int)(((byte)(51)))), ((int)(((byte)(63))))); + this.pl_bg_image.Controls.Add(this.pb_image); + this.pl_bg_image.Dock = System.Windows.Forms.DockStyle.Fill; + this.pl_bg_image.EdgeColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(41)))), ((int)(((byte)(50))))); + this.pl_bg_image.Location = new System.Drawing.Point(4, 4); + this.pl_bg_image.Margin = new System.Windows.Forms.Padding(0); + this.pl_bg_image.Name = "pl_bg_image"; + this.pl_bg_image.Padding = new System.Windows.Forms.Padding(5); + this.pl_bg_image.Size = new System.Drawing.Size(379, 291); + this.pl_bg_image.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.pl_bg_image.TabIndex = 1; + this.pl_bg_image.Text = "panel1"; + // + // pb_image + // + this.pb_image.Dock = System.Windows.Forms.DockStyle.Fill; + this.pb_image.Image = global::PBAnaly.Properties.Resources.壁纸; + this.pb_image.Location = new System.Drawing.Point(5, 5); + this.pb_image.Margin = new System.Windows.Forms.Padding(0); + this.pb_image.Name = "pb_image"; + this.pb_image.Size = new System.Drawing.Size(369, 281); + this.pb_image.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.pb_image.TabIndex = 0; + this.pb_image.TabStop = false; + // + // tableLayoutPanel4 + // + this.tableLayoutPanel4.ColumnCount = 2; + this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 80.93587F)); + this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 19.06413F)); + this.tableLayoutPanel4.Controls.Add(this.mlb_bottomLabel, 0, 0); + this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 329); + this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); + this.tableLayoutPanel4.Name = "tableLayoutPanel4"; + this.tableLayoutPanel4.RowCount = 1; + this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel4.Size = new System.Drawing.Size(456, 12); + this.tableLayoutPanel4.TabIndex = 3; + // + // mlb_bottomLabel + // + this.mlb_bottomLabel.AutoSize = true; + this.mlb_bottomLabel.BackColor = System.Drawing.Color.Transparent; + this.mlb_bottomLabel.Dock = System.Windows.Forms.DockStyle.Fill; + this.mlb_bottomLabel.ForeColor = System.Drawing.Color.Gray; + this.mlb_bottomLabel.Location = new System.Drawing.Point(2, 0); + this.mlb_bottomLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.mlb_bottomLabel.Name = "mlb_bottomLabel"; + this.mlb_bottomLabel.Size = new System.Drawing.Size(365, 12); + this.mlb_bottomLabel.TabIndex = 0; + this.mlb_bottomLabel.Text = "1920x1080 "; + this.mlb_bottomLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // ImagePanelUser + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.tableLayoutPanel1); + this.Name = "ImagePanelUser"; + this.Size = new System.Drawing.Size(456, 341); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel3.ResumeLayout(false); + this.tlpanl_image_bar.ResumeLayout(false); + this.pl_image.ResumeLayout(false); + this.pl_bg_image.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pb_image)).EndInit(); + this.tableLayoutPanel4.ResumeLayout(false); + this.tableLayoutPanel4.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + private System.Windows.Forms.TableLayoutPanel tlpanl_image_bar; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; + private ReaLTaiizor.Controls.Panel pl_image; + private ReaLTaiizor.Controls.Panel pl_bg_image; + private System.Windows.Forms.PictureBox pb_image; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4; + private ReaLTaiizor.Controls.MoonLabel mlb_bottomLabel; + } +} diff --git a/src/PBAnaly/UI/ImagePanelUser.cs b/src/PBAnaly/UI/ImagePanelUser.cs new file mode 100644 index 0000000..9739309 --- /dev/null +++ b/src/PBAnaly/UI/ImagePanelUser.cs @@ -0,0 +1,22 @@ +using PBAnaly.Module; +using PBBiologyVC; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace PBAnaly.UI +{ + public partial class ImagePanelUser : UserControl + { + + } +} diff --git a/src/PBAnaly/UI/ImagePanelUser.resx b/src/PBAnaly/UI/ImagePanelUser.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/src/PBAnaly/UI/ImagePanelUser.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/PBAnaly/UI/ImageToolPaletteForm.Designer.cs b/src/PBAnaly/UI/ImageToolPaletteForm.Designer.cs new file mode 100644 index 0000000..1bb3ad4 --- /dev/null +++ b/src/PBAnaly/UI/ImageToolPaletteForm.Designer.cs @@ -0,0 +1,781 @@ +namespace PBAnaly.UI +{ + partial class ImageToolPaletteForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.cll_panel = new AntdUI.Collapse(); + this.collapseItem1 = new AntdUI.CollapseItem(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.panel1 = new AntdUI.Panel(); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.foxLabel8 = new ReaLTaiizor.Controls.FoxLabel(); + this.flb_act_mm = new ReaLTaiizor.Controls.FoxLabel(); + this.nud_opacity = new System.Windows.Forms.NumericUpDown(); + this.nud_brightness = new System.Windows.Forms.NumericUpDown(); + this.mts_color_max = new MaterialSkin.Controls.MaterialSlider(); + this.mts_color_min = new MaterialSkin.Controls.MaterialSlider(); + this.foxLabel9 = new ReaLTaiizor.Controls.FoxLabel(); + this.foxLabel6 = new ReaLTaiizor.Controls.FoxLabel(); + this.foxLabel2 = new ReaLTaiizor.Controls.FoxLabel(); + this.mts_opacity = new MaterialSkin.Controls.MaterialSlider(); + this.foxLabel3 = new ReaLTaiizor.Controls.FoxLabel(); + this.mts_brightness = new MaterialSkin.Controls.MaterialSlider(); + this.foxLabel1 = new ReaLTaiizor.Controls.FoxLabel(); + this.hpb_line = new ReaLTaiizor.Controls.HopePictureBox(); + this.nud_color_min = new System.Windows.Forms.NumericUpDown(); + this.nud_color_max = new System.Windows.Forms.NumericUpDown(); + this.cb_colortable = new System.Windows.Forms.ComboBox(); + this.pb_bgimage = new System.Windows.Forms.PictureBox(); + this.collapseItem2 = new AntdUI.CollapseItem(); + this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); + this.hpb_wand = new ReaLTaiizor.Controls.HopePictureBox(); + this.hpb_xianduan = new ReaLTaiizor.Controls.HopePictureBox(); + this.hpb_circe = new ReaLTaiizor.Controls.HopePictureBox(); + this.hpb_rect = new ReaLTaiizor.Controls.HopePictureBox(); + this.panel2 = new AntdUI.Panel(); + this.fb_fixSetting = new ReaLTaiizor.Controls.FoxButton(); + this.ftb_r = new ReaLTaiizor.Controls.FoxTextBox(); + this.foxLabel7 = new ReaLTaiizor.Controls.FoxLabel(); + this.ftb_h = new ReaLTaiizor.Controls.FoxTextBox(); + this.foxLabel5 = new ReaLTaiizor.Controls.FoxLabel(); + this.ftb_w = new ReaLTaiizor.Controls.FoxTextBox(); + this.foxLabel4 = new ReaLTaiizor.Controls.FoxLabel(); + this.cll_panel.SuspendLayout(); + this.collapseItem1.SuspendLayout(); + this.tableLayoutPanel1.SuspendLayout(); + this.panel1.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nud_opacity)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nud_brightness)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_line)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nud_color_min)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nud_color_max)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pb_bgimage)).BeginInit(); + this.collapseItem2.SuspendLayout(); + this.tableLayoutPanel3.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_wand)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_xianduan)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_circe)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_rect)).BeginInit(); + this.panel2.SuspendLayout(); + this.SuspendLayout(); + // + // cll_panel + // + this.cll_panel.Cursor = System.Windows.Forms.Cursors.Hand; + this.cll_panel.Dock = System.Windows.Forms.DockStyle.Fill; + this.cll_panel.HeaderBg = System.Drawing.Color.FromArgb(((int)(((byte)(186)))), ((int)(((byte)(179)))), ((int)(((byte)(179))))); + this.cll_panel.Items.Add(this.collapseItem1); + this.cll_panel.Items.Add(this.collapseItem2); + this.cll_panel.Location = new System.Drawing.Point(2, 19); + this.cll_panel.Name = "cll_panel"; + this.cll_panel.Size = new System.Drawing.Size(367, 606); + this.cll_panel.TabIndex = 0; + this.cll_panel.Text = "fed"; + // + // collapseItem1 + // + this.collapseItem1.Controls.Add(this.tableLayoutPanel1); + this.collapseItem1.Expand = true; + this.collapseItem1.Location = new System.Drawing.Point(19, 59); + this.collapseItem1.Name = "collapseItem1"; + this.collapseItem1.Size = new System.Drawing.Size(329, 207); + this.collapseItem1.TabIndex = 0; + this.collapseItem1.Text = "图像调整"; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel1.Controls.Add(this.panel1, 0, 0); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 3; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 181F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(329, 207); + this.tableLayoutPanel1.TabIndex = 0; + // + // panel1 + // + this.panel1.Controls.Add(this.tableLayoutPanel2); + this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel1.Location = new System.Drawing.Point(3, 3); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(323, 175); + this.panel1.TabIndex = 0; + this.panel1.Text = "panel1"; + // + // tableLayoutPanel2 + // + this.tableLayoutPanel2.ColumnCount = 5; + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50F)); + this.tableLayoutPanel2.Controls.Add(this.foxLabel8, 0, 6); + this.tableLayoutPanel2.Controls.Add(this.flb_act_mm, 3, 5); + this.tableLayoutPanel2.Controls.Add(this.nud_opacity, 4, 1); + this.tableLayoutPanel2.Controls.Add(this.nud_brightness, 4, 0); + this.tableLayoutPanel2.Controls.Add(this.mts_color_max, 1, 4); + this.tableLayoutPanel2.Controls.Add(this.mts_color_min, 1, 3); + this.tableLayoutPanel2.Controls.Add(this.foxLabel9, 0, 4); + this.tableLayoutPanel2.Controls.Add(this.foxLabel6, 0, 3); + this.tableLayoutPanel2.Controls.Add(this.foxLabel2, 0, 2); + this.tableLayoutPanel2.Controls.Add(this.mts_opacity, 1, 1); + this.tableLayoutPanel2.Controls.Add(this.foxLabel3, 0, 1); + this.tableLayoutPanel2.Controls.Add(this.mts_brightness, 1, 0); + this.tableLayoutPanel2.Controls.Add(this.foxLabel1, 0, 0); + this.tableLayoutPanel2.Controls.Add(this.hpb_line, 0, 5); + this.tableLayoutPanel2.Controls.Add(this.nud_color_min, 4, 3); + this.tableLayoutPanel2.Controls.Add(this.nud_color_max, 4, 4); + this.tableLayoutPanel2.Controls.Add(this.cb_colortable, 0, 7); + this.tableLayoutPanel2.Controls.Add(this.pb_bgimage, 3, 7); + this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + this.tableLayoutPanel2.RowCount = 9; + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 19F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 19F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.Size = new System.Drawing.Size(323, 175); + this.tableLayoutPanel2.TabIndex = 0; + // + // foxLabel8 + // + this.foxLabel8.BackColor = System.Drawing.Color.Transparent; + this.tableLayoutPanel2.SetColumnSpan(this.foxLabel8, 4); + this.foxLabel8.Dock = System.Windows.Forms.DockStyle.Fill; + this.foxLabel8.Font = new System.Drawing.Font("宋体", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.foxLabel8.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(88)))), ((int)(((byte)(100))))); + this.foxLabel8.Location = new System.Drawing.Point(3, 130); + this.foxLabel8.Name = "foxLabel8"; + this.foxLabel8.Size = new System.Drawing.Size(267, 14); + this.foxLabel8.TabIndex = 34; + this.foxLabel8.Text = "Color Rable"; + // + // flb_act_mm + // + this.flb_act_mm.BackColor = System.Drawing.Color.Transparent; + this.flb_act_mm.Dock = System.Windows.Forms.DockStyle.Fill; + this.flb_act_mm.Font = new System.Drawing.Font("宋体", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.flb_act_mm.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(88)))), ((int)(((byte)(100))))); + this.flb_act_mm.Location = new System.Drawing.Point(93, 110); + this.flb_act_mm.Name = "flb_act_mm"; + this.flb_act_mm.Size = new System.Drawing.Size(177, 14); + this.flb_act_mm.TabIndex = 30; + this.flb_act_mm.Text = "0 mm"; + // + // nud_opacity + // + this.nud_opacity.Dock = System.Windows.Forms.DockStyle.Fill; + this.nud_opacity.Location = new System.Drawing.Point(276, 22); + this.nud_opacity.Name = "nud_opacity"; + this.nud_opacity.Size = new System.Drawing.Size(44, 21); + this.nud_opacity.TabIndex = 27; + this.nud_opacity.Value = new decimal(new int[] { + 100, + 0, + 0, + 0}); + this.nud_opacity.ValueChanged += new System.EventHandler(this.nud_opacity_ValueChanged); + // + // nud_brightness + // + this.nud_brightness.Dock = System.Windows.Forms.DockStyle.Fill; + this.nud_brightness.Location = new System.Drawing.Point(276, 3); + this.nud_brightness.Maximum = new decimal(new int[] { + 254, + 0, + 0, + 0}); + this.nud_brightness.Name = "nud_brightness"; + this.nud_brightness.Size = new System.Drawing.Size(44, 21); + this.nud_brightness.TabIndex = 26; + this.nud_brightness.Value = new decimal(new int[] { + 127, + 0, + 0, + 0}); + this.nud_brightness.ValueChanged += new System.EventHandler(this.nud_brightness_ValueChanged); + // + // mts_color_max + // + this.mts_color_max.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tableLayoutPanel2.SetColumnSpan(this.mts_color_max, 3); + this.mts_color_max.Depth = 0; + this.mts_color_max.Font = new System.Drawing.Font("Roboto", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.mts_color_max.FontType = MaterialSkin.MaterialSkinManager.fontType.Body2; + this.mts_color_max.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(222)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.mts_color_max.Location = new System.Drawing.Point(53, 88); + this.mts_color_max.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3); + this.mts_color_max.MaximumSize = new System.Drawing.Size(0, 10); + this.mts_color_max.MouseState = MaterialSkin.MouseState.HOVER; + this.mts_color_max.Name = "mts_color_max"; + this.mts_color_max.RangeMax = 65535; + this.mts_color_max.RangeMin = 5; + this.mts_color_max.ShowText = false; + this.mts_color_max.ShowValue = false; + this.mts_color_max.Size = new System.Drawing.Size(217, 10); + this.mts_color_max.TabIndex = 23; + this.mts_color_max.Text = "materialSlider5"; + this.mts_color_max.Value = 20; + this.mts_color_max.ValueMax = 65535; + this.mts_color_max.onValueChanged += new MaterialSkin.Controls.MaterialSlider.ValueChanged(this.mts_color_max_onValueChanged); + // + // mts_color_min + // + this.tableLayoutPanel2.SetColumnSpan(this.mts_color_min, 3); + this.mts_color_min.Depth = 0; + this.mts_color_min.Dock = System.Windows.Forms.DockStyle.Fill; + this.mts_color_min.Font = new System.Drawing.Font("Roboto", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.mts_color_min.FontType = MaterialSkin.MaterialSkinManager.fontType.Body2; + this.mts_color_min.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(222)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.mts_color_min.Location = new System.Drawing.Point(53, 63); + this.mts_color_min.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3); + this.mts_color_min.MaximumSize = new System.Drawing.Size(0, 10); + this.mts_color_min.MouseState = MaterialSkin.MouseState.HOVER; + this.mts_color_min.Name = "mts_color_min"; + this.mts_color_min.RangeMax = 65535; + this.mts_color_min.RangeMin = 5; + this.mts_color_min.ShowText = false; + this.mts_color_min.ShowValue = false; + this.mts_color_min.Size = new System.Drawing.Size(217, 10); + this.mts_color_min.TabIndex = 21; + this.mts_color_min.Text = "materialSlider3"; + this.mts_color_min.Value = 5; + this.mts_color_min.ValueMax = 65535; + this.mts_color_min.onValueChanged += new MaterialSkin.Controls.MaterialSlider.ValueChanged(this.mts_color_min_onValueChanged); + // + // foxLabel9 + // + this.foxLabel9.BackColor = System.Drawing.Color.Transparent; + this.foxLabel9.Dock = System.Windows.Forms.DockStyle.Fill; + this.foxLabel9.Font = new System.Drawing.Font("宋体", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.foxLabel9.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(88)))), ((int)(((byte)(100))))); + this.foxLabel9.Location = new System.Drawing.Point(3, 86); + this.foxLabel9.Name = "foxLabel9"; + this.foxLabel9.Size = new System.Drawing.Size(44, 18); + this.foxLabel9.TabIndex = 18; + this.foxLabel9.Text = "Max"; + // + // foxLabel6 + // + this.foxLabel6.BackColor = System.Drawing.Color.Transparent; + this.foxLabel6.Dock = System.Windows.Forms.DockStyle.Fill; + this.foxLabel6.Font = new System.Drawing.Font("宋体", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.foxLabel6.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(88)))), ((int)(((byte)(100))))); + this.foxLabel6.Location = new System.Drawing.Point(3, 61); + this.foxLabel6.Name = "foxLabel6"; + this.foxLabel6.Size = new System.Drawing.Size(44, 19); + this.foxLabel6.TabIndex = 13; + this.foxLabel6.Text = "Min"; + // + // foxLabel2 + // + this.foxLabel2.BackColor = System.Drawing.Color.Transparent; + this.foxLabel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.foxLabel2.Font = new System.Drawing.Font("宋体", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.foxLabel2.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(88)))), ((int)(((byte)(100))))); + this.foxLabel2.Location = new System.Drawing.Point(3, 41); + this.foxLabel2.Name = "foxLabel2"; + this.foxLabel2.Size = new System.Drawing.Size(44, 14); + this.foxLabel2.TabIndex = 10; + this.foxLabel2.Text = "色阶"; + // + // mts_opacity + // + this.tableLayoutPanel2.SetColumnSpan(this.mts_opacity, 3); + this.mts_opacity.Depth = 0; + this.mts_opacity.Dock = System.Windows.Forms.DockStyle.Fill; + this.mts_opacity.Font = new System.Drawing.Font("Roboto", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.mts_opacity.FontType = MaterialSkin.MaterialSkinManager.fontType.Body2; + this.mts_opacity.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(222)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.mts_opacity.Location = new System.Drawing.Point(53, 22); + this.mts_opacity.MaximumSize = new System.Drawing.Size(0, 10); + this.mts_opacity.MouseState = MaterialSkin.MouseState.HOVER; + this.mts_opacity.Name = "mts_opacity"; + this.mts_opacity.ShowText = false; + this.mts_opacity.ShowValue = false; + this.mts_opacity.Size = new System.Drawing.Size(217, 10); + this.mts_opacity.TabIndex = 7; + this.mts_opacity.Text = "mts_opacity"; + this.mts_opacity.onValueChanged += new MaterialSkin.Controls.MaterialSlider.ValueChanged(this.mts_opacity_onValueChanged); + // + // foxLabel3 + // + this.foxLabel3.BackColor = System.Drawing.Color.Transparent; + this.foxLabel3.Dock = System.Windows.Forms.DockStyle.Fill; + this.foxLabel3.Font = new System.Drawing.Font("宋体", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.foxLabel3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(88)))), ((int)(((byte)(100))))); + this.foxLabel3.Location = new System.Drawing.Point(3, 22); + this.foxLabel3.Name = "foxLabel3"; + this.foxLabel3.Size = new System.Drawing.Size(44, 13); + this.foxLabel3.TabIndex = 6; + this.foxLabel3.Text = "透明度::"; + // + // mts_brightness + // + this.tableLayoutPanel2.SetColumnSpan(this.mts_brightness, 3); + this.mts_brightness.Depth = 0; + this.mts_brightness.Dock = System.Windows.Forms.DockStyle.Fill; + this.mts_brightness.Font = new System.Drawing.Font("Roboto", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel); + this.mts_brightness.FontType = MaterialSkin.MaterialSkinManager.fontType.Body2; + this.mts_brightness.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(222)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.mts_brightness.Location = new System.Drawing.Point(53, 3); + this.mts_brightness.MaximumSize = new System.Drawing.Size(0, 10); + this.mts_brightness.MouseState = MaterialSkin.MouseState.HOVER; + this.mts_brightness.Name = "mts_brightness"; + this.mts_brightness.RangeMax = 254; + this.mts_brightness.ShowText = false; + this.mts_brightness.ShowValue = false; + this.mts_brightness.Size = new System.Drawing.Size(217, 10); + this.mts_brightness.TabIndex = 0; + this.mts_brightness.Text = "mts_brightness"; + this.mts_brightness.ValueMax = 254; + this.mts_brightness.onValueChanged += new MaterialSkin.Controls.MaterialSlider.ValueChanged(this.mts_brightness_onValueChanged); + // + // foxLabel1 + // + this.foxLabel1.BackColor = System.Drawing.Color.Transparent; + this.foxLabel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.foxLabel1.Font = new System.Drawing.Font("宋体", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.foxLabel1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(88)))), ((int)(((byte)(100))))); + this.foxLabel1.Location = new System.Drawing.Point(3, 3); + this.foxLabel1.Name = "foxLabel1"; + this.foxLabel1.Size = new System.Drawing.Size(44, 13); + this.foxLabel1.TabIndex = 1; + this.foxLabel1.Text = "亮度:"; + // + // hpb_line + // + this.hpb_line.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(196)))), ((int)(((byte)(204))))); + this.hpb_line.Dock = System.Windows.Forms.DockStyle.Fill; + this.hpb_line.Image = global::PBAnaly.Properties.Resources.线段; + this.hpb_line.Location = new System.Drawing.Point(3, 110); + this.hpb_line.Name = "hpb_line"; + this.hpb_line.PixelOffsetType = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; + this.hpb_line.Size = new System.Drawing.Size(44, 14); + this.hpb_line.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.hpb_line.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.hpb_line.TabIndex = 9; + this.hpb_line.TabStop = false; + this.hpb_line.TextRenderingType = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + this.hpb_line.Click += new System.EventHandler(this.hpb_line_Click); + // + // nud_color_min + // + this.nud_color_min.Dock = System.Windows.Forms.DockStyle.Fill; + this.nud_color_min.Location = new System.Drawing.Point(276, 61); + this.nud_color_min.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.nud_color_min.Minimum = new decimal(new int[] { + 5, + 0, + 0, + 0}); + this.nud_color_min.Name = "nud_color_min"; + this.nud_color_min.Size = new System.Drawing.Size(44, 21); + this.nud_color_min.TabIndex = 24; + this.nud_color_min.Value = new decimal(new int[] { + 6000, + 0, + 0, + 0}); + this.nud_color_min.ValueChanged += new System.EventHandler(this.nud_color_min_ValueChanged); + // + // nud_color_max + // + this.nud_color_max.Dock = System.Windows.Forms.DockStyle.Fill; + this.nud_color_max.Location = new System.Drawing.Point(276, 86); + this.nud_color_max.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.nud_color_max.Minimum = new decimal(new int[] { + 10, + 0, + 0, + 0}); + this.nud_color_max.Name = "nud_color_max"; + this.nud_color_max.Size = new System.Drawing.Size(44, 21); + this.nud_color_max.TabIndex = 25; + this.nud_color_max.Value = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.nud_color_max.ValueChanged += new System.EventHandler(this.nud_color_max_ValueChanged); + // + // cb_colortable + // + this.tableLayoutPanel2.SetColumnSpan(this.cb_colortable, 3); + this.cb_colortable.Dock = System.Windows.Forms.DockStyle.Fill; + this.cb_colortable.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cb_colortable.FormattingEnabled = true; + this.cb_colortable.Items.AddRange(new object[] { + "YellowHot", + "Black_Red", + "Black_Green", + "Black_Blue", + "Black_Yley", + "RGB", + "Pseudo", + "Gray"}); + this.cb_colortable.Location = new System.Drawing.Point(3, 150); + this.cb_colortable.Name = "cb_colortable"; + this.cb_colortable.Size = new System.Drawing.Size(84, 20); + this.cb_colortable.TabIndex = 35; + this.cb_colortable.SelectedIndexChanged += new System.EventHandler(this.cb_colortable_SelectedIndexChanged); + // + // pb_bgimage + // + this.pb_bgimage.Dock = System.Windows.Forms.DockStyle.Fill; + this.pb_bgimage.Location = new System.Drawing.Point(90, 147); + this.pb_bgimage.Margin = new System.Windows.Forms.Padding(0); + this.pb_bgimage.Name = "pb_bgimage"; + this.pb_bgimage.Size = new System.Drawing.Size(183, 20); + this.pb_bgimage.TabIndex = 36; + this.pb_bgimage.TabStop = false; + // + // collapseItem2 + // + this.collapseItem2.Controls.Add(this.tableLayoutPanel3); + this.collapseItem2.Expand = true; + this.collapseItem2.Location = new System.Drawing.Point(19, 338); + this.collapseItem2.Name = "collapseItem2"; + this.collapseItem2.Size = new System.Drawing.Size(329, 113); + this.collapseItem2.TabIndex = 1; + this.collapseItem2.Text = "ROI工具"; + // + // tableLayoutPanel3 + // + this.tableLayoutPanel3.ColumnCount = 5; + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 34F)); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 34F)); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 34F)); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 34F)); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel3.Controls.Add(this.hpb_wand, 3, 0); + this.tableLayoutPanel3.Controls.Add(this.hpb_xianduan, 2, 0); + this.tableLayoutPanel3.Controls.Add(this.hpb_circe, 1, 0); + this.tableLayoutPanel3.Controls.Add(this.hpb_rect, 0, 0); + this.tableLayoutPanel3.Controls.Add(this.panel2, 0, 1); + this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(0); + this.tableLayoutPanel3.Name = "tableLayoutPanel3"; + this.tableLayoutPanel3.RowCount = 2; + this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 34F)); + this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel3.Size = new System.Drawing.Size(329, 113); + this.tableLayoutPanel3.TabIndex = 0; + // + // hpb_wand + // + this.hpb_wand.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(196)))), ((int)(((byte)(204))))); + this.hpb_wand.Image = global::PBAnaly.Properties.Resources.魔术棒_魔法_魔术_一键; + this.hpb_wand.Location = new System.Drawing.Point(105, 3); + this.hpb_wand.Name = "hpb_wand"; + this.hpb_wand.PixelOffsetType = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; + this.hpb_wand.Size = new System.Drawing.Size(28, 28); + this.hpb_wand.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.hpb_wand.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.hpb_wand.TabIndex = 13; + this.hpb_wand.TabStop = false; + this.hpb_wand.TextRenderingType = System.Drawing.Text.TextRenderingHint.SystemDefault; + this.hpb_wand.Click += new System.EventHandler(this.hpb_wand_Click); + // + // hpb_xianduan + // + this.hpb_xianduan.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(196)))), ((int)(((byte)(204))))); + this.hpb_xianduan.Image = global::PBAnaly.Properties.Resources.线段__1_; + this.hpb_xianduan.Location = new System.Drawing.Point(71, 3); + this.hpb_xianduan.Name = "hpb_xianduan"; + this.hpb_xianduan.PixelOffsetType = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; + this.hpb_xianduan.Size = new System.Drawing.Size(28, 28); + this.hpb_xianduan.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.hpb_xianduan.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.hpb_xianduan.TabIndex = 12; + this.hpb_xianduan.TabStop = false; + this.hpb_xianduan.TextRenderingType = System.Drawing.Text.TextRenderingHint.SystemDefault; + this.hpb_xianduan.Click += new System.EventHandler(this.hpb_xianduan_Click); + // + // hpb_circe + // + this.hpb_circe.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(196)))), ((int)(((byte)(204))))); + this.hpb_circe.Image = global::PBAnaly.Properties.Resources.圆形1; + this.hpb_circe.Location = new System.Drawing.Point(37, 3); + this.hpb_circe.Name = "hpb_circe"; + this.hpb_circe.PixelOffsetType = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; + this.hpb_circe.Size = new System.Drawing.Size(28, 28); + this.hpb_circe.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.hpb_circe.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.hpb_circe.TabIndex = 11; + this.hpb_circe.TabStop = false; + this.hpb_circe.TextRenderingType = System.Drawing.Text.TextRenderingHint.SystemDefault; + this.hpb_circe.Click += new System.EventHandler(this.hpb_circe_Click); + // + // hpb_rect + // + this.hpb_rect.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(196)))), ((int)(((byte)(204))))); + this.hpb_rect.Dock = System.Windows.Forms.DockStyle.Fill; + this.hpb_rect.Image = global::PBAnaly.Properties.Resources._10矩形; + this.hpb_rect.Location = new System.Drawing.Point(2, 2); + this.hpb_rect.Margin = new System.Windows.Forms.Padding(2); + this.hpb_rect.Name = "hpb_rect"; + this.hpb_rect.PixelOffsetType = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; + this.hpb_rect.Size = new System.Drawing.Size(30, 30); + this.hpb_rect.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.hpb_rect.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + this.hpb_rect.TabIndex = 10; + this.hpb_rect.TabStop = false; + this.hpb_rect.TextRenderingType = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + this.hpb_rect.Click += new System.EventHandler(this.hpb_rect_Click); + // + // panel2 + // + this.tableLayoutPanel3.SetColumnSpan(this.panel2, 5); + this.panel2.Controls.Add(this.fb_fixSetting); + this.panel2.Controls.Add(this.ftb_r); + this.panel2.Controls.Add(this.foxLabel7); + this.panel2.Controls.Add(this.ftb_h); + this.panel2.Controls.Add(this.foxLabel5); + this.panel2.Controls.Add(this.ftb_w); + this.panel2.Controls.Add(this.foxLabel4); + this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel2.Location = new System.Drawing.Point(3, 37); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(323, 73); + this.panel2.TabIndex = 14; + this.panel2.Text = "panel2"; + // + // fb_fixSetting + // + this.fb_fixSetting.BackColor = System.Drawing.Color.Transparent; + this.fb_fixSetting.BaseColor = System.Drawing.Color.FromArgb(((int)(((byte)(249)))), ((int)(((byte)(249)))), ((int)(((byte)(249))))); + this.fb_fixSetting.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(193)))), ((int)(((byte)(193)))), ((int)(((byte)(193))))); + this.fb_fixSetting.Cursor = System.Windows.Forms.Cursors.Hand; + this.fb_fixSetting.DisabledBaseColor = System.Drawing.Color.FromArgb(((int)(((byte)(249)))), ((int)(((byte)(249)))), ((int)(((byte)(249))))); + this.fb_fixSetting.DisabledBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(209)))), ((int)(((byte)(209)))), ((int)(((byte)(209))))); + this.fb_fixSetting.DisabledTextColor = System.Drawing.Color.FromArgb(((int)(((byte)(166)))), ((int)(((byte)(178)))), ((int)(((byte)(190))))); + this.fb_fixSetting.DownColor = System.Drawing.Color.FromArgb(((int)(((byte)(232)))), ((int)(((byte)(232)))), ((int)(((byte)(232))))); + this.fb_fixSetting.EnabledCalc = true; + this.fb_fixSetting.Font = new System.Drawing.Font("Segoe UI", 10F); + this.fb_fixSetting.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(66)))), ((int)(((byte)(78)))), ((int)(((byte)(90))))); + this.fb_fixSetting.Location = new System.Drawing.Point(120, 30); + this.fb_fixSetting.Name = "fb_fixSetting"; + this.fb_fixSetting.OverColor = System.Drawing.Color.FromArgb(((int)(((byte)(242)))), ((int)(((byte)(242)))), ((int)(((byte)(242))))); + this.fb_fixSetting.Size = new System.Drawing.Size(59, 31); + this.fb_fixSetting.TabIndex = 6; + this.fb_fixSetting.Text = "修改"; + this.fb_fixSetting.Visible = false; + this.fb_fixSetting.Click += new ReaLTaiizor.Util.FoxBase.ButtonFoxBase.ClickEventHandler(this.fb_fixSetting_Click); + // + // ftb_r + // + this.ftb_r.BackColor = System.Drawing.Color.Transparent; + this.ftb_r.Cursor = System.Windows.Forms.Cursors.Hand; + this.ftb_r.EnabledCalc = true; + this.ftb_r.Font = new System.Drawing.Font("Segoe UI", 10F); + this.ftb_r.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(66)))), ((int)(((byte)(78)))), ((int)(((byte)(90))))); + this.ftb_r.Location = new System.Drawing.Point(151, 2); + this.ftb_r.MaxLength = 32767; + this.ftb_r.MultiLine = false; + this.ftb_r.Name = "ftb_r"; + this.ftb_r.ReadOnly = false; + this.ftb_r.Size = new System.Drawing.Size(75, 22); + this.ftb_r.TabIndex = 5; + this.ftb_r.Text = "10"; + this.ftb_r.TextAlign = System.Windows.Forms.HorizontalAlignment.Left; + this.ftb_r.UseSystemPasswordChar = false; + // + // foxLabel7 + // + this.foxLabel7.BackColor = System.Drawing.Color.Transparent; + this.foxLabel7.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold); + this.foxLabel7.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(88)))), ((int)(((byte)(100))))); + this.foxLabel7.Location = new System.Drawing.Point(120, 5); + this.foxLabel7.Name = "foxLabel7"; + this.foxLabel7.Size = new System.Drawing.Size(26, 19); + this.foxLabel7.TabIndex = 4; + this.foxLabel7.Text = "r="; + // + // ftb_h + // + this.ftb_h.BackColor = System.Drawing.Color.Transparent; + this.ftb_h.Cursor = System.Windows.Forms.Cursors.Hand; + this.ftb_h.EnabledCalc = true; + this.ftb_h.Font = new System.Drawing.Font("Segoe UI", 10F); + this.ftb_h.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(66)))), ((int)(((byte)(78)))), ((int)(((byte)(90))))); + this.ftb_h.Location = new System.Drawing.Point(34, 28); + this.ftb_h.MaxLength = 32767; + this.ftb_h.MultiLine = false; + this.ftb_h.Name = "ftb_h"; + this.ftb_h.ReadOnly = false; + this.ftb_h.Size = new System.Drawing.Size(75, 22); + this.ftb_h.TabIndex = 3; + this.ftb_h.Text = "20"; + this.ftb_h.TextAlign = System.Windows.Forms.HorizontalAlignment.Left; + this.ftb_h.UseSystemPasswordChar = false; + // + // foxLabel5 + // + this.foxLabel5.BackColor = System.Drawing.Color.Transparent; + this.foxLabel5.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold); + this.foxLabel5.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(88)))), ((int)(((byte)(100))))); + this.foxLabel5.Location = new System.Drawing.Point(3, 31); + this.foxLabel5.Name = "foxLabel5"; + this.foxLabel5.Size = new System.Drawing.Size(26, 19); + this.foxLabel5.TabIndex = 2; + this.foxLabel5.Text = "h="; + // + // ftb_w + // + this.ftb_w.BackColor = System.Drawing.Color.Transparent; + this.ftb_w.Cursor = System.Windows.Forms.Cursors.Hand; + this.ftb_w.EnabledCalc = true; + this.ftb_w.Font = new System.Drawing.Font("Segoe UI", 10F); + this.ftb_w.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(66)))), ((int)(((byte)(78)))), ((int)(((byte)(90))))); + this.ftb_w.Location = new System.Drawing.Point(34, 0); + this.ftb_w.MaxLength = 32767; + this.ftb_w.MultiLine = false; + this.ftb_w.Name = "ftb_w"; + this.ftb_w.ReadOnly = false; + this.ftb_w.Size = new System.Drawing.Size(75, 22); + this.ftb_w.TabIndex = 1; + this.ftb_w.Text = "20"; + this.ftb_w.TextAlign = System.Windows.Forms.HorizontalAlignment.Left; + this.ftb_w.UseSystemPasswordChar = false; + // + // foxLabel4 + // + this.foxLabel4.BackColor = System.Drawing.Color.Transparent; + this.foxLabel4.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold); + this.foxLabel4.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(76)))), ((int)(((byte)(88)))), ((int)(((byte)(100))))); + this.foxLabel4.Location = new System.Drawing.Point(3, 3); + this.foxLabel4.Name = "foxLabel4"; + this.foxLabel4.Size = new System.Drawing.Size(26, 19); + this.foxLabel4.TabIndex = 0; + this.foxLabel4.Text = "w="; + // + // ImageToolPaletteForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(371, 627); + this.ControlBox = false; + this.Controls.Add(this.cll_panel); + this.FormStyle = MaterialSkin.Controls.MaterialForm.FormStyles.ActionBar_None; + this.Margin = new System.Windows.Forms.Padding(2); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ImageToolPaletteForm"; + this.Padding = new System.Windows.Forms.Padding(2, 19, 2, 2); + this.Text = "ImageToolPaletteForm"; + this.cll_panel.ResumeLayout(false); + this.collapseItem1.ResumeLayout(false); + this.tableLayoutPanel1.ResumeLayout(false); + this.panel1.ResumeLayout(false); + this.tableLayoutPanel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.nud_opacity)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nud_brightness)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_line)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nud_color_min)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nud_color_max)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pb_bgimage)).EndInit(); + this.collapseItem2.ResumeLayout(false); + this.tableLayoutPanel3.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.hpb_wand)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_xianduan)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_circe)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.hpb_rect)).EndInit(); + this.panel2.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private AntdUI.Collapse cll_panel; + private AntdUI.CollapseItem collapseItem1; + private AntdUI.CollapseItem collapseItem2; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private AntdUI.Panel panel1; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; + private MaterialSkin.Controls.MaterialSlider mts_brightness; + private ReaLTaiizor.Controls.FoxLabel foxLabel1; + private MaterialSkin.Controls.MaterialSlider mts_opacity; + private ReaLTaiizor.Controls.FoxLabel foxLabel3; + private ReaLTaiizor.Controls.HopePictureBox hpb_line; + private MaterialSkin.Controls.MaterialSlider mts_color_max; + private MaterialSkin.Controls.MaterialSlider mts_color_min; + private ReaLTaiizor.Controls.FoxLabel foxLabel9; + private ReaLTaiizor.Controls.FoxLabel foxLabel6; + private ReaLTaiizor.Controls.FoxLabel foxLabel2; + private System.Windows.Forms.NumericUpDown nud_color_min; + private System.Windows.Forms.NumericUpDown nud_color_max; + private System.Windows.Forms.NumericUpDown nud_brightness; + private System.Windows.Forms.NumericUpDown nud_opacity; + private ReaLTaiizor.Controls.FoxLabel flb_act_mm; + private ReaLTaiizor.Controls.FoxLabel foxLabel8; + private System.Windows.Forms.ComboBox cb_colortable; + private System.Windows.Forms.PictureBox pb_bgimage; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; + private ReaLTaiizor.Controls.HopePictureBox hpb_rect; + private ReaLTaiizor.Controls.HopePictureBox hpb_circe; + private ReaLTaiizor.Controls.HopePictureBox hpb_wand; + private ReaLTaiizor.Controls.HopePictureBox hpb_xianduan; + private AntdUI.Panel panel2; + private ReaLTaiizor.Controls.FoxLabel foxLabel4; + private ReaLTaiizor.Controls.FoxTextBox ftb_r; + private ReaLTaiizor.Controls.FoxLabel foxLabel7; + private ReaLTaiizor.Controls.FoxTextBox ftb_h; + private ReaLTaiizor.Controls.FoxLabel foxLabel5; + private ReaLTaiizor.Controls.FoxTextBox ftb_w; + private ReaLTaiizor.Controls.FoxButton fb_fixSetting; + } +} \ No newline at end of file diff --git a/src/PBAnaly/UI/ImageToolPaletteForm.cs b/src/PBAnaly/UI/ImageToolPaletteForm.cs new file mode 100644 index 0000000..a9c4c93 --- /dev/null +++ b/src/PBAnaly/UI/ImageToolPaletteForm.cs @@ -0,0 +1,354 @@ +using System; +using System.Drawing; +using MaterialSkin; +using MaterialSkin.Controls; +using PBAnaly.Module; +using PBAnaly.Properties; + +namespace PBAnaly.UI +{ + public partial class ImageToolPaletteForm : MaterialForm + { + private int roi_w = 20; + private int roi_h = 20; + private int circle_r = 10; + public ImageToolPaletteForm() + { + InitializeComponent(); + mts_brightness.Value = ImageToolMannage.beta; + nud_brightness.Value = mts_brightness.Value; + nud_opacity.Value = mts_opacity.Value = (int)ImageToolMannage.alpha; + mts_color_max.Value = ImageToolMannage.color_max; + nud_color_max.Value = ImageToolMannage.color_max; + mts_color_min.RangeMax = ImageToolMannage.color_max; + mts_color_min.RangeMin = 5; + nud_color_min.Maximum = ImageToolMannage.color_max; + nud_color_min.Value = ImageToolMannage.color_min; + mts_color_min.Value = ImageToolMannage.color_min; + + cb_colortable.SelectedIndex = 0; + } + + private void mts_brightness_onValueChanged(object sender, int newValue) + { + //if (newValue > 254) newValue = 254; + //if (newValue < 0) newValue = 0; + //mts_brightness.Value = newValue; + nud_brightness.Value = mts_brightness.Value; + ImageToolMannage.beta = mts_brightness.Value; + + if (ImageToolMannage.imagePanel != null) + ImageToolMannage.imagePanel.ThisRefresh(); + } + private void nud_brightness_ValueChanged(object sender, EventArgs e) + { + mts_brightness.Value = (int)nud_brightness.Value; + ImageToolMannage.beta = mts_brightness.Value; + if (ImageToolMannage.imagePanel != null) + ImageToolMannage.imagePanel.ThisRefresh(); + + + } + private void mts_opacity_onValueChanged(object sender, int newValue) + { + nud_opacity.Value = mts_opacity.Value; + ImageToolMannage.alpha = mts_opacity.Value; + if (ImageToolMannage.imagePanel != null) + ImageToolMannage.imagePanel.ThisRefresh(); + } + + private void mts_color_max_onValueChanged(object sender, int newValue) + { + if (newValue < 10) + return; + //mts_color_min.RangeMax = newValue; + //mts_color_min.ValueMax = newValue; + nud_color_min.Maximum = newValue; + //mts_color_max.Value = newValue; + nud_color_max.Value = newValue; + if (ImageToolMannage.imagePanel != null) + ImageToolMannage.imagePanel.ThisRefresh(); + + + } + + private void mts_color_min_onValueChanged(object sender, int newValue) + { + if (newValue < 5) + return; + //mts_color_min.Value = newValue; + nud_color_min.Value = newValue; + if (ImageToolMannage.imagePanel != null) + ImageToolMannage.imagePanel.ThisRefresh(); + + + } + + private void nud_color_min_ValueChanged(object sender, EventArgs e) + { + + if (nud_color_min.Value < 5) return; + mts_color_min.Value = (int)nud_color_min.Value; + if (ImageToolMannage.imagePanel != null) + ImageToolMannage.imagePanel.ThisRefresh(); + } + + private void nud_color_max_ValueChanged(object sender, EventArgs e) + { + + if (ImageToolMannage.imagePanel != null) + ImageToolMannage.imagePanel.ThisRefresh(); + + mts_color_max.Value = (int)nud_color_max.Value; + mts_color_min.RangeMax = (int)nud_color_max.Value; + mts_color_min.ValueMax = (int)nud_color_max.Value; + + if (ImageToolMannage.imagePanel != null) + ImageToolMannage.imagePanel.ThisRefresh(); + } + + private void nud_opacity_ValueChanged(object sender, EventArgs e) + { + mts_opacity.Value = (int)nud_opacity.Value; + ImageToolMannage.alpha = mts_opacity.Value; + if (ImageToolMannage.imagePanel != null) + ImageToolMannage.imagePanel.ThisRefresh(); + } + + public void SetactMM(string value) + { + flb_act_mm.Text = value; + flb_act_mm.Refresh(); + } + + private void hpb_line_Click(object sender, EventArgs e) + { + ImageToolMannage.lineDisON = true; + } + private void hpb_xianduan_Click(object sender, EventArgs e) + { + ImageToolMannage.linepolygonON = true; + } + + private void hpb_wand_Click(object sender, EventArgs e) + { + ImageToolMannage.linewandON = true; + } + public void SetMaxMin(int min, int max) + { + mts_color_min.Value = min; + mts_color_max.Value = max; + cb_colortable.SelectedIndex = 0; + } + + private void cb_colortable_SelectedIndexChanged(object sender, EventArgs e) + { + Bitmap rotatedImage = null; + switch (cb_colortable.Text) + { + case "YellowHot": + rotatedImage = Resources.YellowHot_1; + rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipX); + + break; + case "Black_Red": + rotatedImage = Resources.Black_Red_1; + rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipX); + + break; + case "Black_Green": + rotatedImage = Resources.Black_Green_1; + rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipX); + + break; + case "Black_Blue": + rotatedImage = Resources.Black_Blue_1; + rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipX); + + break; + case "Black_Yley": + rotatedImage = Resources.Black_Yley_1; + rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipX); + + break; + case "RGB": + rotatedImage = Resources.EtBr_1; + rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipX); + + break; + case "Pseudo": + rotatedImage = Resources.Pseudo_1; + rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipX); + + break; + case "Gray": + rotatedImage = Resources.Gray; + rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipX); + + break; + + + } + if (ImageToolMannage.imagePanel != null) + { + ImageToolMannage.imagePanel.colorValue = cb_colortable.Text; + ImageToolMannage.imagePanel.colorIndex = cb_colortable.SelectedIndex; + } + if (ImageToolMannage.imagePanel != null) + ImageToolMannage.imagePanel.ThisRefresh(); + if (rotatedImage != null) + { + pb_bgimage.Image = rotatedImage; + pb_bgimage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + } + + + } + + + private void hpb_rect_Click(object sender, EventArgs e) + { + ImageToolMannage.rectON = true; + } + private void hpb_circe_Click(object sender, EventArgs e) + { + ImageToolMannage.circleON = true; + } + private void fb_fixSetting_Click(object sender, EventArgs e) + { + roi_w = int.Parse(ftb_w.Text.ToString()); + roi_h = int.Parse(ftb_h.Text.ToString()); + circle_r = int.Parse(ftb_r.Text.ToString()); + // ImageToolMannage.imagePanel.SampleOneSize(); + + } + #region 对外接口 + int lastColor = -1; + bool isMark = false; + public void SetMark(bool ret = true) + { + if (ret) + { + isMark = true; + lastColor = cb_colortable.SelectedIndex; + cb_colortable.SelectedIndex = 7; + cb_colortable.Enabled = false; + } + else + { + cb_colortable.Enabled = true; + if (isMark == true) + { + if (lastColor > 0) + { + cb_colortable.SelectedIndex = lastColor; + lastColor = -1; + isMark = false; + } + + } + } + } + + public float ColorMax + { + get + { + if (nud_color_max.InvokeRequired) + { + + return (float)nud_color_max.Invoke(new Func(() => (float)nud_color_max.Value)); + } + else + { + + return (float)nud_color_max.Value; + } + } + } + + public float ColorMin + { + get + { + if (nud_color_min.InvokeRequired) + { + + return (float)nud_color_min.Invoke(new Func(() => (float)nud_color_min.Value)); + } + else + { + + return (float)nud_color_min.Value; + } + } + } + + public int brightness + { + get + { + if (mts_brightness.InvokeRequired) + { + + return (int)mts_brightness.Invoke(new Func(() => ( mts_brightness.Value -127))); + } + else + { + + return (mts_brightness.Value - 127); + } + } + } + public double opacity + { + get + { + if (mts_opacity.InvokeRequired) + { + + return (double)mts_opacity.Invoke(new Func(() => (mts_opacity.Value / 100.0))); + } + else + { + + return (mts_opacity.Value / 100.0); + } + + } + } + public int colorbarIndex + { + get { + if (cb_colortable.InvokeRequired) + { + + return (int)cb_colortable.Invoke(new Func(() => cb_colortable.SelectedIndex)); + } + else + { + + return cb_colortable.SelectedIndex; + } + } + } + public int ROI_W + { + get { return roi_w; } + set { roi_w = value; ftb_w.Text = roi_w.ToString(); } + } + public int ROI_H + { + get { return roi_h; } + set { roi_h = value; ftb_h.Text = roi_h.ToString(); } + } + public int CIRCLE_R + { + get { return circle_r; } + set { circle_r = value; ftb_r.Text = circle_r.ToString(); } + } + #endregion + + + } +} diff --git a/src/PBAnaly/UI/ImageToolPaletteForm.resx b/src/PBAnaly/UI/ImageToolPaletteForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/src/PBAnaly/UI/ImageToolPaletteForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/PBAnaly/UI/RowMergeView.cs b/src/PBAnaly/UI/RowMergeView.cs new file mode 100644 index 0000000..4425b58 --- /dev/null +++ b/src/PBAnaly/UI/RowMergeView.cs @@ -0,0 +1,352 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Text; +using System.Windows.Forms; +using System.Collections; +using System.Reflection; +using System.Runtime.InteropServices; + + /// + /// DataGridView行合并.请对属性MergeColumnNames 赋值既可 + /// + public partial class RowMergeView : DataGridView + { + #region 构造函数 + public RowMergeView() + { + InitializeComponent(); + } + #endregion + #region 重写的事件 + protected override void OnPaint(PaintEventArgs pe) + { + // TODO: 在此处添加自定义绘制代码 + + // 调用基类 OnPaint + base.OnPaint(pe); + } + protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e) + { + try + { + if (e.RowIndex > -1 && e.ColumnIndex > -1) + { + DrawCell(e); + } + else + { + //二维表头 + if (e.RowIndex == -1) + { + if (SpanRows.ContainsKey(e.ColumnIndex)) //被合并的列 + { + //画边框 + Graphics g = e.Graphics; + e.Paint(e.CellBounds, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border); + + int left = e.CellBounds.Left, top = e.CellBounds.Top + 2, + right = e.CellBounds.Right, bottom = e.CellBounds.Bottom; + + switch (SpanRows[e.ColumnIndex].Position) + { + case 1: + left += 2; + break; + case 2: + break; + case 3: + right -= 2; + break; + } + + //画上半部分底色 + g.FillRectangle(new SolidBrush(this._mergecolumnheaderbackcolor), left, top, + right - left, (bottom - top) / 2); + + //画中线 + g.DrawLine(new Pen(this.GridColor), left, (top + bottom) / 2, + right, (top + bottom) / 2); + + //写小标题 + StringFormat sf = new StringFormat(); + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + g.DrawString(e.Value + "", e.CellStyle.Font, Brushes.Black, + new Rectangle(left, (top + bottom) / 2, right - left, (bottom - top) / 2), sf); + left = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Left, true).Left - 2; + + if (left < 0) left = this.GetCellDisplayRectangle(-1, -1, true).Width; + right = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Right, true).Right - 2; + if (right < 0) right = this.Width; + + g.DrawString(SpanRows[e.ColumnIndex].Text, e.CellStyle.Font, Brushes.Black, + new Rectangle(left, top, right - left, (bottom - top) / 2), sf); + e.Handled = true; + } + } + } + base.OnCellPainting(e); + } + catch + { } + } + protected override void OnCellClick(DataGridViewCellEventArgs e) + { + base.OnCellClick(e); + } + #endregion + #region 自定义方法 + /// + /// 画单元格 + /// + /// + private void DrawCell(DataGridViewCellPaintingEventArgs e) + { + if (e.CellStyle.Alignment == DataGridViewContentAlignment.NotSet) + { + e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; + } + Brush gridBrush = new SolidBrush(this.GridColor); + SolidBrush backBrush = new SolidBrush(e.CellStyle.BackColor); + SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor); + int cellwidth; + //上面相同的行数 + int UpRows = 0; + //下面相同的行数 + int DownRows = 0; + //总行数 + int count = 0; + if (this.MergeColumnNames.Contains(this.Columns[e.ColumnIndex].Name) && e.RowIndex != -1) + { + cellwidth = e.CellBounds.Width; + Pen gridLinePen = new Pen(gridBrush); + string curValue = e.Value == null ? "" : e.Value.ToString().Trim(); + string curSelected = this.CurrentRow.Cells[e.ColumnIndex].Value == null ? "" : this.CurrentRow.Cells[e.ColumnIndex].Value.ToString().Trim(); + if (!string.IsNullOrEmpty(curValue)) + { + #region 获取下面的行数 + for (int i = e.RowIndex; i < this.Rows.Count; i++) + { + if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue)) + { + //this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected; + + DownRows++; + if (e.RowIndex != i) + { + cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width; + } + } + else + { + break; + } + } + #endregion + #region 获取上面的行数 + for (int i = e.RowIndex; i >= 0; i--) + { + if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue)) + { + //this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected; + UpRows++; + if (e.RowIndex != i) + { + cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width; + } + } + else + { + break; + } + } + #endregion + count = DownRows + UpRows - 1; + if (count < 2) + { + return; + } + } + if (this.Rows[e.RowIndex].Selected) + { + backBrush.Color = e.CellStyle.SelectionBackColor; + fontBrush.Color = e.CellStyle.SelectionForeColor; + } + //以背景色填充 + e.Graphics.FillRectangle(backBrush, e.CellBounds); + //画字符串 + PaintingFont(e, cellwidth, UpRows, DownRows, count); + if (DownRows == 1) + { + e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + count = 0; + } + // 画右边线 + e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom); + + e.Handled = true; + } + } + /// + /// 画字符串 + /// + /// + /// + /// + /// + /// + private void PaintingFont(System.Windows.Forms.DataGridViewCellPaintingEventArgs e, int cellwidth, int UpRows, int DownRows, int count) + { + SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor); + int fontheight = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Height; + int fontwidth = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Width; + int cellheight = e.CellBounds.Height; + + if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomCenter) + { + e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y + cellheight * DownRows - fontheight); + } + else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomLeft) + { + e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y + cellheight * DownRows - fontheight); + } + else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomRight) + { + e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y + cellheight * DownRows - fontheight); + } + else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleCenter) + { + e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2); + } + else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleLeft) + { + e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2); + } + else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleRight) + { + e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2); + } + else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopCenter) + { + e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1)); + } + else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopLeft) + { + e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1)); + } + else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopRight) + { + e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1)); + } + else + { + e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2); + } + } + #endregion + #region 属性 + /// + /// 设置或获取合并列的集合 + /// + [MergableProperty(false)] + [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + [DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Visible)] + [Localizable(true)] + [Description("设置或获取合并列的集合"), Browsable(true), Category("单元格合并")] + public List MergeColumnNames + { + get + { + return _mergecolumnname; + } + set + { + _mergecolumnname = value; + } + } + private List _mergecolumnname = new List(); + #endregion + #region 二维表头 + private struct SpanInfo //表头信息 + { + public SpanInfo(string Text, int Position, int Left, int Right) + { + this.Text = Text; + this.Position = Position; + this.Left = Left; + this.Right = Right; + } + + public string Text; //列主标题 + public int Position; //位置,1:左,2中,3右 + public int Left; //对应左行 + public int Right; //对应右行 + } + private Dictionary SpanRows = new Dictionary();//需要2维表头的列 + /// + /// 合并列 + /// + /// 列的索引 + /// 需要合并的列数 + /// 合并列后的文本 + public void AddSpanHeader(int ColIndex, int ColCount, string Text) + { + if (ColCount < 2) + { + throw new Exception("行宽应大于等于2,合并1列无意义。"); + } + //将这些列加入列表 + int Right = ColIndex + ColCount - 1; //同一大标题下的最后一列的索引 + SpanRows[ColIndex] = new SpanInfo(Text, 1, ColIndex, Right); //添加标题下的最左列 + SpanRows[Right] = new SpanInfo(Text, 3, ColIndex, Right); //添加该标题下的最右列 + for (int i = ColIndex + 1; i < Right; i++) //中间的列 + { + SpanRows[i] = new SpanInfo(Text, 2, ColIndex, Right); + } + } + /// + /// 清除合并的列 + /// + public void ClearSpanInfo() + { + SpanRows.Clear(); + //ReDrawHead(); + } + private void DataGridViewEx_Scroll(object sender, ScrollEventArgs e) + { + if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)// && e.Type == ScrollEventType.EndScroll) + { + timer1.Enabled = false; timer1.Enabled = true; + } + } + //刷新显示表头 + public void ReDrawHead() + { + foreach (int si in SpanRows.Keys) + { + this.Invalidate(this.GetCellDisplayRectangle(si, -1, true)); + } + } + private void timer1_Tick(object sender, EventArgs e) + { + timer1.Enabled = false; + ReDrawHead(); + } + /// + /// 二维表头的背景颜色 + /// + [Description("二维表头的背景颜色"), Browsable(true), Category("二维表头")] + public Color MergeColumnHeaderBackColor + { + get { return this._mergecolumnheaderbackcolor; } + set { this._mergecolumnheaderbackcolor = value; } + } + private Color _mergecolumnheaderbackcolor = System.Drawing.SystemColors.Control; + #endregion + } + diff --git a/src/PBAnaly/UI/RowMergeView.designer.cs b/src/PBAnaly/UI/RowMergeView.designer.cs new file mode 100644 index 0000000..585bfd8 --- /dev/null +++ b/src/PBAnaly/UI/RowMergeView.designer.cs @@ -0,0 +1,51 @@ + + partial class RowMergeView + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + ((System.ComponentModel.ISupportInitialize)(this)).BeginInit(); + this.SuspendLayout(); + // + // timer1 + // + this.timer1.Interval = 20; + // + // RowMergeView + // + this.RowTemplate.Height = 23; + ((System.ComponentModel.ISupportInitialize)(this)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Timer timer1; + } + diff --git a/src/PBAnaly/UI/RowMergeView.resx b/src/PBAnaly/UI/RowMergeView.resx new file mode 100644 index 0000000..a6e85b6 --- /dev/null +++ b/src/PBAnaly/UI/RowMergeView.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + False + + \ No newline at end of file diff --git a/src/PBAnaly/UI/colorbarControl.Designer.cs b/src/PBAnaly/UI/colorbarControl.Designer.cs new file mode 100644 index 0000000..1687be4 --- /dev/null +++ b/src/PBAnaly/UI/colorbarControl.Designer.cs @@ -0,0 +1,103 @@ +namespace PBAnaly.UI +{ + partial class colorbarControl + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.slb_name = new ReaLTaiizor.Controls.SkyLabel(); + this.pb_colorbar = new System.Windows.Forms.PictureBox(); + this.tableLayoutPanel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pb_colorbar)).BeginInit(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.37313F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 74.62687F)); + this.tableLayoutPanel1.Controls.Add(this.slb_name, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.pb_colorbar, 0, 1); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 3; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 19F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 52F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(67, 300); + this.tableLayoutPanel1.TabIndex = 0; + // + // slb_name + // + this.slb_name.AutoSize = true; + this.tableLayoutPanel1.SetColumnSpan(this.slb_name, 2); + this.slb_name.Dock = System.Windows.Forms.DockStyle.Fill; + this.slb_name.Font = new System.Drawing.Font("Verdana", 6.75F, System.Drawing.FontStyle.Bold); + this.slb_name.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(27)))), ((int)(((byte)(94)))), ((int)(((byte)(137))))); + this.slb_name.Location = new System.Drawing.Point(3, 0); + this.slb_name.Name = "slb_name"; + this.slb_name.Size = new System.Drawing.Size(61, 19); + this.slb_name.TabIndex = 0; + this.slb_name.Text = "mark"; + this.slb_name.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // pb_colorbar + // + this.pb_colorbar.Dock = System.Windows.Forms.DockStyle.Fill; + this.pb_colorbar.Image = global::PBAnaly.Properties.Resources.Gray; + this.pb_colorbar.Location = new System.Drawing.Point(0, 19); + this.pb_colorbar.Margin = new System.Windows.Forms.Padding(0); + this.pb_colorbar.Name = "pb_colorbar"; + this.pb_colorbar.Size = new System.Drawing.Size(16, 229); + this.pb_colorbar.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.pb_colorbar.TabIndex = 1; + this.pb_colorbar.TabStop = false; + // + // colorbarControl + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.tableLayoutPanel1); + this.MaximumSize = new System.Drawing.Size(70, 200); + this.MinimumSize = new System.Drawing.Size(0, 300); + this.Name = "colorbarControl"; + this.Size = new System.Drawing.Size(67, 300); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pb_colorbar)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private ReaLTaiizor.Controls.SkyLabel slb_name; + private System.Windows.Forms.PictureBox pb_colorbar; + } +} diff --git a/src/PBAnaly/UI/colorbarControl.cs b/src/PBAnaly/UI/colorbarControl.cs new file mode 100644 index 0000000..a98a963 --- /dev/null +++ b/src/PBAnaly/UI/colorbarControl.cs @@ -0,0 +1,122 @@ +using PBAnaly.Properties; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace PBAnaly.UI +{ + public partial class colorbarControl : UserControl + { + public colorbarControl() + { + InitializeComponent(); + + } + + public string SetSytingName + { + set { slb_name.Text = value; } + } + public void SetDrawBar(string type) + { + Bitmap rotatedImage = null; + switch (type) + { + case "YellowHot": + rotatedImage = Resources.YellowHot_1; + + + break; + case "Black_Red": + rotatedImage = Resources.Black_Blue_1; + + break; + case "Black_Green": + rotatedImage = Resources.Black_Green_1; + + break; + case "Black_Blue": + rotatedImage = Resources.Black_Blue_1; + + break; + case "Black_Yley": + rotatedImage = Resources.Black_Yley_1; + + break; + case "Black_SDS": + rotatedImage = Resources.Black_SDS_1; + + break; + case "EtBr": + rotatedImage = Resources.EtBr_1; + + break; + case "Pseudo": + rotatedImage = Resources.Pseudo_1; + + break; + case "Gray": + rotatedImage = Resources.Gray; + + break; + + + } + if (rotatedImage != null) + { + pb_colorbar.Image = rotatedImage; + pb_colorbar.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + } + } + + //public void SetHistogramGradient(int[] histom,int min,int max) + //{ + // using (Graphics g = panel1.CreateGraphics()) + // { + // panel1.Refresh(); // 清除之前的绘制 + // Rectangle rect = new Rectangle(0, 0, 30, panel1.Height); + // byte StartgrayScaleValue = (byte)((min / 65535.0) * 255); + // byte EndgrayScaleValue = (byte)((max / 65535.0) * 255); + // Color startColor = Color.FromArgb(StartgrayScaleValue, StartgrayScaleValue, StartgrayScaleValue); + // Color endColor = Color.FromArgb(EndgrayScaleValue, EndgrayScaleValue, EndgrayScaleValue); + + // using (LinearGradientBrush brush = new LinearGradientBrush(rect, endColor, startColor, LinearGradientMode.Vertical)) + // { + // g.FillRectangle(brush, rect); + // } + + // Pen pen = new Pen(Color.Black, 1); + // Font font = new Font("Arial", 8); + // int diff = max - min; + // int numberOfTicks = CalculateNumberOfTicks(diff); // 计算刻度数量 + + // // 循环现在从1开始并在numberOfTicks-1结束,避免绘制首尾标签 + // for (int i = 1; i < numberOfTicks; i++) + // { + // int labelValue = max - (diff / numberOfTicks * i); + // int y = rect.Top + (i * (rect.Height / numberOfTicks)); + // g.DrawLine(pen, rect.Right, y, rect.Right + 5, y); // 绘制刻度 + // string labelText = labelValue.ToString(); + // g.DrawString(labelText, font, Brushes.Black, rect.Right + 10, y - font.Height / 2); + // } + // } + + //} + //private int CalculateNumberOfTicks(int diff) + //{ + // if (diff > 10000) return 10; + // if (diff > 5000) return 8; + // if (diff > 1000) return 5; + // return 3; // 最小的刻度数量 + //} + + + } +} diff --git a/src/PBAnaly/UI/colorbarControl.resx b/src/PBAnaly/UI/colorbarControl.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/src/PBAnaly/UI/colorbarControl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/PBAnaly/packages.config b/src/PBAnaly/packages.config new file mode 100644 index 0000000..cd0c6a0 --- /dev/null +++ b/src/PBAnaly/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/PBAnaly/testAlgForm.Designer.cs b/src/PBAnaly/testAlgForm.Designer.cs new file mode 100644 index 0000000..9ee9673 --- /dev/null +++ b/src/PBAnaly/testAlgForm.Designer.cs @@ -0,0 +1,74 @@ +namespace PBAnaly +{ + partial class testAlgForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.button1 = new System.Windows.Forms.Button(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // button1 + // + this.button1.Location = new System.Drawing.Point(42, 12); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(117, 61); + this.button1.TabIndex = 0; + this.button1.Text = "button1"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // pictureBox1 + // + this.pictureBox1.Location = new System.Drawing.Point(123, 97); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(1042, 636); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBox1.TabIndex = 1; + this.pictureBox1.TabStop = false; + // + // testAlgForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1348, 773); + this.Controls.Add(this.pictureBox1); + this.Controls.Add(this.button1); + this.Name = "testAlgForm"; + this.Text = "testAlgForm"; + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button button1; + private System.Windows.Forms.PictureBox pictureBox1; + } +} \ No newline at end of file diff --git a/src/PBAnaly/testAlgForm.cs b/src/PBAnaly/testAlgForm.cs new file mode 100644 index 0000000..e3738e5 --- /dev/null +++ b/src/PBAnaly/testAlgForm.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using PBBiologyVC; +using OpenCvSharp; +using OpenCvSharp.Extensions; +using System.Windows.Markup; +using System.Runtime.InteropServices; + +namespace PBAnaly +{ + public partial class testAlgForm : Form + { + public testAlgForm() + { + InitializeComponent(); + } + public Mat ConvertByteArrayToMat(byte[] imageData, int width, int height, MatType type) + { + Mat image = new Mat(height, width, type); + if (type == MatType.CV_8UC1) + { + Marshal.Copy(imageData, 0, image.Data, width * height); + } + else if (type == MatType.CV_16UC1) + { + Marshal.Copy(imageData, 0, image.Data, width * height*2); + } + return image; + } + public byte[] ConvertUShortArrayToByteArrayComplete(ushort[] ushortArray) + { + // 创建一个byte数组,长度是ushort数组的两倍 + byte[] byteArray = new byte[ushortArray.Length * 2]; + + for (int i = 0, j = 0; i < ushortArray.Length; i++, j += 2) + { + // 高位byte + byteArray[j+1] = (byte)(ushortArray[i] >> 8); + // 低位byte + byteArray[j] = (byte)(ushortArray[i] & 0xFF); + } + + return byteArray; + } + + private void button1_Click(object sender, EventArgs e) + { + Mat image = Cv2.ImRead("1.tif", ImreadModes.Unchanged); + //Cv2.ImShow("image", image); + //Cv2.WaitKey(0); + Mat whiteBackgroundImg=new Mat(); + Scalar meanValue = Cv2.Mean(image); + if (meanValue[0] < 10000) + { + Cv2.BitwiseNot(image, whiteBackgroundImg); + } + else + { + whiteBackgroundImg = image.Clone(); + } + //Cv2.ImShow("whiteBackgroundImg", whiteBackgroundImg); + //Cv2.WaitKey(0); + Mat input_cn1 = new Mat(); + whiteBackgroundImg.ConvertTo(input_cn1, MatType.CV_8U, 0.00390625); + + //Cv2.ImShow("whiteBackgroundImg", whiteBackgroundImg); + //Cv2.WaitKey(0); + if (image.Depth() != MatType.CV_8U) + { + Mat convertedImage = new Mat(); + image.ConvertTo(convertedImage, MatType.CV_8U); + pictureBox1.Image = convertedImage.ToBitmap(); + } + else + { + pictureBox1.Image = image.ToBitmap(); + } + //// 读tiff文件 + byte[] byte_image = new byte[input_cn1.Width * input_cn1.Height]; + ushort[] whiteBackgroundImg_image = new ushort[whiteBackgroundImg.Width * whiteBackgroundImg.Height]; + int index = 0; + for (int i = 0; i < input_cn1.Rows; i++) + { + for (int j = 0; j < input_cn1.Cols; j++) + { + byte value = input_cn1.At(i, j); // 使用At方法访问数据 + ushort value1 = whiteBackgroundImg.At(i, j); // 使用At方法访问数据 + byte_image[index] = value; + whiteBackgroundImg_image[index++] = value1; + + } + + } + + + + PBBiology dd = new PBBiology(); + List proteinRect = new List(); + List<_band_info> band_info = new List<_band_info>(); + + + unsafe + { + fixed (byte* p = byte_image) + { + proteinRect = dd.getProteinRectVC(p, (ushort)input_cn1.Width, (ushort)input_cn1.Height); + } + + byte[] bytes = ConvertUShortArrayToByteArrayComplete(whiteBackgroundImg_image); + + + fixed (byte* p = bytes) + { + dd.getProteinBandsVC(p, 16, (ushort)input_cn1.Width, (ushort)input_cn1.Height, proteinRect,ref band_info); + } + dd.adjustBands(band_info, 10); + dd.molecularWeightResult(ref proteinRect, ref band_info); + Console.WriteLine(); + } + + + //PBAnaly.LaneChartForm laneChartForm = new PBAnaly.LaneChartForm(proteinRect, band_info); + //laneChartForm.Show(); + + } + } +} diff --git a/src/PBAnaly/testAlgForm.resx b/src/PBAnaly/testAlgForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/src/PBAnaly/testAlgForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/PBBiology/PBBiology.cpp b/src/PBBiology/PBBiology.cpp new file mode 100644 index 0000000..27e44f5 --- /dev/null +++ b/src/PBBiology/PBBiology.cpp @@ -0,0 +1,10 @@ +// PBBiology.cpp : 定义静态库的函数。 +// + +#include "pch.h" +#include "framework.h" + +// TODO: 这是一个库函数示例 +void fnPBBiology() +{ +} diff --git a/src/PBBiology/PBBiology.vcxproj b/src/PBBiology/PBBiology.vcxproj new file mode 100644 index 0000000..e50fc9d --- /dev/null +++ b/src/PBBiology/PBBiology.vcxproj @@ -0,0 +1,172 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {ec5572d1-750b-4f4b-adc2-02b9827e0647} + PBBiology + 10.0 + + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + ..\..\libs\opencv\include;..\..\libs\opencv\include\opencv2;$(IncludePath) + ..\PBBiology\include;..\..\libs\opencv\lib;$(LibraryPath) + + + ..\..\libs\opencv\include\opencv2;..\..\libs\opencv\include;..\..\src\PBBiology\include;$(IncludePath) + ..\..\libs\opencv\lib;$(LibraryPath) + + + + Level3 + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + Use + pch.h + + + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + Use + pch.h + + + + + true + true + true + + + + + Level3 + true + _DEBUG;_LIB;%(PreprocessorDefinitions) + true + NotUsing + pch.h + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + true + NotUsing + pch.h + + + + + true + true + true + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + \ No newline at end of file diff --git a/src/PBBiology/PBBiology.vcxproj.filters b/src/PBBiology/PBBiology.vcxproj.filters new file mode 100644 index 0000000..2fbc30f --- /dev/null +++ b/src/PBBiology/PBBiology.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + \ No newline at end of file diff --git a/src/PBBiology/framework.h b/src/PBBiology/framework.h new file mode 100644 index 0000000..d2d95bd --- /dev/null +++ b/src/PBBiology/framework.h @@ -0,0 +1,3 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 diff --git a/src/PBBiology/include/PBColony.h b/src/PBBiology/include/PBColony.h new file mode 100644 index 0000000..d20b3d0 --- /dev/null +++ b/src/PBBiology/include/PBColony.h @@ -0,0 +1,92 @@ +#pragma once + +#include +#include +#include +#include +#include +#include "PBType.h" +using namespace std; +using namespace cv; + +class PBColony +{ +public: + bool image_inverted_flag;//记录菌落是白色还是黑色 + PBColony(); + ~PBColony(); + +private: + //生长方式找到圆 + int fine_grow_circle(Mat input, Point2f& center, float& radius); + //测边方式找到圆 + int fine_max_circle(Mat input, Point2f& center, float& radius); + +public: + ////函数:获得图像培养皿圆的位置 + ////src:输入图像,需是8bit单通道图像 + ////center:圆心 + ////radius:半径 + ////返回值:是否找到圆,0表示没有找到 + int colony_get_circle(Mat& src, Point2f& center, float& radius); + + ////函数:根据矩形生成白色椭圆,黑色背景的掩膜图像 + ////img_width、img_height:生成掩膜图像宽高 + ////rect_x、rect_y、rect_width、rect_height:椭圆的位置 + ////返回值:对应掩膜图像 + cv::Mat generateMaskImage(int img_width, int img_height, int rect_x, int rect_y, int rect_width, int rect_height); + + ////函数:根据掩膜图像和输入图像生成对应二值化图像 + ////input_cn1:输入图像 + ////mask:掩膜图像 + ////lower、upper:二值化阈值 + ////返回值:二值化图像 + cv::Mat get_lower_upper(Mat& input_cn1, Mat& mask, int& lower, int& upper); + + ////函数:初始化分类标准 + void init_classify_standard(ClassifyStandard& class_stand); + ////函数:设置分类间隔 + void set_classify_standard_num(ClassifyStandard& class_stand, int num); + ////函数:设置分类类别 + void set_classify_standard_classes(ClassifyStandard& class_stand, dataClass classes); + ////函数:修改分类标准数值 + void set_classify_standard_interval(ClassifyStandard& class_stand, int n, float data); + + ////函数:计算得到菌落信息 + ////src:输入图像,8bit灰度图像 + ////bin:二值化图像 + ////dst_cn3:绘制菌落轮廓以及计数标志的输出图像 + ////class_stand:分类标准 + ////inverted_flag:菌落是黑色还是白色的标志 + ////返回值:菌落信息 + vector get_colony_info(Mat src, Mat bin, Mat& dst_cn3, ClassifyStandard class_stand, bool inverted_flag); + + ////函数:统计菌落信息 + ////Cinfo:输入菌落信息 + ////返回值:菌落信息统计结果 + ColonyStatistic get_colony_statistics(vector Cinfo); +}; + +/* text +* + Mat input_cn1;//输入8bit单通道灰度图像 + Mat input_cn3;//显示出来的带有轮廓的图像 + + Point2f center; + float radius; + int ret = colony_get_circle(input_cn1, center, radius); + + if (ret) + { + Mat mask = generateMaskImage(input_cn1.cols, input_cn1.rows, center.x - radius, center.y - radius, 2 * radius, 2 * radius); + int lower = -1; + int upper = -1; + Mat bin = get_lower_upper(input_cn1, mask, lower, upper); + + ClassifyStandard class_stand; + init_classify_standard(class_stand); + vector Cinfo = get_colony_info(input_cn1, bin, input_cn3, class_stand, image_inverted_flag); + ColonyStatistic CStatistic = get_colony_statistics(Cinfo); + } + +*/ diff --git a/src/PBBiology/include/PBImageProcess.h b/src/PBBiology/include/PBImageProcess.h new file mode 100644 index 0000000..5c8ba53 --- /dev/null +++ b/src/PBBiology/include/PBImageProcess.h @@ -0,0 +1,80 @@ +#pragma once +#include "PBType.h" +#include +#include +#include +#include +#include + +using namespace std; +using namespace cv; + + +// +int RegionGrow(cv::Mat& src, cv::Mat& matDst, cv::Point2i pt, int th); +//С˷ȡԲ +void FitCircleCenter(vector& Circle_Data, Point2f& Circle_Center, float& Circle_R); +//С˷ȡԲ +int RANSAC_FitCircleCenter(vector& Circle_Data, Point2f& Circle_Center, float& Circle_R, float thresh); +//С˷ȡԲ +void RANSAC_FitCircleCenter_with_throw(vector& Circle_Data, Point2f& Circle_Center, float& Circle_R); +//ֵֵ +int IJIsoData(int* data); +int defaultIsoData(int* data); + +////maskȾͼ +////srcmaskCV_16UC1ͼ +////dstCV_8UC3ɫͼ +////maxminmaskѡȾСֵ +////colorɫ +////reverseǷתɫ +//int render_mask_image(Mat src, Mat mask, Mat dst, float max, float min, ColorTable color, bool reverse); +// +///// +///// ںͼ +///// +///// +///// +///// +///// +///// +//int blendImages(const Mat& src, const Mat& mark, const Mat& dst, double alpha); +////int render_image(Mat src, Mat& dst, float max, float min, ColorTable color, bool reverse); +////ϳȾͼsrcͼpseudoImgǹȾͼbrightness_offsetȣcontrast_factorԱȶȣcontrast_factor͸ȣںͼ +////brightness_offset:ƫƷΧ -255 +255 +////contrast_factor:ԱȶӷΧ 0.1 3.01.0Ϊ䣩 +////opacity_factor:͸ӷΧ 0 10Ϊ͸1Ϊ͸ +//Mat render_mask_image(Mat src, Mat pseudoImg, int brightness_offset, double contrast_factor, double opacity_factor); +////ȡɫcolorɫͣbgr_tabпռɫָ룬reverseǷת +//void get_bgr_tab(ColorTable color, uint8_t(*bgr_tab)[3], bool reverse); +////ɫֱͼw=200,h_color=10һɫߣbgr_tabпռɫָ +//Mat bgr_tab_image(int w, int h_onecolor, uint8_t(*bgr_tab)[3]); +//int pseudo_color_processing(Mat src, Mat dst, float max, float min, uint8_t(*bgr_tab)[3]); +// +//// ѡĹ +//PseudoInfo get_pseudo_info(Mat src,int x,int y,int w,int h,float max,float min); +// +//Mat bgr_scale_image(Mat src, float maxVal, float minVal); + + + +//ϳȾͼsrcͼpseudoImgǹȾͼbrightness_offsetȣcontrast_factorԱȶȣcontrast_factor͸ȣںͼ +//brightness_offset:ƫƷΧ -255 +255 +//contrast_factor:ԱȶӷΧ 0.1 3.01.0Ϊ䣩 +//opacity_factor:͸ӷΧ 0 10Ϊ͸1Ϊ͸ +Mat render_mask_image(Mat src, Mat pseudoImg, int brightness_offset, double contrast_factor, double opacity_factor); +//ȡɫcolorɫͣbgr_tabпռɫָ룬reverseǷת +void get_bgr_tab(ColorTable color, uint8_t(*bgr_tab)[3], bool reverse); +//ɫֱͼw=200,h_color=10һɫߣbgr_tabпռɫָ +Mat bgr_tab_image(int w, int h_onecolor, uint8_t(*bgr_tab)[3]); +//ͳƼsrcͼ16bitcountͼfloatĹӼͼ룻maskĤͼmaxmin趨ĴС +PseudoInfo get_pseudo_info(Mat src, Mat mask, float max, float min); +//ɹȾͼsrcȾǰͼdstȾͼmaxmin趨ĴСbgr_tabпռɫָ +int pseudo_color_processing(Mat src, Mat dst, float max, float min, uint8_t(*bgr_tab)[3]); +//ɴߵֱͼsrcbgr_tab_imageɵͼmaxValminVal趨ĴСscientific_flagǷѧ +Mat bgr_scale_image(Mat src, float maxVal, float minVal, int scientific_flag); +//ȡӼͼsrcȾǰԭʼͼsecWcm=27ʵʿHcm=18ʵʸߣsrĬ1.0CV_32FC1ĸӽͼ +Mat get_photon_image(Mat src, float sec, float Wcm, float Hcm, float sr); +//ħܣsrcǴ8bitͼx,yǵλõ꣬ +//th趨ز1020֮ģʵʵһ£Ǻ͵λõزthΧڵһأᱻѡ +Mat get_magic_wand_image(Mat src, int x, int y, int th); \ No newline at end of file diff --git a/src/PBBiology/include/PBLane.h b/src/PBBiology/include/PBLane.h new file mode 100644 index 0000000..e68b448 --- /dev/null +++ b/src/PBBiology/include/PBLane.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include +#include +#include +#include +#include "PBType.h" + +using namespace std; +using namespace cv; + +class PBLane +{ +public: + PBLane(); + ~PBLane(); + +private: + //Ӿ˴ + //ӾX꣨groupsXԼӾС루minDifference/maxDifference˵ϹӾ + std::vector processArray(std::vector& groupsX, int minDifference, int maxDifference); + + ///**/㺯Ӿ + vector get_bar_num(vector buf); + + //Ӿⲹȫ + //ӾλãprocessXӾ루meanWͼsrcмٽӾλǷӾԣӾصĿӦҴ + std::vector checkArray(std::vector& processX, Mat src, int start_y, int end_y, int meanW); + + //Ϣ㺯8bit飨rbufԼ˷Χrange˷Χڽһӣ + vector> get_top_point(vector rbuf, int range); + + //ӾϢ㣨λõȣ + BandInfo get_protein_lane_data(Mat src, Rect lane); + static bool myCompare(const int& a, const int& b); + static bool myCompare2(const std::array& a, const std::array& b); + + +public: + //ͼӾλ + //srcͼ8bitͨͼ + //ֵӾλϢ + std::vector getProteinRect(Mat src); + + ////ͼӾӦϢ + ////srcͼ16bitͨͼ + ////lanesӾλϢ + ////ֵӦλϢ + std::vector getProteinBands(Mat src, std::vector lanes); + + ////ƥ + ////bandsλϢ + ////rangeYrangeΧڵıʾӾ1ƥ + ////ֵ޸bands + void adjustBands(std::vector& bands, int range); + + + ////ķϢ + ////lanesӾϢ + ////bandsϢӦķϢṹ + void molecularWeightResult(std::vector lanes, std::vector& bands); +}; \ No newline at end of file diff --git a/src/PBBiology/include/PBType.h b/src/PBBiology/include/PBType.h new file mode 100644 index 0000000..2ac7323 --- /dev/null +++ b/src/PBBiology/include/PBType.h @@ -0,0 +1,106 @@ +#pragma once +#include + + +using namespace std; + +#define ZBAR_FIXED 5 +#define ROUND (1 << (ZBAR_FIXED - 1)) +#define ZBAR_SCANNER_THRESH_FADE 8 +#define EWMA_WEIGHT ((unsigned)((.78 * (1 << (ZBAR_FIXED + 1)) + 1) / 2)) +#define THRESH_INIT ((unsigned)((.44 * (1 << (ZBAR_FIXED + 1)) + 1) / 2)) + + +struct MolecularInfo +{ + float molecular_weight; // 分子量 + int band_content; // 条带含量 + float relative_content; // 相对含量 + int IOD; // IOD + float maxOD; // 最大OD + float percentum; // 百分比 + int match; // 匹配 +}; + +struct BandInfo +{ + std::vector land_data; // 泳道数据(16bit) + std::vector ydata; // 泳道波形y轴(0.0-255.0) + std::vector xdata; // 泳道波形x轴(0.0-1.0) + std::vector> band_point; // 条带位置(顶峰、左括号、右括号) + std::vector Minfo; // 对应条带的分子计算结果 +}; + + + + +enum dataClass +{ + AREA = 0, //面积 + PERIMETER, //周长 + DIAMETER, //直径 + IOD, //IOD +}; + +struct ClassifyStandard +{ + vector interval; //分类依据间隔标志数据 + float maxd; //分类最大间隔标志 + float mind; //分类最小间隔标志 + int num; //分类间隔数 + dataClass classes; //分类类别 +}; + +struct ColonyInfo +{ + int IDX; //菌落序号 + int area; //菌落面积 + int perimeter; //菌落周长 + float diameter; //菌落直径 + int IOD; //菌落IOD + int classify; //菌落分类 +}; + +struct MinMaxInfo +{ + float mind; //最小值 + float minIDX; //最小值对应序号 + float maxd; //最大值 + float maxIDX; //最大值对应序号 + float range; //范围 + float mean; //均值 + float sum; //和 + int number; //数量 +}; + +struct ColonyStatistic +{ + MinMaxInfo area; //面积统计结果 + MinMaxInfo perimeter; //周长统计结果 + MinMaxInfo diameter; //直径统计结果 + MinMaxInfo IOD; //IOD统计结果 + MinMaxInfo classify; //分类统计结果 +}; + +typedef enum _color_table { + + YellowHot=0, + Black_Red=1, + Black_Green=2, + Black_Blue=3, + Black_Yley=4, + RGB=5, + Pseudo=6, + Gray + +}ColorTable; + + +typedef struct _Pseudo_info +{ + int maxOD; + int minOD; + int IOD; + int count; + float AOD; +}PseudoInfo; \ No newline at end of file diff --git a/src/PBBiology/pch.cpp b/src/PBBiology/pch.cpp new file mode 100644 index 0000000..b6fb8f4 --- /dev/null +++ b/src/PBBiology/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: 与预编译标头对应的源文件 + +#include "pch.h" + +// 当使用预编译的头时,需要使用此源文件,编译才能成功。 diff --git a/src/PBBiology/pch.h b/src/PBBiology/pch.h new file mode 100644 index 0000000..9660927 --- /dev/null +++ b/src/PBBiology/pch.h @@ -0,0 +1,13 @@ +// pch.h: 这是预编译标头文件。 +// 下方列出的文件仅编译一次,提高了将来生成的生成性能。 +// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。 +// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。 +// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。 + +#ifndef PCH_H +#define PCH_H + +// 添加要在此处预编译的标头 +#include "framework.h" + +#endif //PCH_H diff --git a/src/PBBiology/src/PBColony.cpp b/src/PBBiology/src/PBColony.cpp new file mode 100644 index 0000000..f9c0d6e --- /dev/null +++ b/src/PBBiology/src/PBColony.cpp @@ -0,0 +1,431 @@ +#include "../include/PBColony.h" +#include "../include/PBImageProcess.h" + +int PBColony::fine_grow_circle(Mat input, Point2f& center, float& radius) +{ + cv::Mat matDst; + int mat_cnt = 0; + int cal_cnt = 0; + int grow_flag = 0; + cv::Point2i pt(input.cols / 2, input.rows / 2); + while (1) + { + mat_cnt = RegionGrow(input, matDst, pt, 3); + if (mat_cnt > input.cols * input.rows / 10) + { + grow_flag = 1; + break; + } + else if (cal_cnt > 10) + { + break; + } + pt = pt + cv::Point2i(2, 0); + cal_cnt++; + } + + + if (grow_flag) + { + std::vector> contours; + cv::findContours(matDst, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); + Mat drawImg = Mat::zeros(input.rows, input.cols, CV_8UC1); + cv::drawContours(drawImg, contours, -1, Scalar(255, 255, 255), 1); + int contour_size_th = (input.rows + input.cols) / 3; + int radiusTh = std::min(input.cols, input.rows) / 4; + float maxRadius = input.cols; + cv::Point2f maxCenter; + for (size_t i = 0; i < contours.size(); i++) { + if (contours[i].size() < contour_size_th) + { + continue; + } + Point2f now_center; + float now_radius; + RANSAC_FitCircleCenter_with_throw(contours[i], now_center, now_radius); + if (now_radius > radiusTh) + { + if (now_radius < maxRadius) { + maxRadius = now_radius; + maxCenter = now_center; + } + } + } + if (maxRadius < input.cols) { + center = maxCenter; + radius = maxRadius; + return 1; + } + else { + return 0; + } + } + else { + return 0; + } +} + +int PBColony::fine_max_circle(Mat input, Point2f& center, float& radius) +{ + Mat blurImg; + cv::medianBlur(input, blurImg, 3); + Mat edgeImg; + cv::Canny(blurImg, edgeImg, 0, 255); + + std::vector> contours; + cv::findContours(edgeImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); + cv::drawContours(edgeImg, contours, -1, Scalar(255, 255, 255), 5); + contours.clear(); + + cv::findContours(edgeImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); + Mat drawImg = Mat::zeros(input.rows, input.cols, CV_8UC1); + cv::drawContours(drawImg, contours, -1, Scalar(255, 255, 255), 1); + + int contour_size_th = (input.rows + input.cols) / 3; + int radiusTh = std::min(edgeImg.cols, edgeImg.rows) / 4; + float maxRadius = edgeImg.cols; + cv::Point2f maxCenter; + for (size_t i = 0; i < contours.size(); i++) { + if (contours[i].size() < contour_size_th) + { + continue; + } + Point2f now_center; + float now_radius; + RANSAC_FitCircleCenter_with_throw(contours[i], now_center, now_radius); + if (now_radius > radiusTh) + { + if (now_radius < maxRadius) { + maxRadius = now_radius; + maxCenter = now_center; + } + } + + } + if (maxRadius < edgeImg.cols) { + center = maxCenter; + radius = maxRadius; + return 1; + } + else { + return 0; + } +} + + + +PBColony::PBColony() {} + +PBColony::~PBColony() {} + + +int PBColony::colony_get_circle(Mat& src, Point2f& center, float& radius) +{ + Point2f center1; + float radius1; + int ret1 = fine_grow_circle(src, center1, radius1); + + Point2f center2; + float radius2; + int ret2 = fine_max_circle(src, center2, radius2); + + if (ret1 && ret2) + { + double distance = sqrt(pow(center1.x - center2.x, 2) + pow(center1.y - center2.y, 2)); + if (distance + radius1 <= radius2) { + center = center1; + radius = radius1 - 3; + } + else { + center = center2; + radius = radius2 - 10; + } + return 1; + } + else if (ret2) + { + center = center2; + radius = radius2 - 10; + return 1; + } + else + { + return 0; + } +} + +cv::Mat PBColony::generateMaskImage(int img_width, int img_height, int rect_x, int rect_y, int rect_width, int rect_height) +{ + cv::Mat image = cv::Mat::zeros(img_height, img_width, CV_8UC1); + cv::Point ellipse_center(rect_x + rect_width / 2, rect_y + rect_height / 2); + cv::Size ellipse_axes(rect_width / 2, rect_height / 2); + cv::Scalar white_color(255); + cv::ellipse(image, ellipse_center, ellipse_axes, 0, 0, 360, white_color, -1); + return image; +} + +cv::Mat PBColony::get_lower_upper(Mat& input_cn1, Mat& mask, int& lower, int& upper) +{ + input_cn1 = input_cn1 & mask; + + if (lower == -1 || upper == -1) + { + int pixel_count[256] = { 0 }; + unsigned char* pixel_point = input_cn1.data; + for (int n = 0; n < input_cn1.rows * input_cn1.cols; n++) { + pixel_count[*pixel_point++]++; + } + int value = defaultIsoData(pixel_count); + int lowsum = std::accumulate(pixel_count + 1, pixel_count + value, 0); + int upsum = std::accumulate(pixel_count + value, pixel_count + 255, 0); + if (lowsum > upsum) + { + image_inverted_flag = 0; + lower = value; + upper = 255; + } + else + { + image_inverted_flag = 1; + lower = 0; + upper = value; + } + } + + Mat bin; + cv::inRange(input_cn1, lower, upper, bin); + bin = bin & mask; + + return bin; +} + + +void PBColony::init_classify_standard(ClassifyStandard& class_stand) +{ + class_stand.num = 2; + class_stand.mind = 1; + class_stand.maxd = 65535; + class_stand.interval.clear(); + float data_interval = (class_stand.maxd - class_stand.mind) / (class_stand.num - 1); + for (int n = 0; n < class_stand.num; n++) + { + class_stand.interval.push_back(class_stand.mind + n * data_interval); + } + class_stand.classes = dataClass::AREA; +} + +void PBColony::set_classify_standard_num(ClassifyStandard& class_stand, int num) +{ + class_stand.num = num; + class_stand.interval.clear(); + float data_interval = (class_stand.maxd - class_stand.mind) / (class_stand.num - 1); + for (int n = 0; n < class_stand.num; n++) + { + class_stand.interval.push_back(class_stand.mind + n * data_interval); + } +} + +void PBColony::set_classify_standard_classes(ClassifyStandard& class_stand, dataClass classes) +{ + class_stand.classes = classes; +} + +void PBColony::set_classify_standard_interval(ClassifyStandard& class_stand, int n, float data) +{ + if (n < class_stand.num) + { + class_stand.interval[n] = data; + } +} + + +vector PBColony::get_colony_info(Mat src, Mat bin, Mat& dst_cn3, ClassifyStandard class_stand, bool inverted_flag) +{ + vector Cinfo; + std::vector> contours; + cvtColor(src, dst_cn3, COLOR_GRAY2BGR); + cv::findContours(bin, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE); + if (inverted_flag) + { + src = 255 - src; + } + int cnt_colony = 0; + for (int i = 0; i < contours.size(); i++) + { + cv::Mat mask = cv::Mat::zeros(src.rows, src.cols, CV_8UC1); + cv::drawContours(mask, contours, i, cv::Scalar(255), 1); + int perimeter = cv::countNonZero(mask); + cv::drawContours(mask, contours, i, cv::Scalar(255), -1); + int area = cv::countNonZero(mask); + + if (perimeter < 8) { + continue; + } + cnt_colony++; + cv::putText(dst_cn3, std::to_string(cnt_colony), contours[i][0], cv::FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 0, 0), 1); + cv::drawContours(dst_cn3, contours, i, Scalar(0, 0, 255), 1); + + float diameter = std::sqrt(4 * area / 3.141592653); + int pixel_sum = cv::sum(src & mask)[0]; + + int n = 0; + switch (class_stand.classes) + { + case AREA: + for (; n < class_stand.num; n++) + { + if (class_stand.interval[n] > area) break; + } + break; + case PERIMETER: + for (; n < class_stand.num; n++) + { + if (class_stand.interval[n] > perimeter) break; + } + break; + case DIAMETER: + for (; n < class_stand.num; n++) + { + if (class_stand.interval[n] > diameter) break; + } + break; + case IOD: + for (; n < class_stand.num; n++) + { + if (class_stand.interval[n] > pixel_sum) break; + } + break; + default: + break; + } + + ColonyInfo info; + info.IDX = cnt_colony; + info.area = area; + info.perimeter = perimeter; + info.diameter = diameter; + info.IOD = pixel_sum; + info.classify = n; + + Cinfo.push_back(info); + } + return Cinfo; +} + +ColonyStatistic PBColony::get_colony_statistics(vector Cinfo) +{ + ColonyStatistic CStatistic; + CStatistic.area.maxd = Cinfo[0].area; + CStatistic.area.maxIDX = Cinfo[0].IDX; + CStatistic.area.mind = Cinfo[0].area; + CStatistic.area.minIDX = Cinfo[0].IDX; + CStatistic.area.sum = Cinfo[0].area; + + CStatistic.perimeter.maxd = Cinfo[0].perimeter; + CStatistic.perimeter.maxIDX = Cinfo[0].IDX; + CStatistic.perimeter.mind = Cinfo[0].perimeter; + CStatistic.perimeter.minIDX = Cinfo[0].IDX; + CStatistic.perimeter.sum = Cinfo[0].perimeter; + + CStatistic.diameter.maxd = Cinfo[0].diameter; + CStatistic.diameter.maxIDX = Cinfo[0].IDX; + CStatistic.diameter.mind = Cinfo[0].diameter; + CStatistic.diameter.minIDX = Cinfo[0].IDX; + CStatistic.diameter.sum = Cinfo[0].diameter; + + CStatistic.IOD.maxd = Cinfo[0].IOD; + CStatistic.IOD.maxIDX = Cinfo[0].IDX; + CStatistic.IOD.mind = Cinfo[0].IOD; + CStatistic.IOD.minIDX = Cinfo[0].IDX; + CStatistic.IOD.sum = Cinfo[0].IOD; + + CStatistic.classify.maxd = Cinfo[0].classify; + CStatistic.classify.maxIDX = Cinfo[0].IDX; + CStatistic.classify.mind = Cinfo[0].classify; + CStatistic.classify.minIDX = Cinfo[0].IDX; + CStatistic.classify.sum = Cinfo[0].classify; + + for (int i = 1; i < Cinfo.size(); i++) + { + if (CStatistic.area.maxd < Cinfo[i].area) + { + CStatistic.area.maxd = Cinfo[i].area; + CStatistic.area.maxIDX = Cinfo[i].IDX; + } + if (CStatistic.area.mind > Cinfo[i].area) + { + CStatistic.area.mind = Cinfo[i].area; + CStatistic.area.minIDX = Cinfo[i].IDX; + } + CStatistic.area.sum += Cinfo[i].area; + + if (CStatistic.perimeter.maxd < Cinfo[i].perimeter) + { + CStatistic.perimeter.maxd = Cinfo[i].perimeter; + CStatistic.perimeter.maxIDX = Cinfo[i].IDX; + } + if (CStatistic.perimeter.mind > Cinfo[i].perimeter) + { + CStatistic.perimeter.mind = Cinfo[i].perimeter; + CStatistic.perimeter.minIDX = Cinfo[i].IDX; + } + CStatistic.perimeter.sum += Cinfo[i].perimeter; + + if (CStatistic.diameter.maxd < Cinfo[i].diameter) + { + CStatistic.diameter.maxd = Cinfo[i].diameter; + CStatistic.diameter.maxIDX = Cinfo[i].IDX; + } + if (CStatistic.diameter.mind > Cinfo[i].diameter) + { + CStatistic.diameter.mind = Cinfo[i].diameter; + CStatistic.diameter.minIDX = Cinfo[i].IDX; + } + CStatistic.diameter.sum += Cinfo[i].diameter; + + if (CStatistic.IOD.maxd < Cinfo[i].IOD) + { + CStatistic.IOD.maxd = Cinfo[i].IOD; + CStatistic.IOD.maxIDX = Cinfo[i].IDX; + } + if (CStatistic.IOD.mind > Cinfo[i].IOD) + { + CStatistic.IOD.mind = Cinfo[i].IOD; + CStatistic.IOD.minIDX = Cinfo[i].IDX; + } + CStatistic.IOD.sum += Cinfo[i].IOD; + + if (CStatistic.classify.maxd < Cinfo[i].classify) + { + CStatistic.classify.maxd = Cinfo[i].classify; + CStatistic.classify.maxIDX = Cinfo[i].IDX; + } + if (CStatistic.classify.mind > Cinfo[i].classify) + { + CStatistic.classify.mind = Cinfo[i].classify; + CStatistic.classify.minIDX = Cinfo[i].IDX; + } + CStatistic.classify.sum += Cinfo[i].classify; + } + CStatistic.area.range = CStatistic.area.maxd - CStatistic.area.mind; + CStatistic.area.mean = CStatistic.area.sum / Cinfo.size(); + CStatistic.area.number = Cinfo.size(); + + CStatistic.perimeter.range = CStatistic.perimeter.maxd - CStatistic.perimeter.mind; + CStatistic.perimeter.mean = CStatistic.perimeter.sum / Cinfo.size(); + CStatistic.perimeter.number = Cinfo.size(); + + CStatistic.diameter.range = CStatistic.diameter.maxd - CStatistic.diameter.mind; + CStatistic.diameter.mean = CStatistic.diameter.sum / Cinfo.size(); + CStatistic.diameter.number = Cinfo.size(); + + CStatistic.IOD.range = CStatistic.IOD.maxd - CStatistic.IOD.mind; + CStatistic.IOD.mean = CStatistic.IOD.sum / Cinfo.size(); + CStatistic.IOD.number = Cinfo.size(); + + CStatistic.classify.range = CStatistic.classify.maxd - CStatistic.classify.mind; + CStatistic.classify.mean = CStatistic.classify.sum / Cinfo.size(); + CStatistic.classify.number = Cinfo.size(); + + return CStatistic; +} diff --git a/src/PBBiology/src/PBImageProcess.cpp b/src/PBBiology/src/PBImageProcess.cpp new file mode 100644 index 0000000..ec8b870 --- /dev/null +++ b/src/PBBiology/src/PBImageProcess.cpp @@ -0,0 +1,1269 @@ +#include "../include/PBImageProcess.h" +#include + + +//㷨 +int RegionGrow(cv::Mat& src, cv::Mat& matDst, cv::Point2i pt, int th) +{ + cv::Point2i ptGrowing; + int nGrowLable = 0; + int nSrcValue = 0; + int nCurValue = 0; + int mat_cnt = 0; + matDst = cv::Mat::zeros(src.size(), CV_8UC1); + int DIR[8][2] = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 }, { -1, 0 } }; + std::vector vcGrowPt; + vcGrowPt.push_back(pt); + matDst.at(pt.y, pt.x) = 255; + + while (!vcGrowPt.empty()) //ջΪ + { + pt = vcGrowPt.back(); //ȡһ + vcGrowPt.pop_back(); + + std::vector temp_vcGrowPt; //ʱջ + int temp_vcGrowPt_size = 0; //Ϊڱֱʹtemp_vcGrowPt.size() + nSrcValue = src.at(pt.y, pt.x); + //ֱ԰˸ϵĵ + for (int i = 0; i < 8; ++i) + { + ptGrowing.x = pt.x + DIR[i][0]; + ptGrowing.y = pt.y + DIR[i][1]; + //ǷDZԵ + if (ptGrowing.x < 0 || ptGrowing.y < 0 || ptGrowing.x >(src.cols - 1) || (ptGrowing.y > src.rows - 1)) + continue; + + nGrowLable = matDst.at(ptGrowing.y, ptGrowing.x); //ǰĻҶֵ + if (nGrowLable == 0) //ǵ㻹ûб + { + nCurValue = src.at(ptGrowing.y, ptGrowing.x); + if (abs(nCurValue - nSrcValue) < th) //ֵΧ + { + // matDst.at(ptGrowing.y, ptGrowing.x) = 255; + temp_vcGrowPt_size++; + temp_vcGrowPt.push_back(ptGrowing); //һѹջ + } + } + else { + temp_vcGrowPt_size++; + } + } + //ڵ㲻ǵЧ + if (temp_vcGrowPt_size >= 1) { + mat_cnt++; + matDst.at(pt.y, pt.x) = 255; + vcGrowPt.insert(vcGrowPt.end(), temp_vcGrowPt.begin(), temp_vcGrowPt.end()); + } + } + return mat_cnt; + // bitwise_and(src, matDst, matDst); //Աԭͼ +} + +// Բεĺ +void FitCircleCenter(vector& Circle_Data, Point2f& Circle_Center, float& Circle_R) +{ + //м + double sumX1 = 0.0; //Xiĺ(1~n) X1X1η + double sumY1 = 0.0; + double sumX2 = 0.0; //(Xi)^2ĺ(i1~n)X2XĶη + double sumY2 = 0.0; + double sumX3 = 0.0; + double sumY3 = 0.0; + double sumX1Y1 = 0.0; + double sumX1Y2 = 0.0; + double sumX2Y1 = 0.0; + const double N = (double)Circle_Data.size();//ĸ + + for (int i = 0; i < Circle_Data.size(); ++i)// + { + double x = 0; + double y = 0; + x = Circle_Data[i].x; //еix + y = Circle_Data[i].y; //еiy + double x2 = x * x; //x^2 + double y2 = y * y; //y^2 + double x3 = x2 * x; //x^3 + double y3 = y2 * y; //y^3 + double xy = x * y; //xy + double x1y2 = x * y2; //x*y^2 + double x2y1 = x2 * y; //x^2*y + + sumX1 += x; //sumX=sumX+x;xĺ + sumY1 += y; //sumY=sumY+y;yĺ + sumX2 += x2; //x^2ĺ + sumY2 += y2; //y^2ĺ + sumX3 += x3; //x^3ĺ + sumY3 += y3; + sumX1Y1 += xy; + sumX1Y2 += x1y2; + sumX2Y1 += x2y1; + } + double C = N * sumX2 - sumX1 * sumX1; + double D = N * sumX1Y1 - sumX1 * sumY1; + double E = N * sumX3 + N * sumX1Y2 - (sumX2 + sumY2) * sumX1; + double G = N * sumY2 - sumY1 * sumY1; + double H = N * sumX2Y1 + N * sumY3 - (sumX2 + sumY2) * sumY1; + + double denominator = C * G - D * D; + double a = (H * D - E * G) / (denominator); + double b = (H * C - E * D) / (-denominator); + double c = -(a * sumX1 + b * sumY1 + sumX2 + sumY2) / N; + + Circle_Center.x = a / (-2); + Circle_Center.y = b / (-2); + Circle_R = std::sqrt(a * a + b * b - 4 * c) / 2; +} + + +int RANSAC_FitCircleCenter(vector& Circle_Data, Point2f& Circle_Center, float& Circle_R, float thresh) +{ + // RANSACС + int iterations = 1000; + int min_samples = 3; + + // ʹRANSAC㷨Բ + float best_radius = 0; + Point2f best_center; + std::vector is_inlier(Circle_Data.size(), 0); + std::vector is_inlier_tmp(Circle_Data.size(), 0); + int max_inlier_num = 0; + double max_diff = 0; + int sample_count = 0; + + while (sample_count < iterations) + { + // ѡС + vector points; + for (int j = 0; j < min_samples; j++) + { + int index = rand() % Circle_Data.size(); + Point2f point(Circle_Data[index].x, Circle_Data[index].y); + points.push_back(point); + } + + // ʹС˷Բ + float radius; + Point2f center; + FitCircleCenter(points, center, radius); + + // еԲ֮ľ룬ȷڵ + vector inliers; + for (int i = 0; i < Circle_Data.size(); i++) + { + Point2f point(Circle_Data[i].x, Circle_Data[i].y); + is_inlier_tmp[i] = 0; + + float distance = norm(point - center) - radius; + if (abs(distance) < thresh) + { + is_inlier_tmp[i] = 1; + inliers.push_back(point); + } + } + // Բ + if (inliers.size() > max_inlier_num) { + max_inlier_num = inliers.size(); + is_inlier = is_inlier_tmp; + best_radius = radius; + best_center = center; + } + //6. µѴ + if (inliers.size() == 0) + { + iterations = 1000; + } + else + { + double epsilon = 1.0 - double(inliers.size()) / (double)Circle_Data.size(); //Ұֵ + double p = 0.9; //д1ĸ + double s = 3.0; + iterations = int(std::log(1.0 - p) / std::log(1.0 - std::pow((1.0 - epsilon), s))); + } + sample_count++; + } + //7. ŵĽӦڵ + std::vector inliers; + inliers.reserve(max_inlier_num); + for (int i = 0; i < is_inlier.size(); i++) + { + if (1 == is_inlier[i]) + { + inliers.push_back(Circle_Data[i]); + } + } + float radius = 0.0f; + cv::Point2f center; + if (max_inlier_num == 0) { + return 0; + } + else { + minEnclosingCircle(inliers, center, radius); + Circle_R = radius; + Circle_Center = center; + return 1; + } +} + +void RANSAC_FitCircleCenter_with_throw(vector& Circle_Data, Point2f& Circle_Center, float& Circle_R) +{ + float thresh = 2; + int ret = 0; + + while (1) { + if (Circle_Data.size() < 3) { + break; + } + ret = RANSAC_FitCircleCenter(Circle_Data, Circle_Center, Circle_R, thresh); + if (ret == 0) { + thresh = thresh + 0.5; + continue; + } + break; + } +} + +int IJIsoData(int* data) +{ + int level; + int maxValue = 256 - 1; + double result, sum1, sum2, sum3, sum4; + int count0 = data[0]; + data[0] = 0; //set to zero so erased areas aren't included + int countMax = data[maxValue]; + data[maxValue] = 0; + int min = 0; + while ((data[min] == 0) && (min < maxValue)) + min++; + int max = maxValue; + while ((data[max] == 0) && (max > 0)) + max--; + if (min >= max) { + data[0] = count0; data[maxValue] = countMax; + level = 256 / 2; + return level; + } + int movingIndex = min; + int inc = std::max(max / 40, 1); + do { + sum1 = sum2 = sum3 = sum4 = 0.0; + for (int i = min; i <= movingIndex; i++) { + sum1 += (double)i * data[i]; + sum2 += data[i]; + } + for (int i = (movingIndex + 1); i <= max; i++) { + sum3 += (double)i * data[i]; + sum4 += data[i]; + } + result = (sum1 / sum2 + sum3 / sum4) / 2.0; + movingIndex++; + } while ((movingIndex + 1) <= result && movingIndex < max - 1); + data[0] = count0; data[maxValue] = countMax; + level = (int)round(result); + return level; +} + +int defaultIsoData(int* data) +{ + int n = 256; + int* data2 = new int[n]; + int mode = 0, maxCount = 0; + for (int i = 0; i < n; i++) { + int count = data[i]; + data2[i] = count; + if (count > maxCount) { + maxCount = count; + mode = i; + } + } + int maxCount2 = 0; + for (int i = 0; i < n; i++) { + if ((data2[i] > maxCount2) && (i != mode)) + maxCount2 = data2[i]; + } + int hmax = maxCount; + if ((hmax > (maxCount2 * 2)) && (maxCount2 != 0)) { + hmax = (int)(maxCount2 * 1.5); + data2[mode] = hmax; + } + int value = IJIsoData(data2); + delete[] data2; + return value; +} +// +//Mat render_mask_image(Mat src, Mat pseudoImg, int brightness_offset, double contrast_factor, double opacity_factor) +//{ +// Mat dst = pseudoImg.clone(); +// if (src.type() != CV_16UC1 || pseudoImg.type() != CV_8UC3) +// { +// return dst; +// } +// //brightness_offset:ƫƷΧ -255 +255 +// //contrast_factor:ԱȶӷΧ 0.1 3.01.0Ϊ䣩 +// //opacity_factor:͸ӷΧ 0 10Ϊ͸1Ϊ͸ +// +// Mat img8bit; +// src.convertTo(img8bit, CV_8UC1, 0.00390625); +// Mat img_brightness_contrast; +// img8bit.convertTo(img_brightness_contrast, -1, contrast_factor, brightness_offset); +// Mat img_with_opacity = img_brightness_contrast * opacity_factor; +// img_with_opacity = cv::min(img_with_opacity, 255.0); +// img_with_opacity = cv::max(img_with_opacity, 0.0); +// img_with_opacity.convertTo(img_with_opacity, CV_8UC1); +// +// Mat img_with_opacity_rgb; +// cvtColor(img_with_opacity, img_with_opacity_rgb, COLOR_GRAY2BGR); // ͨҶͼתΪͨRGBͼ +// +// for (int y = 0; y < pseudoImg.rows; y++) { +// for (int x = 0; x < pseudoImg.cols; x++) { +// Vec3b pixel = pseudoImg.at(y, x); +// if (pixel == Vec3b(0, 0, 0)) { +// dst.at(y, x) = img_with_opacity_rgb.at(y, x); +// } +// } +// } +// return dst; +//} +Mat bgr_scale_image(Mat src, float maxVal, float minVal) +{ + int w = src.cols; + int h = src.rows; + int start = 2 * h / 255; + Mat image = Mat(h + 2 * start, w + w + 100, CV_8UC3); + image.setTo(255); + src.copyTo(image(Rect(0, start, w, h))); + + int scale_w = 40; + int scale_h = 5; + int numTicks = 10; + float tickInterval = float(maxVal - minVal) / numTicks; + + for (int i = 0; i <= numTicks; i++) + { + int value = minVal + i * tickInterval; + int yPos = h - (i * h / numTicks); + line(image, Point(w, yPos + start), Point(scale_w + w, yPos + start), Scalar(0, 0, 0), scale_h); + putText(image, to_string(int(value)), Point(scale_w * 1.5 + w, yPos + 5 + start), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 0), 2, LINE_AA); + for (int j = 1; j < 5; j++) { + int smallTickY = yPos - (h / numTicks) * j / 5; + line(image, Point(w, smallTickY + start), Point(scale_w * 2 / 3 + w, smallTickY + start), Scalar(0, 0, 0), scale_h / 2); + } + } + + return image; +} + +//int render_mask_image(Mat src, Mat mask, Mat dst, float max, float min, ColorTable color, bool reverse) +//{ +// +// if (src.type() != CV_16UC1 || mask.type() != CV_16UC1) +// { +// return -1; +// } +// uint8_t bgr_tab[445][3] = { 0 }; +// switch (color) +// { +// case YellowHot: +// if (reverse) { +// int n = 0; +// for (int i = 67; i <= 255; i++, n++) { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 0; +// bgr_tab[n][2] = i; +// } +// for (int i = 0; i <= 255; i++, n++) +// { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = i; +// bgr_tab[n][2] = 255; +// } +// } +// else { +// int n = 0; +// for (int i = 255; i >= 0; i--, n++) { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = i; +// bgr_tab[n][2] = 255; +// } +// for (int i = 255; i >= 67; i--, n++) +// { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 0; +// bgr_tab[n][2] = i; +// } +// } +// break; +// +// default:break; +// } +// +// +// +// Mat temp; +// src.convertTo(temp, CV_8UC1, 0.00390625); +// cvtColor(temp, dst, COLOR_GRAY2BGR); +// +// uint16_t* pMask = mask.ptr(0); +// uint8_t* pDst = dst.ptr(0); +// +// float rotia = 444.0 / (max - min); +// for (int n = 0; n < src.rows * src.cols; n++) +// { +// if (*pMask > min && *pMask <= max) +// { +// int c = (*pMask - min) * rotia; +// *(pDst + 0) = bgr_tab[c][0]; +// *(pDst + 1) = bgr_tab[c][1]; +// *(pDst + 2) = bgr_tab[c][2]; +// } +// pDst += 3; +// pMask++; +// } +// +// return 0; +//} + +//int blendImages(const Mat& src, const Mat& mark, const Mat& dst, double alpha) +//{ +// // ͼͺʹС +// if (src.type() != CV_16UC1 || mark.type() != CV_8UC3) +// { +// return -1; // +// } +// +// // alpha 0-100 ķΧתΪ 0-1 +// double alpha_normalized = alpha / 100.0; +// +// // src 16 λתΪ 8 λ +// Mat src8U; +// src.convertTo(src8U, CV_8UC1, 1.0 / 256); // 16λֵŵ0-255Χ +// +// // src8U תΪɫͼԱ mark ں +// Mat srcColor; +// cvtColor(src8U, srcColor, COLOR_GRAY2RGB); // תΪ BGR ɫͼ +// +// // һͼ +// Mat blended; +// +// // ʹ addWeighted ں +// addWeighted(srcColor, 1, mark,alpha_normalized, 0.0, blended); +// blended.copyTo(dst); +// return 1; // ɹ +//} + + +//int render_image(Mat src, Mat& dst, float max, float min, ColorTable color, bool reverse) +//{ +// if (src.type() != CV_16UC1) +// { +// return -1; +// } +// uint8_t bgr_tab[445][3] = { 0 }; +// switch (color) +// { +// case YellowHot: +// if (reverse) { +// int n = 0; +// for (int i = 67; i <= 255; i++, n++) { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 0; +// bgr_tab[n][2] = i; +// } +// for (int i = 0; i <= 255; i++, n++) +// { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = i; +// bgr_tab[n][2] = 255; +// } +// } +// else { +// int n = 0; +// for (int i = 255; i >= 0; i--, n++) { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = i; +// bgr_tab[n][2] = 255; +// } +// for (int i = 255; i >= 67; i--, n++) +// { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 0; +// bgr_tab[n][2] = i; +// } +// } +// break; +// +// default:break; +// } +// +// +// +// Mat temp; +// src.convertTo(temp, CV_8UC1, 0.00390625); +// cvtColor(temp, dst, COLOR_GRAY2BGR); +// +// uint16_t* pMask = src.ptr(0); +// uint8_t* pDst = dst.ptr(0); +// +// float rotia = 444.0 / (max - min); +// for (int n = 0; n < src.rows * src.cols; n++) +// { +// if (*pMask > min && *pMask <= max) +// { +// int c = (*pMask - min) * rotia; +// *(pDst + 0) = bgr_tab[c][0]; +// *(pDst + 1) = bgr_tab[c][1]; +// *(pDst + 2) = bgr_tab[c][2]; +// } +// pDst += 3; +// pMask++; +// } +// +// return 0; +// +//} +// +//void get_bgr_tab(ColorTable color, uint8_t(*bgr_tab)[3], bool reverse) +//{ +// // uint8_t bgr_tab[256][3] = {0}; +// int n = 0; +// +// switch (color) +// { +// case YellowHot: +// for (int i = 0; i <= 128; i++, n++) { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 255.0 - i * 255.0 / 128.0; +// bgr_tab[n][2] = 255; +// } +// n--; +// for (int i = 0; i <= 127; i++, n++) +// { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 0; +// bgr_tab[n][2] = 255.0 - i * (255.0 - 67.0) / 127.0; +// } +// break; +// case Pseudo: +// for (int i = 0; i <= 25; i++, n++) { +// bgr_tab[n][0] = i * 255.0 / 25.0; +// bgr_tab[n][1] = 0; +// bgr_tab[n][2] = 0; +// } +// n--; +// for (int i = 0; i <= 26; i++, n++) +// { +// bgr_tab[n][0] = 255; +// bgr_tab[n][1] = i * 175.0 / 26.0; +// bgr_tab[n][2] = 0; +// } +// n--; +// for (int i = 0; i <= 24; i++, n++) +// { +// bgr_tab[n][0] = 255; +// bgr_tab[n][1] = 175 + i * (255.0 - 175.0) / 24.0; +// bgr_tab[n][2] = 0; +// } +// n--; +// for (int i = 0; i <= 27; i++, n++) +// { +// bgr_tab[n][0] = 255 - i * 80.0 / 27.0; +// bgr_tab[n][1] = 255; +// bgr_tab[n][2] = 0; +// } +// n--; +// for (int i = 0; i <= 25; i++, n++) +// { +// bgr_tab[n][0] = 175.0 - i * 175.0 / 25.0; +// bgr_tab[n][1] = 255; +// bgr_tab[n][2] = 0; +// } +// n--; +// for (int i = 0; i <= 28; i++, n++) +// { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 255; +// bgr_tab[n][2] = i * 175.0 / 28.0; +// } +// n--; +// for (int i = 0; i <= 30; i++, n++) +// { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 255; +// bgr_tab[n][2] = 175.0 + i * 80.0 / 30.0; +// } +// n--; +// for (int i = 0; i <= 30; i++, n++) +// { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 255.0 - i * 80.0 / 30.0; +// bgr_tab[n][2] = 255; +// } +// n--; +// for (int i = 0; i <= 40; i++, n++) +// { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 175.0 - i * 175.0 / 40.0; +// bgr_tab[n][2] = 255; +// } +// break; +// case Black_Red: +// for (int i = 0; i <= 255; i++, n++) { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 0; +// bgr_tab[n][2] = i; +// } +// break; +// case Black_Green: +// for (int i = 0; i <= 255; i++, n++) { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = i; +// bgr_tab[n][2] = i * 17.0 / 255.0; +// } +// break; +// case Black_Blue: +// for (int i = 0; i <= 255; i++, n++) { +// bgr_tab[n][0] = i; +// bgr_tab[n][1] = 0; +// bgr_tab[n][2] = 0; +// } +// break; +// case Black_Yley: +// for (int i = 0; i <= 255; i++, n++) { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = i * 125.0 / 255.0; +// bgr_tab[n][2] = i; +// } +// break; +// +// case RGB: +// for (int i = 0; i <= 25; i++, n++) { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 0; +// bgr_tab[n][2] = 0; +// } +// n--; +// for (int i = 0; i <= 50; i++, n++) +// { +// bgr_tab[n][0] = i * 255.0 / 50.0; +// bgr_tab[n][1] = 0; +// bgr_tab[n][2] = 0; +// } +// n--; +// for (int i = 0; i <= 50; i++, n++) +// { +// bgr_tab[n][0] = 255; +// bgr_tab[n][1] = i * 255.0 / 50.0; +// bgr_tab[n][2] = 0; +// } +// n--; +// for (int i = 0; i <= 50; i++, n++) +// { +// bgr_tab[n][0] = 255 - i * 255.0 / 50.0; +// bgr_tab[n][1] = 255; +// bgr_tab[n][2] = 0; +// } +// n--; +// for (int i = 0; i <= 29; i++, n++) +// { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 255; +// bgr_tab[n][2] = i * 255.0 / 29.0; +// } +// n--; +// for (int i = 0; i <= 51; i++, n++) +// { +// bgr_tab[n][0] = 0; +// bgr_tab[n][1] = 255 - i * 255.0 / 51.0; +// bgr_tab[n][2] = 255; +// } +// break; +// case Gray: +// for (int i = 0; i <= 255; i++, n++) { +// bgr_tab[n][0] = i; +// bgr_tab[n][1] = i; +// bgr_tab[n][2] = i; +// } +// break; +// default:break; +// } +// if (reverse) +// { +// for (int i = 0; i < 128; ++i) { +// for (int j = 0; j < 3; ++j) { +// uint8_t temp = bgr_tab[i][j]; +// bgr_tab[i][j] = bgr_tab[255 - i][j]; +// bgr_tab[255 - i][j] = temp; +// } +// } +// } +//} +// +//Mat bgr_tab_image(int w, int h_onecolor, uint8_t(*bgr_tab)[3]) +//{ +// Mat dst(h_onecolor * 256, w, CV_8UC3); +// for (int n = 0; n < h_onecolor * 256; n++) +// { +// dst.row(n) = cv::Scalar(bgr_tab[n / h_onecolor][0], bgr_tab[n / h_onecolor][1], bgr_tab[n / h_onecolor][2]); +// } +// return dst; +//} +// +//int pseudo_color_processing(Mat src, Mat dst, float max, float min, uint8_t(*bgr_tab)[3]) +//{ +// +// if (src.type() != CV_16UC1 || dst.type() != CV_8UC3) +// { +// return -1; +// } +// uint16_t* pSrc = src.ptr(0); +// uint8_t* pDst = dst.ptr(0); +// +// float rotia = 255.0 / (max - min); +// for (int n = 0; n < src.rows * src.cols; n++) +// { +// if (*pSrc <= min) +// { +// *(pDst + 0) = 0;//bgr_tab[0][0]; +// *(pDst + 1) = 0;//bgr_tab[0][1]; +// *(pDst + 2) = 0;//bgr_tab[0][2]; +// } +// else if (*pSrc > min && *pSrc <= max) +// { +// int c = (*pSrc - min) * rotia; +// *(pDst + 0) = bgr_tab[c][0]; +// *(pDst + 1) = bgr_tab[c][1]; +// *(pDst + 2) = bgr_tab[c][2]; +// } +// else +// { +// *(pDst + 0) = bgr_tab[255][0]; +// *(pDst + 1) = bgr_tab[255][1]; +// *(pDst + 2) = bgr_tab[255][2]; +// } +// pDst += 3; +// pSrc++; +// } +// +// return 0; +//} +// +//PseudoInfo get_pseudo_info(Mat src, int x, int y, int w, int h, float max, float min) +//{ +// PseudoInfo info; +// info.maxOD = min; +// info.minOD = max; +// info.IOD = 0; +// info.count = 0; +// info.AOD = 0; +// +// Mat cut; +// Rect roi(x, y, w, h); +// cut = src(roi).clone(); +// uint16_t* pCut = cut.ptr(0); +// for (int n = 0; n < w * h; n++) +// { +// if (*pCut > min) +// { +// if (*pCut < info.minOD) +// info.minOD = *pCut; +// if (*pCut > info.maxOD) +// info.maxOD = *pCut; +// info.IOD += *pCut; +// info.count++; +// } +// pCut++; +// } +// if(info.count !=0 ) +// info.AOD = info.IOD / info.count; +// else +// { +// info.maxOD = 0; +// info.minOD = 0; +// } +// return info; +//} +// +// + + +Mat render_mask_image(Mat src, Mat pseudoImg, int brightness_offset, double contrast_factor, double opacity_factor) +{ + Mat dst = pseudoImg.clone(); + if (src.type() != CV_16UC1 || pseudoImg.type() != CV_8UC3) + { + return dst; + } + //brightness_offset:ƫƷΧ -255 +255 + //contrast_factor:ԱȶӷΧ 0.1 3.01.0Ϊ䣩 + //opacity_factor:͸ӷΧ 0 10Ϊ͸1Ϊ͸ + + Mat img8bit; + src.convertTo(img8bit, CV_8UC1, 0.00390625); + Mat img_brightness_contrast; + img8bit.convertTo(img_brightness_contrast, -1, contrast_factor, brightness_offset); + Mat img_with_opacity = img_brightness_contrast * opacity_factor; + img_with_opacity = cv::min(img_with_opacity, 255.0); + img_with_opacity = cv::max(img_with_opacity, 0.0); + img_with_opacity.convertTo(img_with_opacity, CV_8UC1); + + Mat img_with_opacity_rgb; + cvtColor(img_with_opacity, img_with_opacity_rgb, COLOR_GRAY2BGR); // ͨҶͼתΪͨRGBͼ + + for (int y = 0; y < pseudoImg.rows; y++) { + for (int x = 0; x < pseudoImg.cols; x++) { + Vec3b pixel = pseudoImg.at(y, x); + if (pixel == Vec3b(0, 0, 0)) { + dst.at(y, x) = img_with_opacity_rgb.at(y, x); + } + } + } + return dst; +} + +void get_bgr_tab(ColorTable color, uint8_t(*bgr_tab)[3], bool reverse) +{ + // uint8_t bgr_tab[256][3] = {0}; + int n = 0; + switch (color) + { + case YellowHot: + for (int i = 0; i <= 128; i++, n++) { + bgr_tab[n][0] = 0; + bgr_tab[n][1] = 255.0 - i * 255.0 / 128.0; + bgr_tab[n][2] = 255; + } + n--; + for (int i = 0; i <= 127; i++, n++) + { + bgr_tab[n][0] = 0; + bgr_tab[n][1] = 0; + bgr_tab[n][2] = 255.0 - i * (255.0 - 67.0) / 127.0; + } + break; + case Pseudo: + for (int i = 0; i <= 25; i++, n++) { + bgr_tab[n][0] = i * 255.0 / 25.0; + bgr_tab[n][1] = 0; + bgr_tab[n][2] = 0; + } + n--; + for (int i = 0; i <= 26; i++, n++) + { + bgr_tab[n][0] = 255; + bgr_tab[n][1] = i * 175.0 / 26.0; + bgr_tab[n][2] = 0; + } + n--; + for (int i = 0; i <= 24; i++, n++) + { + bgr_tab[n][0] = 255; + bgr_tab[n][1] = 175 + i * (255.0 - 175.0) / 24.0; + bgr_tab[n][2] = 0; + } + n--; + for (int i = 0; i <= 27; i++, n++) + { + bgr_tab[n][0] = 255 - i * 80.0 / 27.0; + bgr_tab[n][1] = 255; + bgr_tab[n][2] = 0; + } + n--; + for (int i = 0; i <= 25; i++, n++) + { + bgr_tab[n][0] = 175.0 - i * 175.0 / 25.0; + bgr_tab[n][1] = 255; + bgr_tab[n][2] = 0; + } + n--; + for (int i = 0; i <= 28; i++, n++) + { + bgr_tab[n][0] = 0; + bgr_tab[n][1] = 255; + bgr_tab[n][2] = i * 175.0 / 28.0; + } + n--; + for (int i = 0; i <= 30; i++, n++) + { + bgr_tab[n][0] = 0; + bgr_tab[n][1] = 255; + bgr_tab[n][2] = 175.0 + i * 80.0 / 30.0; + } + n--; + for (int i = 0; i <= 30; i++, n++) + { + bgr_tab[n][0] = 0; + bgr_tab[n][1] = 255.0 - i * 80.0 / 30.0; + bgr_tab[n][2] = 255; + } + n--; + for (int i = 0; i <= 40; i++, n++) + { + bgr_tab[n][0] = 0; + bgr_tab[n][1] = 175.0 - i * 175.0 / 40.0; + bgr_tab[n][2] = 255; + } + break; + case Black_Red: + for (int i = 0; i <= 255; i++, n++) { + bgr_tab[n][0] = 0; + bgr_tab[n][1] = 0; + bgr_tab[n][2] = i; + } + break; + case Black_Green: + for (int i = 0; i <= 255; i++, n++) { + bgr_tab[n][0] = 0; + bgr_tab[n][1] = i; + bgr_tab[n][2] = i * 17.0 / 255.0; + } + break; + case Black_Blue: + for (int i = 0; i <= 255; i++, n++) { + bgr_tab[n][0] = i; + bgr_tab[n][1] = 0; + bgr_tab[n][2] = 0; + } + break; + case Black_Yley: + for (int i = 0; i <= 255; i++, n++) { + bgr_tab[n][0] = 0; + bgr_tab[n][1] = i * 125.0 / 255.0; + bgr_tab[n][2] = i; + } + break; + + case RGB: + for (int i = 0; i <= 25; i++, n++) { + bgr_tab[n][0] = 0; + bgr_tab[n][1] = 0; + bgr_tab[n][2] = 0; + } + n--; + for (int i = 0; i <= 50; i++, n++) + { + bgr_tab[n][0] = i * 255.0 / 50.0; + bgr_tab[n][1] = 0; + bgr_tab[n][2] = 0; + } + n--; + for (int i = 0; i <= 50; i++, n++) + { + bgr_tab[n][0] = 255; + bgr_tab[n][1] = i * 255.0 / 50.0; + bgr_tab[n][2] = 0; + } + n--; + for (int i = 0; i <= 50; i++, n++) + { + bgr_tab[n][0] = 255 - i * 255.0 / 50.0; + bgr_tab[n][1] = 255; + bgr_tab[n][2] = 0; + } + n--; + for (int i = 0; i <= 29; i++, n++) + { + bgr_tab[n][0] = 0; + bgr_tab[n][1] = 255; + bgr_tab[n][2] = i * 255.0 / 29.0; + } + n--; + for (int i = 0; i <= 51; i++, n++) + { + bgr_tab[n][0] = 0; + bgr_tab[n][1] = 255 - i * 255.0 / 51.0; + bgr_tab[n][2] = 255; + } + break; + case Gray: + for (int i = 0; i <= 255; i++, n++) { + bgr_tab[n][0] = i; + bgr_tab[n][1] = i; + bgr_tab[n][2] = i; + } + break; + default:break; + } + if (reverse) + { + for (int i = 0; i < 128; ++i) { + for (int j = 0; j < 3; ++j) { + uint8_t temp = bgr_tab[i][j]; + bgr_tab[i][j] = bgr_tab[255 - i][j]; + bgr_tab[255 - i][j] = temp; + } + } + } +} + +Mat bgr_tab_image(int w, int h_onecolor, uint8_t(*bgr_tab)[3]) +{ + Mat dst(h_onecolor * 256, w, CV_8UC3); + for (int n = 0; n < h_onecolor * 256; n++) + { + dst.row(h_onecolor * 256 - 1 - n) = cv::Scalar(bgr_tab[n / h_onecolor][0], bgr_tab[n / h_onecolor][1], bgr_tab[n / h_onecolor][2]); + } + return dst; +} + +float get_img_data(Mat src, int x, int y) +{ + float data = 0.0; + if (src.type() == CV_16UC1) + { + data = src.at(y, x); + } + else if (src.type() == CV_32FC1) + { + data = src.at(y, x); + } + else if (src.type() == CV_8UC1) + { + data = src.at(y, x); + } + return data; +} + +PseudoInfo get_pseudo_info(Mat src, Mat mask, float max, float min) +{ + PseudoInfo info; + info.maxOD = min; + info.minOD = max; + info.IOD = 0; + info.count = 0; + info.AOD = 0; + + unsigned char* pMask = mask.ptr(0); + for (int y = 0; y < src.rows; y++) + { + for (int x = 0; x < src.cols; x++) + { + if (*pMask == 255) + { + float data = get_img_data(src, x, y); + if (data > min) + { + if (data < info.minOD) + info.minOD = data; + if (data > info.maxOD) + info.maxOD = data; + info.IOD += data; + info.count++; + } + } + pMask++; + } + } + if (info.count != 0) + info.AOD = info.IOD / info.count; + else { + info.maxOD = 0; + info.minOD = 0; + } + return info; +} + +int pseudo_color_processing(Mat src, Mat dst, float max, float min, uint8_t(*bgr_tab)[3]) +{ + if (dst.type() != CV_8UC3) + { + return -1; + } + uint8_t* pDst = dst.ptr(0); + + float rotia = 255.0 / (max - min); + for (int y = 0; y < src.rows; y++) + { + for (int x = 0; x < src.cols; x++) + { + + float data = get_img_data(src, x, y); + if (data <= min) + { + *(pDst + 0) = 0;//bgr_tab[0][0]; + *(pDst + 1) = 0;//bgr_tab[0][1]; + *(pDst + 2) = 0;//bgr_tab[0][2]; + } + else if (data > min && data <= max) + { + int c = (data - min) * rotia; + *(pDst + 0) = bgr_tab[c][0]; + *(pDst + 1) = bgr_tab[c][1]; + *(pDst + 2) = bgr_tab[c][2]; + } + else + { + *(pDst + 0) = bgr_tab[255][0]; + *(pDst + 1) = bgr_tab[255][1]; + *(pDst + 2) = bgr_tab[255][2]; + } + pDst += 3; + } + } + return 0; +} + +Mat bgr_scale_image(Mat src, float maxVal, float minVal, int scientific_flag) +{ + int w = src.cols; + int h = src.rows; + int h_color = h / 256; + int start = 2 * h_color; + float rotia = 255.0 / (maxVal - minVal); + Mat image = Mat(h + 2 * start, 3 * w, CV_8UC3); + image.setTo(255); + src.copyTo(image(Rect(0, start, w, h))); + + float diff = maxVal - minVal; + int exponent = static_cast(std::log10(diff)); + float normalized = diff / std::pow(10, exponent); + int firstDigit = static_cast(normalized); + float result = firstDigit * std::pow(10, exponent); + + int numTicks = 0; + float tickInterval = 0; + if (firstDigit >= 6) { + tickInterval = 2 * std::pow(10, exponent); + } + else if (firstDigit >= 3) { + tickInterval = std::pow(10, exponent); + } + else { + tickInterval = std::pow(10, exponent) / 2; + } + + std::vector tickData; + float tick = tickInterval; + while (1) + { + if (tick >= minVal && tick <= maxVal) + { + tickData.push_back(tick); + } + else if (tick > maxVal) + { + break; + } + tick += tickInterval; + } + std::vector smallTickData; + tick = tickInterval / 5.0; + while (1) + { + if (tick >= minVal && tick <= maxVal) + { + smallTickData.push_back(tick); + } + else if (tick > maxVal) + { + break; + } + tick += tickInterval / 5.0; + } + + + if (scientific_flag) + { + std::stringstream ss; + ss << "x10^" << exponent; + std::string text = ss.str(); + putText(image, text, Point(2 * w, image.rows / 2), FONT_HERSHEY_SIMPLEX, 1.5, Scalar(0, 0, 0), 3, LINE_AA); + } + + int scale_w = 40; + int scale_h = 5; + for (int i = 0; i < smallTickData.size(); i++) + { + int yPos = image.rows - start - (smallTickData[i] - minVal) * rotia * h_color; + line(image, Point(w, yPos), Point(scale_w * 2 / 3 + w, yPos), Scalar(0, 0, 0), scale_h / 2); + } + for (int i = 0; i < tickData.size(); i++) + { + int yPos = image.rows - start - (tickData[i] - minVal) * rotia * h_color; + line(image, Point(w, yPos), Point(scale_w + w, yPos), Scalar(0, 0, 0), scale_h); + + if (scientific_flag) + { + tickData[i] /= std::pow(10, exponent); + } + + std::ostringstream oss; + if (tickData[i] == int(tickData[i])) { + oss << static_cast(tickData[i]); + } + else { + oss.precision(1); + oss << std::fixed << tickData[i]; + } + std::string text = oss.str(); + putText(image, text, Point(scale_w * 3 / 2 + w, yPos + 5), FONT_HERSHEY_SIMPLEX, 1.5, Scalar(0, 0, 0), 2, LINE_AA); + } + + return image; +} + +Mat get_photon_image(Mat src, float sec, float Wcm, float Hcm, float sr) +{ + cv::Mat src_float32; + src.convertTo(src_float32, CV_32FC1); + float pixel_W = Wcm / src.cols; + float pixel_H = Hcm / src.rows; + + Mat dst = src_float32 / sec / (pixel_W * pixel_H) / sr; + + return dst; +} + +Mat get_magic_wand_image(Mat src, int x, int y, int th) +{ + Mat matDst = cv::Mat::zeros(src.size(), CV_8UC1); + cv::Point2i pt(x, y); + cv::Point2i ptGrowing; + int nGrowLable = 0; + int nSrcValue = 0; + int nCurValue = 0; + int mat_cnt = 0; + int DIR[8][2] = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 }, { -1, 0 } }; + std::vector vcGrowPt; + vcGrowPt.push_back(pt); + matDst.at(pt.y, pt.x) = 255; + nSrcValue = src.at(pt.y, pt.x); + while (!vcGrowPt.empty()) + { + pt = vcGrowPt.back(); + vcGrowPt.pop_back(); + + std::vector temp_vcGrowPt; + int temp_vcGrowPt_size = 0; + // nSrcValue = src.at(pt.y, pt.x); + //ֱ԰˸ϵĵ + for (int i = 0; i < 8; ++i) + { + ptGrowing.x = pt.x + DIR[i][0]; + ptGrowing.y = pt.y + DIR[i][1]; + //ǷDZԵ + if (ptGrowing.x < 0 || ptGrowing.y < 0 || ptGrowing.x >(src.cols - 1) || (ptGrowing.y > src.rows - 1)) + continue; + + nGrowLable = matDst.at(ptGrowing.y, ptGrowing.x); //ǰĻҶֵ + if (nGrowLable == 0) //ǵ㻹ûб + { + nCurValue = src.at(ptGrowing.y, ptGrowing.x); + if (abs(nCurValue - nSrcValue) < th) //ֵΧ + { + // matDst.at(ptGrowing.y, ptGrowing.x) = 255; + temp_vcGrowPt_size++; + temp_vcGrowPt.push_back(ptGrowing); //һѹջ + } + } + else { + temp_vcGrowPt_size++; + } + } + //ڵ㲻ǵЧ + if (temp_vcGrowPt_size >= 1) { + mat_cnt++; + matDst.at(pt.y, pt.x) = 255; + vcGrowPt.insert(vcGrowPt.end(), temp_vcGrowPt.begin(), temp_vcGrowPt.end()); + } + } + return matDst; +} diff --git a/src/PBBiology/src/PBLane.cpp b/src/PBBiology/src/PBLane.cpp new file mode 100644 index 0000000..3d2beaf --- /dev/null +++ b/src/PBBiology/src/PBLane.cpp @@ -0,0 +1,714 @@ +#include "../include/PBLane.h" + + +bool PBLane::myCompare(const int& a, const int& b) +{ + return a < b; +} +bool PBLane::myCompare2(const std::array& a, const std::array& b) +{ + return a[0] < b[0]; +} + +std::vector PBLane::processArray(std::vector& groupsX, int minDifference, int maxDifference) +{ + std::vector result; + + for (size_t i = 0; i < groupsX.size(); ++i) { + if (i == groupsX.size() - 1) { + result.push_back(groupsX[i]); + break; + } + + int diff = groupsX[i + 1] - groupsX[i]; + + if (diff < minDifference) { + groupsX[i + 1] = groupsX[i]; + continue; + } + else { + result.push_back(groupsX[i]); + if (diff > maxDifference) { + int numInserts = (int)std::ceil(diff / static_cast(maxDifference)) - 1; + int step = diff / (numInserts + 1); + + for (int j = 1; j <= numInserts; ++j) { + result.push_back(groupsX[i] + j * step); + } + for (size_t i = 1; i < result.size(); ++i) { + if ((std::abs(result[i] - result[i - 1]) > maxDifference) || (std::abs(result[i] - result[i - 1]) < minDifference)) { + result.erase(result.end() - numInserts, result.end()); + } + } + } + } + } + return result; +} + +vector PBLane::get_bar_num(vector buf) +{ + vector w; + unsigned int y1_thresh = 4; + unsigned int y1_min_thresh = 4; + unsigned int width = 0; + unsigned int last_edge = 0; + unsigned int cur_edge = 0; + int y1_sign = 0; + int y0_0, y0_1, y0_2, y0_3; + int y1_1, y2_1, y2_2; + int y0[4]; + y0_0 = y0_1 = y0[0] = y0[1] = y0[2] = y0[3] = buf[0]; + for (int i = 0; i < buf.size(); i++) + { + y0_0 = y0_1 = y0[(i - 1) & 3]; + y0_0 += ((int)((buf[i] - y0_1) * EWMA_WEIGHT)) >> ZBAR_FIXED; + y0[i & 3] = y0_0; + y0_2 = y0[(i - 2) & 3]; + y0_3 = y0[(i - 3) & 3]; + y1_1 = y0_1 - y0_2; + + int abs_y1_1 = abs(y1_1); + int y1_2 = y0_2 - y0_3; + y2_1 = y0_0 - y0_1 - y1_1; + y2_2 = y1_1 - y1_2; + + if ((abs_y1_1 < abs(y1_2)) && ((y1_1 >= 0) == (y1_2 >= 0))) + y1_1 = y1_2; + + if (!y2_1 || ((y2_1 >= 0) ? y2_2 < 0 : y2_2 > 0)) + { + unsigned temp_thresh; + unsigned dx, thresh = y1_thresh; + unsigned long t; + + if ((thresh <= y1_min_thresh) || !width) { + temp_thresh = y1_min_thresh; + } + else { + dx = (i << ZBAR_FIXED) - last_edge; + t = thresh * dx; + t /= width; + t /= ZBAR_SCANNER_THRESH_FADE; + int temp_t = thresh - t; + if ((temp_t > 0) && (temp_t > y1_min_thresh)) { + temp_thresh = temp_t; + } + else { + y1_thresh = y1_min_thresh; + temp_thresh = y1_min_thresh; + } + } + if ((temp_thresh) <= abs_y1_1) + { + char y1_rev = (y1_sign > 0) ? y1_1 < 0 : y1_1 > 0; + if (y1_rev) { + if (!y1_sign) + last_edge = cur_edge = (1 << ZBAR_FIXED) + ROUND; + else if (!last_edge) + last_edge = cur_edge; + width = cur_edge - last_edge; + last_edge = cur_edge; + // printf("i=%d,width=%d\n",i,width); + w.push_back(i); + } + if (y1_rev || (abs(y1_sign) < abs_y1_1)) { + int d; + y1_sign = y1_1; + y1_thresh = (abs_y1_1 * THRESH_INIT + ROUND) >> ZBAR_FIXED; + if (y1_thresh < y1_min_thresh) + y1_thresh = y1_min_thresh; + + d = y2_1 - y2_2; + cur_edge = 1 << ZBAR_FIXED; + if (!d) { + cur_edge >>= 1; + } + else if (y2_1) { + cur_edge -= ((y2_1 << ZBAR_FIXED) + 1) / d; + } + cur_edge += i << ZBAR_FIXED; + } + } + } + } + return w; +} + + +std::vector PBLane::checkArray(std::vector& processX, Mat src, int start_y, int end_y, int meanW) +{ + std::vector result; + std::vector diffX(processX.size() - 1); + for (int i = 1; i < processX.size(); i++) + { + diffX[i - 1] = processX[i] - processX[i - 1]; + } + std::sort(diffX.begin(), diffX.end(), myCompare); + int meanDiffX = 0; + int cnt = 0; + for (int i = diffX.size() / 3; i <= 2 * diffX.size() / 3; i++) + { + meanDiffX += diffX[i]; + cnt++; + } + meanDiffX /= cnt; + + int ret = 0; + int len_H = end_y - start_y; + vector w1; + vector w2; + vector rowPixels1(len_H); + vector rowPixels2(len_H); + cnt = 0; + while (1) + { + cnt++; + int dealX = processX[0] - (meanDiffX * cnt); + if (dealX < meanDiffX / 2) { break; } + + for (int col = 0; col < len_H; col++) { + rowPixels1[col] = src.at(start_y + col, dealX - meanW / 4); + rowPixels2[col] = src.at(start_y + col, dealX + meanW / 4); + } + w1 = get_bar_num(rowPixels1); + w2 = get_bar_num(rowPixels2); + ret = 0; + if (w1.size() && w2.size()) + { + for (int i = 0; i < w1.size(); i++) + { + for (int j = 0; j < w2.size(); j++) + { + if (abs(w1[i] - w2[j]) <= 2) { + ret = 1; + break; + } + } + } + } + if (ret) { + result.push_back(dealX); + } + else { + break; + } + } + + for (int i = 0; i < processX.size(); i++) + { + for (int col = 0; col < len_H; col++) { + rowPixels1[col] = src.at(start_y + col, processX[i] - meanW / 4); + rowPixels2[col] = src.at(start_y + col, processX[i] + meanW / 4); + } + w1 = get_bar_num(rowPixels1); + w2 = get_bar_num(rowPixels2); + ret = 0; + if (w1.size() && w2.size()) + { + for (int i = 0; i < w1.size(); i++) + { + for (int j = 0; j < w2.size(); j++) + { + if (abs(w1[i] - w2[j]) <= 2) { + ret = 1; + break; + } + } + } + } + if (ret) { + result.push_back(processX[i]); + } + } + + cnt = 0; + while (1) + { + cnt++; + int dealX = processX[processX.size() - 1] + (meanDiffX * cnt); + if (dealX > (src.cols - meanDiffX / 2)) { break; } + + for (int col = 0; col < len_H; col++) { + rowPixels1[col] = src.at(start_y + col, dealX - meanW / 4); + rowPixels2[col] = src.at(start_y + col, dealX + meanW / 4); + } + w1 = get_bar_num(rowPixels1); + w2 = get_bar_num(rowPixels2); + ret = 0; + if (w1.size() && w1.size() == w2.size()) + { + for (int i = 0; i < w1.size(); i++) + { + if (abs(w1[i] - w2[i]) > 2) { + ret = 0; + break; + } + } + ret = 1; + } + if (ret) { + result.push_back(dealX); + } + else { + break; + } + } + + std::sort(result.begin(), result.end(), myCompare); + return result; +} + +vector> PBLane::get_top_point(vector rbuf, int range) +{ + vector> point; + vector diff(rbuf.size()); + + int maxValue = *max_element(rbuf.begin(), rbuf.end()); + int minValue = *min_element(rbuf.begin(), rbuf.end()); + int limit = (maxValue - minValue) / 10; + + for (int i = 0; i < rbuf.size() - 1; i++) + { + if (rbuf[i + 1] - rbuf[i] > 0) + diff[i] = 1; + else if (rbuf[i + 1] - rbuf[i] < 0) + diff[i] = -1; + else + diff[i] = 0; + } + for (int i = rbuf.size() - 1; i >= 0; i--) + { + if (diff[i] == 0 && i == rbuf.size() - 1) + { + diff[i] = 1; + } + else if (diff[i] == 0) + { + if (diff[i + 1] >= 0) + diff[i] = 1; + else + diff[i] = -1; + } + } + for (int i = 0; i != rbuf.size() - 1; i++) + { + diff[i] = diff[i + 1] - diff[i]; + } + + unsigned char flag = 0; + for (int i = 0; i != rbuf.size() - 1; i++) + { + if (flag == 0 && diff[i] == 2)//bottom + { + point.push_back({ i + 1, 0 }); + flag = 1; + } + else if (flag == 1 && diff[i] == -2)//top + { + point.push_back({ i + 1, 1 }); + flag = 0; + } + } + + for (int i = 0; i < point.size(); i++) + { + for (int j = 0; j < point.size(); j++) + { + if (point[i][1] == 1 && point[j][1] == 1) + { + if (point[i][0] > point[j][0]) + { + if (point[i][0] - point[j][0] <= range && rbuf[point[i][0]] < rbuf[point[j][0]]) + { + point[i][1] = 255; + break; + } + } + else if (point[i][0] < point[j][0]) + { + if (point[j][0] - point[i][0] <= range) + { + if (rbuf[point[i][0]] < rbuf[point[j][0]]) + { + point[i][1] = 255; + break; + } + } + else + { + break; + } + } + } + else if (point[i][1] == 0 && point[j][1] == 0) + { + if (point[i][0] > point[j][0]) + { + if (point[i][0] - point[j][0] <= range && rbuf[point[i][0]] > rbuf[point[j][0]]) + { + point[i][1] = 255; + break; + } + } + else if (point[i][0] < point[j][0]) + { + if (point[j][0] - point[i][0] <= range) + { + if (rbuf[point[i][0]] > rbuf[point[j][0]]) + { + point[i][1] = 255; + break; + } + } + else + { + break; + } + } + } + } + } + + vector filterPoint; + flag = 0; + int temp = 0; + for (int i = 0; i < point.size(); i++) + { + if (flag == 1)//top + { + if (point[i][1] == 1) + { + if (rbuf[point[temp][0]] <= rbuf[point[i][0]]) + { + temp = i; + } + } + else if (point[i][1] == 0) + { + filterPoint.push_back(point[temp][0]); + temp = i; + flag = 0; + } + } + else if (flag == 0)//bottom + { + if (point[i][1] == 0) + { + if (rbuf[point[temp][0]] >= rbuf[point[i][0]]) + { + temp = i; + } + } + else if (point[i][1] == 1) + { + filterPoint.push_back(point[temp][0]); + temp = i; + flag = 1; + } + } + } + filterPoint.push_back(point[temp][0]); + + vector> topPoint; + if (filterPoint.size() < 3) + { + return topPoint; + } + + for (int i = 1; i < filterPoint.size() - 1; i += 1) + { + if (rbuf[filterPoint[i]] - rbuf[filterPoint[i - 1]] > limit && rbuf[filterPoint[i]] - rbuf[filterPoint[i + 1]] > limit) + { + int len_left = filterPoint[i] - filterPoint[i - 1]; + int len_right = filterPoint[i + 1] - filterPoint[i]; + if (len_left > len_right && len_left / len_right >= 3) + { + filterPoint[i - 1] = filterPoint[i] - len_right * 3; + } + else if (len_right > len_left && len_right / len_left >= 3) + { + filterPoint[i + 1] = filterPoint[i] + len_left * 3; + } + + topPoint.push_back({ filterPoint[i],filterPoint[i - 1],filterPoint[i + 1] }); + } + } + return topPoint; +} + +BandInfo PBLane::get_protein_lane_data(Mat src, Rect lane) +{ + BandInfo band; + int sum = 0; + vector cdata; + for (int i = lane.y; i < lane.y + lane.height; i++) + { + sum = 0; + for (int j = lane.x; j < lane.x + lane.width; j++) + { + sum += src.at(i, j); + } + sum /= lane.width; + band.land_data.push_back((unsigned short)sum); + band.ydata.push_back((float)((65535 - sum) / 255.0)); + cdata.push_back((unsigned char)((65535 - sum) >> 8)); + } + for (int i = 0; i < lane.height; i++) + { + band.xdata.push_back((float)i / lane.height); + } + band.band_point = get_top_point(cdata, 8); + return band; +} + + +PBLane::PBLane() {} + +PBLane::~PBLane() {} + +std::vector PBLane::getProteinRect(Mat src) +{ + cv::Mat edges; + Canny(src, edges, 50, 150); + + std::vector> contours; + findContours(edges, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE); + + std::vector boundingRects; + for (const auto& contour : contours) { + cv::Rect rect = cv::boundingRect(contour); + double area = rect.area(); + if (area < 20 || area > 700) { + continue; + } + double rotia = 0.0; + rotia = (double)rect.width / rect.height; + if (rotia >= 7 || rotia <= 2) { + continue; + } + boundingRects.push_back(rect); + } + + std::vector allX(boundingRects.size()); + std::vector allY(boundingRects.size()); + std::vector allW(boundingRects.size()); + int up = src.rows; + int down = 0; + for (int i = 0; i < boundingRects.size(); i++) + { + allX[i] = boundingRects[i].x + boundingRects[i].width / 2; + allY[i] = boundingRects[i].y + boundingRects[i].height / 2; + allW[i] = boundingRects[i].width; + up = min(boundingRects[i].y, up); + down = max(boundingRects[i].y + boundingRects[i].height, down); + } + int meanW = 0; + int meanY = 0; + int maxH = 0; + std::sort(allW.begin(), allW.end(), myCompare); + std::sort(allY.begin(), allY.end(), myCompare); + std::sort(allX.begin(), allX.end(), myCompare); + int cnt = 0; + if (boundingRects.size() == 0) + { + std::vector proteinRect1(boundingRects.size()); + return proteinRect1; + } + for (int i = boundingRects.size() / 3; i <= 2 * boundingRects.size() / 3; i++) + { + cnt++; + meanW += allW[i]; + meanY += allY[i]; + } + meanW /= cnt; + meanY /= cnt; + maxH = max(down - meanY, meanY - up) * 2; + maxH = max(maxH, src.rows / 3); + std::vector groupsX; + const int n = 3; + int sumX = allX[0]; + cnt = 1; + for (int i = 1; i < boundingRects.size(); i++) { + if (allX[i] - allX[i - 1] > n) + { + groupsX.push_back(sumX / cnt); + sumX = 0; + cnt = 0; + } + sumX += allX[i]; + cnt++; + } + groupsX.push_back(sumX / cnt); + + std::vector processX = processArray(groupsX, meanW, meanW * 1.8); + std::vector proteinX = checkArray(processX, src, 15, src.rows - 30, meanW); + std::vector proteinRect(proteinX.size()); + for (int i = 0; i < proteinX.size(); i++) + { + proteinRect[i].x = proteinX[i] - meanW / 2; + + proteinRect[i].y = 15;//meanY - maxH/2; + proteinRect[i].width = meanW; + proteinRect[i].height = src.rows - 30; + } + return proteinRect; +} + + +std::vector PBLane::getProteinBands(Mat src, std::vector lanes) +{ + std::vector bands; + if (src.type() != CV_16UC1) + { + std::cout << "The image is not 16-bit single-channel as expected." << std::endl; + return bands; + } + int lanes_num = lanes.size(); + if (lanes_num <= 0) + { + std::cout << "The lanes_num is 0." << std::endl; + return bands; + } + bands.resize(lanes_num); + + for (int i = 0; i < lanes_num; i++) + { + bands[i] = get_protein_lane_data(src, lanes[i]); + } + //adjustBands(bands, 10); + return bands; +} + + +void PBLane::adjustBands(std::vector& bands, int range) +{ + // ڴ洢еֵӦ + std::map columnMap; + + std::vector> vec; + for (int i = 0; i < bands.size(); i++) + { + for (int j = 0; j < bands[i].band_point.size(); j++) + { + std::array bp = { bands[i].band_point[j][0],bands[i].band_point[j][1],bands[i].band_point[j][2],i }; + vec.push_back(bp); + } + bands[i].band_point.clear(); + } + std::sort(vec.begin(), vec.end(), myCompare2); + + vector point; + point.push_back(0); + vector onep; + onep.push_back(vec[0][3]); + + for (int i = 1; i < vec.size(); i++) + { + if (std::find(onep.begin(), onep.end(), vec[i][3]) != onep.end()) + { + point.push_back(i); + onep.clear(); + onep.push_back(vec[i][3]); + } + else + { + if (std::abs(vec[i][0] - vec[point.back()][0]) > range) + { + point.push_back(i); + onep.clear(); + onep.push_back(vec[i][3]); + } + } + } + + for (int i = 0; i < bands.size(); i++) + { + bands[i].band_point.resize(point.size(), { -1,-1,-1 }); + } + + int columnIndex = 1; + point.push_back(-1); + bands[vec[0][3]].band_point[0] = { vec[0][0],vec[0][1],vec[0][2] }; + for (int i = 1; i < vec.size(); i++) + { + if (i != point[columnIndex]) + { + bands[vec[i][3]].band_point[columnIndex - 1] = { vec[i][0],vec[i][1],vec[i][2] }; + } + else + { + columnIndex++; + bands[vec[i][3]].band_point[columnIndex - 1] = { vec[i][0],vec[i][1],vec[i][2] }; + } + } + return; +} + +void PBLane::molecularWeightResult(std::vector lanes, std::vector& bands) +{ + for (int i = 0; i < bands.size(); i++) + { + int rNum = bands[i].band_point.size(); + bands[i].Minfo.resize(rNum); + + unsigned long land_sum = lanes[i].width * std::accumulate(bands[i].ydata.begin(), bands[i].ydata.end(), 0UL); + unsigned long band_sum = 0; + for (int j = 0; j < rNum; j++) + { + std::array point = bands[i].band_point[j]; + if (point[0] != -1) + { + bands[i].Minfo[j].molecular_weight = bands[i].xdata[point[0]]; + bands[i].Minfo[j].band_content = 0; + for (int s = point[1]; s < point[2]; s++) + { + bands[i].Minfo[j].band_content += bands[i].ydata[s] * lanes[i].width; + } + bands[i].Minfo[j].IOD = bands[i].Minfo[j].band_content; + band_sum += bands[i].Minfo[j].band_content; + bands[i].Minfo[j].maxOD = bands[i].ydata[point[0]]; + } + else + { + bands[i].Minfo[j].molecular_weight = -1; + bands[i].Minfo[j].band_content = -1; + bands[i].Minfo[j].IOD = -1; + bands[i].Minfo[j].maxOD = -1; + } + } + for (int j = 0; j < rNum; j++) + { + std::array point = bands[i].band_point[j]; + if (point[0] != -1) + { + bands[i].Minfo[j].relative_content = 100.0 * bands[i].Minfo[j].band_content / band_sum; + bands[i].Minfo[j].percentum = 100.0 * bands[i].Minfo[j].IOD / land_sum; + + if (bands[0].band_point[j][0] != -1) + { + bands[i].Minfo[j].match = 1; + } + else + { + bands[i].Minfo[j].match = -1; + } + } + else + { + bands[i].Minfo[j].relative_content = -1; + bands[i].Minfo[j].percentum = -1; + + if (bands[0].band_point[j][0] != -1) + { + bands[i].Minfo[j].match = 0; + } + else + { + bands[i].Minfo[j].match = -255; + } + } + } + } + return; +} \ No newline at end of file diff --git a/src/PBBiologyAlg/AssemblyInfo.cpp b/src/PBBiologyAlg/AssemblyInfo.cpp new file mode 100644 index 0000000..f6efb80 --- /dev/null +++ b/src/PBBiologyAlg/AssemblyInfo.cpp @@ -0,0 +1,20 @@ + + +using namespace System; +using namespace System::Reflection; +using namespace System::Runtime::CompilerServices; +using namespace System::Runtime::InteropServices; +using namespace System::Security::Permissions; + +[assembly:AssemblyTitleAttribute(L"PBBiologyAlg")]; +[assembly:AssemblyDescriptionAttribute(L"")]; +[assembly:AssemblyConfigurationAttribute(L"")]; +[assembly:AssemblyCompanyAttribute(L"")]; +[assembly:AssemblyProductAttribute(L"PBBiologyAlg")]; +[assembly:AssemblyCopyrightAttribute(L"版权所有(c) 2024")]; +[assembly:AssemblyTrademarkAttribute(L"")]; +[assembly:AssemblyCultureAttribute(L"")]; + +[assembly:AssemblyVersionAttribute(L"1.0.*")]; + +[assembly:ComVisible(false)]; diff --git a/src/PBBiologyAlg/PBBiologyAlg.cpp b/src/PBBiologyAlg/PBBiologyAlg.cpp new file mode 100644 index 0000000..df10edf --- /dev/null +++ b/src/PBBiologyAlg/PBBiologyAlg.cpp @@ -0,0 +1,708 @@ +// +//#include "PBBiologyAlg.h" +// +// +// +//namespace PBBiologyAlg +//{ +// bool myCompare(const int& a, const int& b) { +// return a < b; +// } +// +// bool myCompare2(const std::array& a, const std::array& b) { +// return a[0] < b[0]; +// } +// +// std::vector PBBiologyAlg::biologyAPI::processArray(std::vector& groupsX, int minDifference, int maxDifference) +// { +// std::vector result; +// +// for (size_t i = 0; i < groupsX.size(); ++i) { +// if (i == groupsX.size() - 1) { +// result.push_back(groupsX[i]); +// break; +// } +// +// int diff = groupsX[i + 1] - groupsX[i]; +// +// if (diff < minDifference) { +// groupsX[i + 1] = groupsX[i]; +// continue; +// } +// else { +// result.push_back(groupsX[i]); +// if (diff > maxDifference) { +// int numInserts = (int)std::ceil(diff / static_cast(maxDifference)) - 1; +// int step = diff / (numInserts + 1); +// +// for (int j = 1; j <= numInserts; ++j) { +// result.push_back(groupsX[i] + j * step); +// } +// for (size_t i = 1; i < result.size(); ++i) { +// if ((std::abs(result[i] - result[i - 1]) > maxDifference) || (std::abs(result[i] - result[i - 1]) < minDifference)) { +// result.erase(result.end() - numInserts, result.end()); +// } +// } +// } +// } +// } +// return result; +// } +// +//#define ZBAR_FIXED 5 +//#define ROUND (1 << (ZBAR_FIXED - 1)) +//#define ZBAR_SCANNER_THRESH_FADE 8 +//#define EWMA_WEIGHT ((unsigned)((.78 * (1 << (ZBAR_FIXED + 1)) + 1) / 2)) +//#define THRESH_INIT ((unsigned)((.44 * (1 << (ZBAR_FIXED + 1)) + 1) / 2)) +// vector PBBiologyAlg::biologyAPI::get_bar_num(vector buf) +// { +// vector w; +// unsigned int y1_thresh = 4; +// unsigned int y1_min_thresh = 4; +// unsigned int width = 0; +// unsigned int last_edge = 0; +// unsigned int cur_edge = 0; +// int y1_sign = 0; +// int y0_0, y0_1, y0_2, y0_3; +// int y1_1, y2_1, y2_2; +// int y0[4]; +// y0_0 = y0_1 = y0[0] = y0[1] = y0[2] = y0[3] = buf[0]; +// for (int i = 0; i < buf.size(); i++) +// { +// y0_0 = y0_1 = y0[(i - 1) & 3]; +// y0_0 += ((int)((buf[i] - y0_1) * EWMA_WEIGHT)) >> ZBAR_FIXED; +// y0[i & 3] = y0_0; +// y0_2 = y0[(i - 2) & 3]; +// y0_3 = y0[(i - 3) & 3]; +// y1_1 = y0_1 - y0_2; +// +// int abs_y1_1 = abs(y1_1); +// int y1_2 = y0_2 - y0_3; +// y2_1 = y0_0 - y0_1 - y1_1; +// y2_2 = y1_1 - y1_2; +// +// if ((abs_y1_1 < abs(y1_2)) && ((y1_1 >= 0) == (y1_2 >= 0))) +// y1_1 = y1_2; +// +// if (!y2_1 || ((y2_1 >= 0) ? y2_2 < 0 : y2_2 > 0)) +// { +// unsigned temp_thresh; +// unsigned dx, thresh = y1_thresh; +// unsigned long t; +// +// if ((thresh <= y1_min_thresh) || !width) { +// temp_thresh = y1_min_thresh; +// } +// else { +// dx = (i << ZBAR_FIXED) - last_edge; +// t = thresh * dx; +// t /= width; +// t /= ZBAR_SCANNER_THRESH_FADE; +// int temp_t = thresh - t; +// if ((temp_t > 0) && (temp_t > y1_min_thresh)) { +// temp_thresh = temp_t; +// } +// else { +// y1_thresh = y1_min_thresh; +// temp_thresh = y1_min_thresh; +// } +// } +// if ((temp_thresh) <= abs_y1_1) +// { +// char y1_rev = (y1_sign > 0) ? y1_1 < 0 : y1_1 > 0; +// if (y1_rev) { +// if (!y1_sign) +// last_edge = cur_edge = (1 << ZBAR_FIXED) + ROUND; +// else if (!last_edge) +// last_edge = cur_edge; +// width = cur_edge - last_edge; +// last_edge = cur_edge; +// // printf("i=%d,width=%d\n",i,width); +// w.push_back(i); +// } +// if (y1_rev || (abs(y1_sign) < abs_y1_1)) { +// int d; +// y1_sign = y1_1; +// y1_thresh = (abs_y1_1 * THRESH_INIT + ROUND) >> ZBAR_FIXED; +// if (y1_thresh < y1_min_thresh) +// y1_thresh = y1_min_thresh; +// +// d = y2_1 - y2_2; +// cur_edge = 1 << ZBAR_FIXED; +// if (!d) { +// cur_edge >>= 1; +// } +// else if (y2_1) { +// cur_edge -= ((y2_1 << ZBAR_FIXED) + 1) / d; +// } +// cur_edge += i << ZBAR_FIXED; +// } +// } +// } +// } +// return w; +// } +// +// +// std::vector PBBiologyAlg::biologyAPI::checkArray(std::vector& processX, Mat src, int start_y, int end_y, int meanW) +// { +// std::vector result; +// std::vector diffX(processX.size() - 1); +// for (int i = 1; i < processX.size(); i++) +// { +// diffX[i - 1] = processX[i] - processX[i - 1]; +// } +// std::sort(diffX.begin(), diffX.end(), myCompare); +// int meanDiffX = 0; +// int cnt = 0; +// for (int i = diffX.size() / 3; i <= 2 * diffX.size() / 3; i++) +// { +// meanDiffX += diffX[i]; +// cnt++; +// } +// meanDiffX /= cnt; +// +// int ret = 0; +// int len_H = end_y - start_y; +// vector w1; +// vector w2; +// vector rowPixels1(len_H); +// vector rowPixels2(len_H); +// cnt = 0; +// while (1) +// { +// cnt++; +// int dealX = processX[0] - (meanDiffX * cnt); +// if (dealX < meanDiffX / 2) { break; } +// +// for (int col = 0; col < len_H; col++) { +// rowPixels1[col] = src.at(start_y + col, dealX - meanW / 4); +// rowPixels2[col] = src.at(start_y + col, dealX + meanW / 4); +// } +// w1 = get_bar_num(rowPixels1); +// w2 = get_bar_num(rowPixels2); +// ret = 0; +// if (w1.size() && w2.size()) +// { +// for (int i = 0; i < w1.size(); i++) +// { +// for (int j = 0; j < w2.size(); j++) +// { +// if (abs(w1[i] - w2[j]) <= 2) { +// ret = 1; +// break; +// } +// } +// } +// } +// if (ret) { +// result.push_back(dealX); +// } +// else { +// break; +// } +// } +// +// for (int i = 0; i < processX.size(); i++) +// { +// for (int col = 0; col < len_H; col++) { +// rowPixels1[col] = src.at(start_y + col, processX[i] - meanW / 4); +// rowPixels2[col] = src.at(start_y + col, processX[i] + meanW / 4); +// } +// w1 = get_bar_num(rowPixels1); +// w2 = get_bar_num(rowPixels2); +// ret = 0; +// if (w1.size() && w2.size()) +// { +// for (int i = 0; i < w1.size(); i++) +// { +// for (int j = 0; j < w2.size(); j++) +// { +// if (abs(w1[i] - w2[j]) <= 2) { +// ret = 1; +// break; +// } +// } +// } +// } +// if (ret) { +// result.push_back(processX[i]); +// } +// } +// +// cnt = 0; +// while (1) +// { +// cnt++; +// int dealX = processX[processX.size() - 1] + (meanDiffX * cnt); +// if (dealX > (src.cols - meanDiffX / 2)) { break; } +// +// for (int col = 0; col < len_H; col++) { +// rowPixels1[col] = src.at(start_y + col, dealX - meanW / 4); +// rowPixels2[col] = src.at(start_y + col, dealX + meanW / 4); +// } +// w1 = get_bar_num(rowPixels1); +// w2 = get_bar_num(rowPixels2); +// ret = 0; +// if (w1.size() && w1.size() == w2.size()) +// { +// for (int i = 0; i < w1.size(); i++) +// { +// if (abs(w1[i] - w2[i]) > 2) { +// ret = 0; +// break; +// } +// } +// ret = 1; +// } +// if (ret) { +// result.push_back(dealX); +// } +// else { +// break; +// } +// } +// +// std::sort(result.begin(), result.end(), myCompare); +// return result; +// } +// +// vector> PBBiologyAlg::biologyAPI::get_top_point(vector rbuf, int range) +// { +// vector> point; +// vector diff(rbuf.size()); +// +// int maxValue = *max_element(rbuf.begin(), rbuf.end()); +// int minValue = *min_element(rbuf.begin(), rbuf.end()); +// int limit = (maxValue - minValue) / 10; +// +// for (int i = 0; i < rbuf.size() - 1; i++) +// { +// if (rbuf[i + 1] - rbuf[i] > 0) +// diff[i] = 1; +// else if (rbuf[i + 1] - rbuf[i] < 0) +// diff[i] = -1; +// else +// diff[i] = 0; +// } +// for (int i = rbuf.size() - 1; i >= 0; i--) +// { +// if (diff[i] == 0 && i == rbuf.size() - 1) +// { +// diff[i] = 1; +// } +// else if (diff[i] == 0) +// { +// if (diff[i + 1] >= 0) +// diff[i] = 1; +// else +// diff[i] = -1; +// } +// } +// for (int i = 0; i != rbuf.size() - 1; i++) +// { +// diff[i] = diff[i + 1] - diff[i]; +// } +// +// unsigned char flag = 0; +// for (int i = 0; i != rbuf.size() - 1; i++) +// { +// if (flag == 0 && diff[i] == 2)//bottom +// { +// point.push_back({ i + 1, 0 }); +// flag = 1; +// } +// else if (flag == 1 && diff[i] == -2)//top +// { +// point.push_back({ i + 1, 1 }); +// flag = 0; +// } +// } +// +// for (int i = 0; i < point.size(); i++) +// { +// for (int j = 0; j < point.size(); j++) +// { +// if (point[i][1] == 1 && point[j][1] == 1) +// { +// if (point[i][0] > point[j][0]) +// { +// if (point[i][0] - point[j][0] <= range && rbuf[point[i][0]] < rbuf[point[j][0]]) +// { +// point[i][1] = 255; +// break; +// } +// } +// else if (point[i][0] < point[j][0]) +// { +// if (point[j][0] - point[i][0] <= range) +// { +// if (rbuf[point[i][0]] < rbuf[point[j][0]]) +// { +// point[i][1] = 255; +// break; +// } +// } +// else +// { +// break; +// } +// } +// } +// else if (point[i][1] == 0 && point[j][1] == 0) +// { +// if (point[i][0] > point[j][0]) +// { +// if (point[i][0] - point[j][0] <= range && rbuf[point[i][0]] > rbuf[point[j][0]]) +// { +// point[i][1] = 255; +// break; +// } +// } +// else if (point[i][0] < point[j][0]) +// { +// if (point[j][0] - point[i][0] <= range) +// { +// if (rbuf[point[i][0]] > rbuf[point[j][0]]) +// { +// point[i][1] = 255; +// break; +// } +// } +// else +// { +// break; +// } +// } +// } +// } +// } +// +// vector filterPoint; +// flag = 0; +// int temp = 0; +// for (int i = 0; i < point.size(); i++) +// { +// if (flag == 1)//top +// { +// if (point[i][1] == 1) +// { +// if (rbuf[point[temp][0]] <= rbuf[point[i][0]]) +// { +// temp = i; +// } +// } +// else if (point[i][1] == 0) +// { +// filterPoint.push_back(point[temp][0]); +// temp = i; +// flag = 0; +// } +// } +// else if (flag == 0)//bottom +// { +// if (point[i][1] == 0) +// { +// if (rbuf[point[temp][0]] >= rbuf[point[i][0]]) +// { +// temp = i; +// } +// } +// else if (point[i][1] == 1) +// { +// filterPoint.push_back(point[temp][0]); +// temp = i; +// flag = 1; +// } +// } +// } +// filterPoint.push_back(point[temp][0]); +// +// vector> topPoint; +// if (filterPoint.size() < 3) +// { +// return topPoint; +// } +// +// for (int i = 1; i < filterPoint.size() - 1; i += 1) +// { +// if (rbuf[filterPoint[i]] - rbuf[filterPoint[i - 1]] > limit && rbuf[filterPoint[i]] - rbuf[filterPoint[i + 1]] > limit) +// { +// topPoint.push_back({ filterPoint[i],filterPoint[i - 1],filterPoint[i + 1] }); +// } +// } +// return topPoint; +// } +// +// BandInfo PBBiologyAlg::biologyAPI::get_protein_lane_data(Mat src, Rect lane) +// { +// BandInfo band; +// int sum = 0; +// vector cdata; +// for (int i = lane.y; i < lane.y + lane.height; i++) +// { +// sum = 0; +// for (int j = lane.x; j < lane.x + lane.width; j++) +// { +// sum += src.at(i, j); +// } +// sum /= lane.width; +// band.land_data.push_back((unsigned short)sum); +// band.ydata.push_back((float)((65535 - sum) / 255.0)); +// cdata.push_back((unsigned char)((65535 - sum) >> 8)); +// } +// for (int i = 0; i < lane.height; i++) +// { +// band.xdata.push_back((float)i / lane.height); +// } +// band.band_point = get_top_point(cdata, 8); +// return band; +// } +// +// +// PBBiologyAlg::biologyAPI::biologyAPI() {} +// +// PBBiologyAlg::biologyAPI::~biologyAPI() {} +// +// std::vector PBBiologyAlg::biologyAPI::getProteinRect(Mat src) +// { +// cv::Mat edges; +// Canny(src, edges, 50, 150); +// +// std::vector> contours; +// findContours(edges, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE); +// +// std::vector boundingRects; +// for (const auto& contour : contours) { +// cv::Rect rect = cv::boundingRect(contour); +// double area = rect.area(); +// if (area < 20 || area > 700) { +// continue; +// } +// double rotia = 0.0; +// rotia = (double)rect.width / rect.height; +// if (rotia >= 7 || rotia <= 2) { +// continue; +// } +// boundingRects.push_back(rect); +// } +// +// std::vector allX(boundingRects.size()); +// std::vector allY(boundingRects.size()); +// std::vector allW(boundingRects.size()); +// int up = src.rows; +// int down = 0; +// for (int i = 0; i < boundingRects.size(); i++) +// { +// allX[i] = boundingRects[i].x + boundingRects[i].width / 2; +// allY[i] = boundingRects[i].y + boundingRects[i].height / 2; +// allW[i] = boundingRects[i].width; +// up = min(boundingRects[i].y, up); +// down = max(boundingRects[i].y + boundingRects[i].height, down); +// } +// int meanW = 0; +// int meanY = 0; +// int maxH = 0; +// std::sort(allW.begin(), allW.end(), myCompare); +// std::sort(allY.begin(), allY.end(), myCompare); +// std::sort(allX.begin(), allX.end(), myCompare); +// int cnt = 0; +// for (int i = boundingRects.size() / 3; i <= 2 * boundingRects.size() / 3; i++) +// { +// cnt++; +// meanW += allW[i]; +// meanY += allY[i]; +// } +// meanW /= cnt; +// meanY /= cnt; +// maxH = max(down - meanY, meanY - up) * 2; +// maxH = max(maxH, src.rows / 3); +// std::vector groupsX; +// const int n = 3; +// int sumX = allX[0]; +// cnt = 1; +// for (int i = 1; i < boundingRects.size(); i++) { +// if (allX[i] - allX[i - 1] > n) +// { +// groupsX.push_back(sumX / cnt); +// sumX = 0; +// cnt = 0; +// } +// sumX += allX[i]; +// cnt++; +// } +// groupsX.push_back(sumX / cnt); +// +// std::vector processX = processArray(groupsX, meanW, meanW * 1.8); +// std::vector proteinX = checkArray(processX, src, 15, src.rows - 30, meanW); +// std::vector proteinRect(proteinX.size()); +// for (int i = 0; i < proteinX.size(); i++) +// { +// proteinRect[i].x = proteinX[i] - meanW / 2; +// +// proteinRect[i].y = 15;//meanY - maxH/2; +// proteinRect[i].width = meanW; +// proteinRect[i].height = src.rows - 30; +// } +// return proteinRect; +// } +// +// +// std::vector PBBiologyAlg::biologyAPI::getProteinBands(Mat src, std::vector lanes) +// { +// std::vector bands; +// if (src.type() != CV_16UC1) +// { +// std::cout << "The image is not 16-bit single-channel as expected." << std::endl; +// return bands; +// } +// int lanes_num = lanes.size(); +// if (lanes_num <= 0) +// { +// std::cout << "The lanes_num is 0." << std::endl; +// return bands; +// } +// bands.resize(lanes_num); +// +// for (int i = 0; i < lanes_num; i++) +// { +// bands[i] = get_protein_lane_data(src, lanes[i]); +// } +// //adjustBands(bands, 10); +// return bands; +// } +// +// +// void PBBiologyAlg::biologyAPI::adjustBands(std::vector& bands, int range) +// { +// // ڴ洢еֵӦ +// std::map columnMap; +// +// std::vector> vec; +// for (int i = 0; i < bands.size(); i++) +// { +// for (int j = 0; j < bands[i].band_point.size(); j++) +// { +// std::array bp = { bands[i].band_point[j][0],bands[i].band_point[j][1],bands[i].band_point[j][2],i }; +// vec.push_back(bp); +// } +// bands[i].band_point.clear(); +// } +// std::sort(vec.begin(), vec.end(), myCompare2); +// +// vector point; +// point.push_back(0); +// vector onep; +// onep.push_back(vec[0][3]); +// +// for (int i = 1; i < vec.size(); i++) +// { +// if (std::find(onep.begin(), onep.end(), vec[i][3]) != onep.end()) +// { +// point.push_back(i); +// onep.clear(); +// onep.push_back(vec[i][3]); +// } +// else +// { +// if (std::abs(vec[i][0] - vec[point.back()][0]) > range) +// { +// point.push_back(i); +// onep.clear(); +// onep.push_back(vec[i][3]); +// } +// } +// } +// +// for (int i = 0; i < bands.size(); i++) +// { +// bands[i].band_point.resize(point.size(), { -1,-1,-1 }); +// } +// +// int columnIndex = 1; +// point.push_back(-1); +// bands[vec[0][3]].band_point[0] = { vec[0][0],vec[0][1],vec[0][2] }; +// for (int i = 1; i < vec.size(); i++) +// { +// if (i != point[columnIndex]) +// { +// bands[vec[i][3]].band_point[columnIndex - 1] = { vec[i][0],vec[i][1],vec[i][2] }; +// } +// else +// { +// columnIndex++; +// bands[vec[i][3]].band_point[columnIndex - 1] = { vec[i][0],vec[i][1],vec[i][2] }; +// } +// } +// return; +// } +// +// void PBBiologyAlg::biologyAPI::molecularWeightResult(std::vector lanes, std::vector& bands) +// { +// for (int i = 0; i < bands.size(); i++) +// { +// int rNum = bands[i].band_point.size(); +// bands[i].Minfo.resize(rNum); +// +// unsigned long land_sum = lanes[i].width * std::accumulate(bands[i].ydata.begin(), bands[i].ydata.end(), 0UL); +// unsigned long band_sum = 0; +// for (int j = 0; j < rNum; j++) +// { +// std::array point = bands[i].band_point[j]; +// if (point[0] != -1) +// { +// bands[i].Minfo[j].molecular_weight = bands[i].xdata[point[0]]; +// bands[i].Minfo[j].band_content = 0; +// for (int s = point[1]; s < point[2]; s++) +// { +// bands[i].Minfo[j].band_content += bands[i].ydata[s] * lanes[i].width; +// } +// bands[i].Minfo[j].IOD = bands[i].Minfo[j].band_content; +// band_sum += bands[i].Minfo[j].band_content; +// bands[i].Minfo[j].maxOD = bands[i].ydata[point[0]]; +// } +// else +// { +// bands[i].Minfo[j].molecular_weight = -1; +// bands[i].Minfo[j].band_content = -1; +// bands[i].Minfo[j].IOD = -1; +// bands[i].Minfo[j].maxOD = -1; +// } +// } +// for (int j = 0; j < rNum; j++) +// { +// std::array point = bands[i].band_point[j]; +// if (point[0] != -1) +// { +// bands[i].Minfo[j].relative_content = 100.0 * bands[i].Minfo[j].band_content / band_sum; +// bands[i].Minfo[j].percentum = 100.0 * bands[i].Minfo[j].IOD / land_sum; +// +// if (bands[0].band_point[j][0] != -1) +// { +// bands[i].Minfo[j].match = 1; +// } +// else +// { +// bands[i].Minfo[j].match = -1; +// } +// } +// else +// { +// bands[i].Minfo[j].relative_content = -1; +// bands[i].Minfo[j].percentum = -1; +// +// if (bands[0].band_point[j][0] != -1) +// { +// bands[i].Minfo[j].match = 0; +// } +// else +// { +// bands[i].Minfo[j].match = -255; +// } +// } +// } +// } +// return; +// } +// +//} diff --git a/src/PBBiologyAlg/PBBiologyAlg.h b/src/PBBiologyAlg/PBBiologyAlg.h new file mode 100644 index 0000000..53f6b5e --- /dev/null +++ b/src/PBBiologyAlg/PBBiologyAlg.h @@ -0,0 +1,120 @@ + +namespace PBBiologyAlg +{ + public ref struct MolecularInfoVC + { + float molecular_weight; // 分子量 + int band_content; // 条带含量 + float relative_content; // 相对含量 + int IOD; // IOD + float maxOD; // 最大OD + float percentum; // 百分比 + int match; // 匹配 + }; + + public ref class MyClass + { + public: + MyClass(); + ~MyClass(); + + private: + + }; + + MyClass::MyClass() + { + } + + MyClass::~MyClass() + { + } +} + + + + +//#pragma once +// +//#include +//#include +//#include +//#include +//#include +//#include +// +//using namespace System; +//using namespace std; +//using namespace cv; +// +// +//typedef struct _molecular_info +//{ +// float molecular_weight; //分子量 +// int band_content; //条带含量 +// float relative_content; //相对含量 +// int IOD; //IOD +// float maxOD; //最大OD +// float percentum; //百分比 +// int match; //匹配 +//}MolecularInfo; +// +//typedef struct _band_info +//{ +// vector land_data; //泳道数据(16bit) +// std::vector ydata; //泳道波形y轴(0.0-255.0) +// std::vector xdata; //泳道波形x轴(0.0-1.0) +// vector> band_point; //条带位置(顶峰、左括号、右括号) +// vector Minfo; //对应条带的分子计算结果 +//}BandInfo; +// +// +//namespace PBBiologyAlg { +// public ref class biologyAPI +// { +// private: +// //泳道过滤处理函数 +// //根据输入所有类似泳道的中心X轴坐标(groupsX),以及泳道的最小最大距离(minDifference/maxDifference),过滤掉不合规的泳道 +// std::vector processArray(std::vector& groupsX, int minDifference, int maxDifference); +// +// //宽度流计算函数,用来计算检测泳道宽度流 +// vector get_bar_num(vector buf); +// +// //泳道检测补全函数 +// //根据泳道位置(processX)和泳道间距离(meanW),从图像(src)中检测临近类泳道位置是否符合泳道特性(泳道内两条像素的宽度流应类似且存在条带) +// std::vector checkArray(std::vector& processX, Mat src, int start_y, int end_y, int meanW); +// +// //条带信息计算函数,输入8bit数组(rbuf)以及过滤范围(range)(此范围内仅保留一个分子) +// vector> get_top_point(vector rbuf, int range); +// +// //单个泳道中条带信息计算(条带位置等) +// BandInfo get_protein_lane_data(Mat src, Rect lane); +// +// public: +// biologyAPI(); +// ~biologyAPI(); +// +// //函数:获得图像中泳道位置 +// //src:输入图像,需是8bit单通道图像 +// //返回值:泳道矩形位置信息 +// std::vector getProteinRect(Mat src); +// +// //函数:获得图像中泳道对应的条带信息 +// //src:输入图像,需是16bit单通道图像 +// //lanes:泳道矩形位置信息 +// //返回值:对应条带位置信息 +// std::vector getProteinBands(Mat src, std::vector lanes); +// +// //函数:条带分子匹配排序函数 +// //bands:所有条带位置信息 +// //range:Y轴差在range范围内的表示和泳道1匹配 +// //返回值:结果修改在bands中 +// void adjustBands(std::vector& bands, int range); +// +// +// //函数:计算所有条带的分子信息 +// //lanes:输入泳道信息 +// //bands:输入条带信息,对应输出的分子信息在这个结构体中 +// void molecularWeightResult(std::vector lanes, std::vector& bands); +// }; +//} diff --git a/src/PBBiologyAlg/PBBiologyAlg.vcxproj b/src/PBBiologyAlg/PBBiologyAlg.vcxproj new file mode 100644 index 0000000..7a230fc --- /dev/null +++ b/src/PBBiologyAlg/PBBiologyAlg.vcxproj @@ -0,0 +1,156 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {110F52DB-2FD8-4C0A-BC29-A375AF36F9C5} + v4.8 + ManagedCProj + PBBiologyAlg + 10.0 + + + + DynamicLibrary + true + v143 + true + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + true + MultiByte + + + DynamicLibrary + false + v143 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + ..\..\src\PBBiology\include;..\..\libs\opencv\include;..\..\libs\opencv\include\opencv2;$(IncludePath) + ..\..\libs\opencv\lib;$(LibraryPath) + + + ..\..\libs\opencv\include;..\..\libs\opencv\include\opencv2;..\..\src\PBBiology\include;$(IncludePath) + ..\..\libs\opencv\lib;$(LibraryPath) + + + + NotUsing + pch.h + Level3 + _DEBUG;%(PreprocessorDefinitions) + + + opencv_world455.lib;%(AdditionalDependencies) + + + + + NotUsing + pch.h + Level3 + WIN32;_DEBUG;%(PreprocessorDefinitions) + + + + + + + + NotUsing + pch.h + Level3 + WIN32;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + NotUsing + pch.h + Level3 + NDEBUG;%(PreprocessorDefinitions) + true + + + opencv_world455.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + {bfe19323-8588-402d-8a9a-86e39c08eb43} + + + + + + \ No newline at end of file diff --git a/src/PBBiologyAlg/PBBiologyAlg.vcxproj.filters b/src/PBBiologyAlg/PBBiologyAlg.vcxproj.filters new file mode 100644 index 0000000..145df0d --- /dev/null +++ b/src/PBBiologyAlg/PBBiologyAlg.vcxproj.filters @@ -0,0 +1,43 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + + + 资源文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/src/PBBiologyAlg/Resource.h b/src/PBBiologyAlg/Resource.h new file mode 100644 index 0000000..c4dffa9 --- /dev/null +++ b/src/PBBiologyAlg/Resource.h @@ -0,0 +1,3 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ 生成的包含文件。 +// 使用者 app.rc diff --git a/src/PBBiologyAlg/app.ico b/src/PBBiologyAlg/app.ico new file mode 100644 index 0000000..789d7cc Binary files /dev/null and b/src/PBBiologyAlg/app.ico differ diff --git a/src/PBBiologyAlg/app.rc b/src/PBBiologyAlg/app.rc new file mode 100644 index 0000000..9e5c3d7 Binary files /dev/null and b/src/PBBiologyAlg/app.rc differ diff --git a/src/PBBiologyVC/AssemblyInfo.cpp b/src/PBBiologyVC/AssemblyInfo.cpp new file mode 100644 index 0000000..7735bc9 --- /dev/null +++ b/src/PBBiologyVC/AssemblyInfo.cpp @@ -0,0 +1,20 @@ +#include "pch.h" + +using namespace System; +using namespace System::Reflection; +using namespace System::Runtime::CompilerServices; +using namespace System::Runtime::InteropServices; +using namespace System::Security::Permissions; + +[assembly:AssemblyTitleAttribute(L"PBBiologyVC")]; +[assembly:AssemblyDescriptionAttribute(L"")]; +[assembly:AssemblyConfigurationAttribute(L"")]; +[assembly:AssemblyCompanyAttribute(L"")]; +[assembly:AssemblyProductAttribute(L"PBBiologyVC")]; +[assembly:AssemblyCopyrightAttribute(L"版权所有(c) 2024")]; +[assembly:AssemblyTrademarkAttribute(L"")]; +[assembly:AssemblyCultureAttribute(L"")]; + +[assembly:AssemblyVersionAttribute(L"1.0.*")]; + +[assembly:ComVisible(false)]; diff --git a/src/PBBiologyVC/PBBiologyVC.cpp b/src/PBBiologyVC/PBBiologyVC.cpp new file mode 100644 index 0000000..c4218c4 --- /dev/null +++ b/src/PBBiologyVC/PBBiologyVC.cpp @@ -0,0 +1,252 @@ +#include "pch.h" +#include "PBBiologyVC.h" +#include +#include + + +void printMatData(const cv::Mat& mat) +{ + Console::WriteLine("First few pixels:"); + for (int i = 0; i < std::min(10, mat.rows); ++i) + { + for (int j = 0; j < std::min(10, mat.cols); ++j) + { + if (mat.type() == CV_8UC1) { + // 8λͨͼ + Console::Write("{0} ", mat.at(i, j)); + } + else if (mat.type() == CV_16UC1) { + // 16λͨͼ + Console::Write("{0} ", mat.at(i, j)); + } + } + Console::WriteLine(); + } +} +void showNormalizedImage(const cv::Mat& src) +{ + // ͼǷΪ16λͨ + if (src.type() == CV_16UC1) + { + // һµĿMatڴתͼ + cv::Mat normalizedImg; + + // 16λͼһ8λΧ + double min, max; + cv::minMaxLoc(src, &min, &max); // ͼСֵ + src.convertTo(normalizedImg, CV_8U, 255.0 / (max - min), -min * 255.0 / (max - min)); + + // ʾͼ + cv::imshow("Normalized src", normalizedImg); + cv::waitKey(0); // ȴ + } + else + { + // 16λֱͨʾ + cv::imshow("src", src); + cv::waitKey(0); + } +} +namespace PBBiologyVC +{ + + PBBiology::~PBBiology() + { + + } + + + + List^ PBBiology::getProteinRectVC(System::Byte* mat, unsigned short width, unsigned short height) + { + /* for (size_t i = 0; i < width*height; i++) + { + std::cout << mat[i] ; + } + std::cout << std::endl;*/ + + cv::Mat src(height, width, CV_8UC1,mat); + cv::Mat edges; + cv::Canny(src, edges, 50, 150); + std::vector rects = pblane->getProteinRect(src); + + List^ results = gcnew List(); + for (const auto& rect : rects) { + results->Add(gcnew RectVC(rect.x, rect.y, rect.width, rect.height)); + } + + return results; + } + void PBBiology::getProteinBandsVC(System::Byte* mat, int bit, unsigned short width, unsigned short height, List^ lanes, List<_band_info^>^% band) + { + cv::Mat src; + if (bit == 8) + { + src = cv::Mat(height, width, CV_8UC1, mat); + } + else if (bit == 16) + { + src = cv::Mat(height, width, CV_16UC1, mat); + } + + std::vector rects(lanes->Count); + + for (size_t i = 0; i < lanes->Count; i++) + { + RectVC^ laneRect = lanes[i]; + rects[i] = cv::Rect(laneRect->X, laneRect->Y, laneRect->Width, laneRect->Height); + } + + std::vector bandinfo = pblane->getProteinBands(src, rects); + + + band_InfoTo_band_info(bandinfo,band); + + } + + List<_band_info^>^ PBBiology::adjustBands(List<_band_info^>^ bands, int range) + { + std::vector bandinfo(bands->Count); + + _band_infoToBand_Info(bandinfo,bands); + + pblane->adjustBands(bandinfo, range); + band_InfoTo_band_info(bandinfo,bands); + return bands; + } + + void PBBiology::molecularWeightResult(List^% lanes, List<_band_info^>^% bands) + { + std::vector rects(lanes->Count); + + for (size_t i = 0; i < lanes->Count; i++) + { + RectVC^ laneRect = lanes[i]; + rects[i] = cv::Rect(laneRect->X, laneRect->Y, laneRect->Width, laneRect->Height); + } + + std::vector bandinfo(bands->Count); + _band_infoToBand_Info(bandinfo,bands); + band_InfoTo_band_info(bandinfo,bands); + + pblane->molecularWeightResult(rects, bandinfo); + /* for (int i = 0; i < bandinfo.size(); i++) + { + std::cout << bandinfo[i].Minfo.size() << std::endl; + for (int j = 0; j < bandinfo[i].Minfo.size(); j++) + { + std::cout << bandinfo[i].Minfo[j].band_content; + } + std::cout << std::endl; + }*/ + band_InfoTo_band_info(bandinfo, bands); + } + + void PBBiology::_band_infoToBand_Info(std::vector& bandinfo, List<_band_info^>^ bands) + { + + for (size_t i = 0; i < bands->Count; i++) + { + BandInfo _bandinfo; + + for each (unsigned short land in bands[i]->land_data) + { + _bandinfo.land_data.push_back(land); + } + + + for each (float y in bands[i]->ydata) + { + _bandinfo.ydata.push_back(y); + } + + + for each (float x in bands[i]->xdata) + { + _bandinfo.xdata.push_back(x); + } + + for each (List ^ points in bands[i]->band_point) + { + if (points->Count == 3) + { + std::array pointArray = { points[0], points[1], points[2] }; + _bandinfo.band_point.push_back(pointArray); + } + } + _bandinfo.Minfo.resize(bands[i]->Minfo->Count); + for (int j = 0; j < bands[i]->Minfo->Count; j++) + { + MolecularInfo molecularInfo; + + molecularInfo.band_content = bands[i]->Minfo[j]->band_content; + molecularInfo.IOD = bands[i]->Minfo[j]->IOD; + molecularInfo.match = bands[i]->Minfo[j]->match; + molecularInfo.maxOD = bands[i]->Minfo[j]->maxOD; + molecularInfo.molecular_weight = bands[i]->Minfo[j]->molecular_weight; + molecularInfo.percentum = bands[i]->Minfo[j]->percentum; + molecularInfo.relative_content = bands[i]->Minfo[j]->relative_content; + _bandinfo.Minfo[i] = molecularInfo; + + } + + + bandinfo[i] = _bandinfo; + } + } + + void PBBiology::band_InfoTo_band_info(std::vector src, List<_band_info^>^% results) + { + /* for (int i = 0; i < src.size(); i++) + { + + for (int j = 0; j < src[i].Minfo.size(); j++) + { + std::cout << src[i].Minfo[j].band_content; + } + std::cout << std::endl; + }*/ + results->Clear(); + for (const auto& rect : src) { + _band_info^ info = gcnew _band_info(); + for (const auto& land : rect.land_data) { + info->land_data->Add(land); + } + for (const auto& y : rect.ydata) { + info->ydata->Add(y); + } + + for (const auto& x : rect.xdata) { + info->xdata->Add(x); + } + + for (const auto& point : rect.band_point) { + + List^ points = gcnew List(); + points->Add(point[0]); // + points->Add(point[1]); // + points->Add(point[2]); // + info->band_point->Add(points); + } + std::cout << rect.Minfo.size()<< std::endl; + info->Minfo = gcnew List(); + for (int i = 0; i < rect.Minfo.size(); ++i) { + MolecularInfoVC^ minfo = gcnew MolecularInfoVC(); + + minfo->band_content = rect.Minfo[i].band_content; + minfo->IOD = rect.Minfo[i].IOD; + minfo->match = rect.Minfo[i].match; + minfo->maxOD = rect.Minfo[i].maxOD; + minfo->molecular_weight = rect.Minfo[i].molecular_weight; + minfo->percentum = rect.Minfo[i].percentum; + minfo->relative_content = rect.Minfo[i].relative_content; + info->Minfo->Add( minfo); + } + + results->Add(info); + } + + } + +} + diff --git a/src/PBBiologyVC/PBBiologyVC.h b/src/PBBiologyVC/PBBiologyVC.h new file mode 100644 index 0000000..d24c49f --- /dev/null +++ b/src/PBBiologyVC/PBBiologyVC.h @@ -0,0 +1,69 @@ +#pragma once +#include "PBLane.h" +using namespace System; +using namespace System::Collections::Generic; + +namespace PBBiologyVC { + + public ref struct RectVC + { + public: + int X; + int Y; + int Width; + int Height; + + RectVC(int x, int y, int width, int height) + : X(x), Y(y), Width(width), Height(height) {} + }; + + public ref struct MolecularInfoVC + { + float molecular_weight; // 分子量 + int band_content; // 条带含量 + float relative_content; // 相对含量 + int IOD; // IOD + float maxOD; // 最大OD + float percentum; // 百分比 + int match; // 匹配 + }; + + + public ref struct _band_info + { + List^ land_data; //泳道数据(16bit) + List^ ydata; //泳道波形y轴(0.0-255.0) + List^ xdata; //泳道波形x轴(0.0-1.0) + List^>^ band_point; //条带位置(顶峰、左括号、右括号) + List^ Minfo; //对应条带的分子计算结果 + + _band_info() + { + land_data = gcnew List(); + ydata = gcnew List(); + xdata = gcnew List(); + band_point = gcnew List^>(3); + Minfo = gcnew List(1); + + + } + }; + + + public ref class PBBiology + { + + ~PBBiology(); + + public: + List^ getProteinRectVC(System::Byte* mat,unsigned short width,unsigned short height); + void getProteinBandsVC(System::Byte* mat,int bit, unsigned short width, unsigned short height, List^ lanes, List<_band_info^>^% band); + List<_band_info^>^ adjustBands(List<_band_info^>^ bands, int range); + void molecularWeightResult(List^% lanes, List<_band_info^>^% bands); + private: + PBLane* pblane; + void _band_infoToBand_Info(std::vector& dst, List<_band_info^>^ src); + void band_InfoTo_band_info(std::vector src, List<_band_info^>^% results); + }; +} + diff --git a/src/PBBiologyVC/PBBiologyVC.vcxproj b/src/PBBiologyVC/PBBiologyVC.vcxproj new file mode 100644 index 0000000..f462ab3 --- /dev/null +++ b/src/PBBiologyVC/PBBiologyVC.vcxproj @@ -0,0 +1,161 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {C1DD8A06-7351-4C8D-BD7F-B2BE76BB3903} + v4.8 + ManagedCProj + PBBiologyVC + 10.0 + + + + DynamicLibrary + true + v143 + true + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + true + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + ..\..\libs\opencv\include\opencv2;..\..\libs\opencv\include;..\PBBiology\include;$(IncludePath) + ..\x64\Debug;..\..\libs\opencv\lib;$(LibraryPath) + + + ..\PBBiology\include;..\..\libs\opencv\include;..\..\libs\opencv\include\opencv2;$(IncludePath) + ..\x64\Release;..\..\libs\opencv\lib;$(LibraryPath) + + + + Use + pch.h + Level3 + _DEBUG;%(PreprocessorDefinitions) + + + opencv_world455d.lib;PBBiology.lib;%(AdditionalDependencies) + + + + + Use + pch.h + Level3 + WIN32;_DEBUG;%(PreprocessorDefinitions) + + + + + + + + Use + pch.h + Level3 + WIN32;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + Use + pch.h + Level3 + NDEBUG;%(PreprocessorDefinitions) + + + opencv_world455.lib;PBBiology.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/PBBiologyVC/PBBiologyVC.vcxproj.filters b/src/PBBiologyVC/PBBiologyVC.vcxproj.filters new file mode 100644 index 0000000..fd9e328 --- /dev/null +++ b/src/PBBiologyVC/PBBiologyVC.vcxproj.filters @@ -0,0 +1,61 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 资源文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/src/PBBiologyVC/PBColonyVC.cpp b/src/PBBiologyVC/PBColonyVC.cpp new file mode 100644 index 0000000..bef0305 --- /dev/null +++ b/src/PBBiologyVC/PBColonyVC.cpp @@ -0,0 +1,46 @@ +#include "pch.h" +//#include "PBColonyVC.h" +//#include +//#include +//#include "PBColony.h" +// +// +// +//namespace PBBiologyVC +//{ +// +// PBColonyVC::~PBColonyVC() +// { +// +// } +// +// void PBColonyVC::run(System::Byte* mat, unsigned short width, unsigned short height) +// { +// +// /*for (size_t i = 0; i < width * height; i++) +// { +// std::cout << mat[i]; +// } +// std::cout << std::endl; +// +// cv::Mat src(height, width, CV_8UC1, mat); +// Mat input_cn3; +// cv::Point2f center; +// float radius; +// int ret = pbcolony->colony_get_circle(src,center,radius); +// if (ret) +// { +// Mat mask = pbcolony->generateMaskImage(src.cols, src.rows, center.x - radius, center.y - radius, 2 * radius, 2 * radius); +// int lower = -1; +// int upper = -1; +// Mat bin = pbcolony->get_lower_upper(src, mask, lower, upper); +// +// ClassifyStandard class_stand; +// pbcolony->init_classify_standard(class_stand); +// vector Cinfo = pbcolony->get_colony_info(src, bin, input_cn3, class_stand, pbcolony->image_inverted_flag); +// ColonyStatistic CStatistic = pbcolony->get_colony_statistics(Cinfo); +// +// +// }*/ +// } +//} \ No newline at end of file diff --git a/src/PBBiologyVC/PBColonyVC.h b/src/PBBiologyVC/PBColonyVC.h new file mode 100644 index 0000000..3e7839c --- /dev/null +++ b/src/PBBiologyVC/PBColonyVC.h @@ -0,0 +1,20 @@ +//#pragma once +//#include "PBLane.h" +//using namespace System; +//using namespace System::Collections::Generic; +// +//namespace PBBiologyVC { +// +// +// public ref class PBColonyVC +// { +// +// ~PBColonyVC(); +// +// public: +// void run(System::Byte* mat, unsigned short width, unsigned short height); +// private: +// +// }; +//} +// diff --git a/src/PBBiologyVC/PBImageProcessVC.cpp b/src/PBBiologyVC/PBImageProcessVC.cpp new file mode 100644 index 0000000..1d57b90 --- /dev/null +++ b/src/PBBiologyVC/PBImageProcessVC.cpp @@ -0,0 +1,299 @@ +#include "pch.h" +#include "PBImageProcessVC.h" +#include "PBImageProcess.h" + + +PBBiologyVC::PBImageProcessVC::~PBImageProcessVC() +{ + throw gcnew System::NotImplementedException(); +} + +int PBBiologyVC::PBImageProcessVC::render_process(System::Byte* pseImage, System::Byte* markImage, System::Byte* renderpseImage, System::Byte* mergepseImage, System::Byte* colorBarImage, int colorIndex, unsigned short colorbarW, unsigned short colorbarH, int bit, unsigned short width, unsigned short height, float sec, float max, float min, int scientific_flag, bool reverse, unsigned short colorbarWW, unsigned short h_onecolor, int brightness_offset, double contrast_factor, double opacity_factor) +{ + cv::Mat cvPseImage(height, width, CV_16UC1, pseImage); + cv::Mat cvmarkImage(height, width, CV_16UC1, markImage); + cv::Mat cvRenderpseImage(height, width, CV_8UC3, renderpseImage); + + + + uint8_t bgr_tab[256][3] = { 0 }; + + ColorTable colortype = ColorTable(colorIndex); //ǰɫ + + get_bgr_tab(colortype, bgr_tab, false); + pseudo_color_processing(cvPseImage, cvRenderpseImage, max, min, bgr_tab); // α õαͼ + + Mat r = render_mask_image(cvmarkImage, cvRenderpseImage, brightness_offset, contrast_factor, opacity_factor); + int byteCount = r.rows * r.cols * r.channels(); + cvtColor(r, r, COLOR_BGR2RGB); + std::memcpy(mergepseImage, r.data, byteCount); + cvtColor(cvRenderpseImage, cvRenderpseImage, COLOR_BGR2RGB); + + + Mat bgr_tab_img = bgr_tab_image(colorbarWW, h_onecolor, bgr_tab); + // std::cout << "w = " << bgr_tab_img.cols << "c= " << bgr_tab_img.rows << "c = " << bgr_tab_img.channels() << std::endl; + Mat bgr_scale_img = bgr_scale_image(bgr_tab_img, max, min,scientific_flag); //õͼ + //std::cout << "w = " << bgr_scale_img.cols << "c= " << bgr_scale_img.rows<<"c = "<(_y, _x) = 255; + } + } + ////// ʾͼ + /*cv::imshow("Processed Image", mask); + cv::waitKey(0);*/ + + // 6. ȡαϢ + PseudoInfo pinfo = get_pseudo_info(image, mask, max, min); + + // 7. Pseudo_infoVC + PBBiologyVC::Pseudo_infoVC^ ppinfovc = gcnew PBBiologyVC::Pseudo_infoVC( + pinfo.maxOD, pinfo.minOD, pinfo.IOD, pinfo.count, pinfo.AOD); + return ppinfovc; +} + +PBBiologyVC::Pseudo_infoVC^ PBBiologyVC::PBImageProcessVC::get_pseudo_info_circle_vc(System::Byte* mat, int bit, unsigned short width, unsigned short height, float max, float min, int x, int y, int r) +{ + // 1. ԭʼתΪ OpenCV Mat ʽ + cv::Mat image(height, width, CV_16UC1, mat); // 16-bit ͨͼ + + cv::Mat mask = cv::Mat::zeros(image.size(), CV_8UC1); + + cv::circle(mask, cv::Point(x, y), r, cv::Scalar(255), cv::FILLED); + ////// ʾͼ + /*cv::imshow("Processed Image", mask); + cv::waitKey(0);*/ + + // 6. ȡαϢ + PseudoInfo pinfo = get_pseudo_info(image, mask, max, min); + + // 7. Pseudo_infoVC + PBBiologyVC::Pseudo_infoVC^ ppinfovc = gcnew PBBiologyVC::Pseudo_infoVC( + pinfo.maxOD, pinfo.minOD, pinfo.IOD, pinfo.count, pinfo.AOD); + return ppinfovc; +} + +PBBiologyVC::Pseudo_infoVC^ PBBiologyVC::PBImageProcessVC::get_pseudo_info_polygon_vc(System::Byte* mat, int bit, unsigned short width, unsigned short height, float max, float min, List^ list_point) +{ + // 1. ԭʼתΪ OpenCV Mat ʽ + cv::Mat image(height, width, CV_16UC1, mat); // 16-bit ͨͼ + + cv::Mat mask = cv::Mat::zeros(image.size(), CV_8UC1); + + std::vector points; + for each (auto var in list_point) + { + cv::Point t(var->x, var->y); + points.push_back(t); + } + const cv::Point* ppt[1] = { points.data() }; + int npt[] = { static_cast(points.size()) }; + + // ʹcv::fillPolyƲ + cv::fillPoly(mask, ppt, npt, 1, cv::Scalar(255), 8); + + ////// ʾͼ + /*cv::imshow("Processed Image", mask); + cv::waitKey(0);*/ + + // 6. ȡαϢ + PseudoInfo pinfo = get_pseudo_info(image, mask, max, min); + + // 7. Pseudo_infoVC + PBBiologyVC::Pseudo_infoVC^ ppinfovc = gcnew PBBiologyVC::Pseudo_infoVC( + pinfo.maxOD, pinfo.minOD, pinfo.IOD, pinfo.count, pinfo.AOD); + return ppinfovc; +} + +PBBiologyVC::Pseudo_infoVC^ PBBiologyVC::PBImageProcessVC::get_pseudo_info_wand_vc(System::Byte* mat, System::Byte* dst, int bit, unsigned short width, unsigned short height, float max, float min, int x, int y, int th) +{ + cv::Mat image(height, width, CV_16UC1, mat); + cv::Mat mask = get_magic_wand_image(image, x, y, 10); + PseudoInfo pinfo = get_pseudo_info(image, mask, max, min); + + + PBBiologyVC::Pseudo_infoVC^ ppinfovc = gcnew PBBiologyVC::Pseudo_infoVC( + pinfo.maxOD, pinfo.minOD, pinfo.IOD, pinfo.count, pinfo.AOD); + + // ʹCannyԵ + cv::Mat edges; + cv::Canny(mask, edges, 100, 200); + std::vector> contours; + std::vector hierarchy; + cv::findContours(edges, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); + + // ҵ + int max_contour_index = -1; + double max_contour_area = 0.0; + for (int i = 0; i < contours.size(); i++) { + double area = cv::contourArea(contours[i]); + if (area > max_contour_area) { + max_contour_area = area; + max_contour_index = i; + } + } + + // һɫ + cv::Mat output = cv::Mat::zeros(image.size(), CV_8UC3); + + // ҵںɫ + if (max_contour_index != -1) { + cv::drawContours(output, contours, max_contour_index, cv::Scalar(255, 255, 255), 2); // ɫ߿Ϊ2 + } + + imshow("a", output); + waitKey(0); + return ppinfovc; +} + +//int PBBiologyVC::PBImageProcessVC::render_mask_image_vc(System::Byte* mat, int bit, unsigned short width, unsigned short height, System::Byte* mark, System::Byte* dst, float max, float min, bool reverse) +//{ +// +// /* if (bit != 16) +// { +// return -1; +// } +// cv::Mat src(height, width, CV_16UC1, mat); +// cv::Mat cvMart(height, width, CV_16UC1, mark); +// cv::Mat cvdst(height, width, CV_8UC3, dst); +// int ret = render_mask_image(cvMart, src , cvdst, max, min, ColorTable::YellowHot, reverse); +// if (ret == -1) return -1;*/ +// return 0; +// +//} + +//int PBBiologyVC::PBImageProcessVC::blendImages_vc(System::Byte* mat, int bit, unsigned short width, unsigned short height, System::Byte* mark, System::Byte* dst, float alpha) +//{ +// /* if (bit != 16) +// { +// return -1; +// } +// cv::Mat src(height, width, CV_16UC1, mat); +// cv::Mat cvMart(height, width, CV_8UC3, mark); +// cv::Mat cvdstrgb(height, width, CV_8UC3, dst); +// +// int ret = blendImages(src, cvMart, cvdstrgb,alpha); +// if (ret == 0) return -1; +// */ +// return 0; +// +//} + +//int PBBiologyVC::PBImageProcessVC::render_image_16_vc(System::Byte* mat, unsigned short width, unsigned short height, System::Byte* dst, +// int colorIndex,float max, float min, bool reverse, System::Byte* colobar,unsigned short colorbar_width, unsigned short colorbar_height, +// int h_onecolor) +//{ +// // 16λͨͼ +// cv::Mat src(height, width, CV_16UC1, mat); +// // 8λ3ͨͼ +// cv::Mat cvdst(height, width, CV_8UC3, dst); +// +// uint8_t bgr_tab[256][3] = { 0 }; +// +// ColorTable colortype = ColorTable(colorIndex); +// +// get_bgr_tab(colortype, bgr_tab, false); +// if(colortype != Gray) +// pseudo_color_processing(src, cvdst, max, min, bgr_tab); // α õαͼ +// Mat bgr_tab_img = bgr_tab_image(colorbar_width, h_onecolor, bgr_tab); +// Mat bgr_scale_img = bgr_scale_image(bgr_tab_img, max, min); +// /*imshow("a", bgr_scale_img); +// waitKey(0);*/ +// +// return 0; +//} + +//PBBiologyVC::Pseudo_infoVC^ PBBiologyVC::PBImageProcessVC::get_pseudo_info_vc(System::Byte* mat, int bit, unsigned short width, unsigned short height, int x, int y, int w, int h, float max, float min) +//{ +// cv::Mat src(height, width, CV_16UC1, mat); +// PseudoInfo pinfo = get_pseudo_info(src, x, y, w, h, max, min); +// PBBiologyVC::Pseudo_infoVC^ ppinfovc = gcnew PBBiologyVC::Pseudo_infoVC(pinfo.maxOD, pinfo.minOD, pinfo.IOD, pinfo.count, pinfo.AOD); +// return ppinfovc; +//} +// +//int PBBiologyVC::PBImageProcessVC::render_process(System::Byte* pseImage, System::Byte* markImage, System::Byte* renderpseImage, System::Byte* mergepseImage, +// System::Byte* colorBarImage, int colorIndex, unsigned short colorbarW, unsigned short colorbarH, +// int bit, unsigned short width, unsigned short height, float max, float min, bool reverse, +// unsigned short colorbarWW, unsigned short h_onecolor, int brightness_offset, double contrast_factor, double opacity_factor) +//{ +// +// cv::Mat cvPseImage(height, width, CV_16UC1, pseImage); +// cv::Mat cvmarkImage(height, width, CV_16UC1, markImage); +// cv::Mat cvRenderpseImage(height, width, CV_8UC3, renderpseImage); +// +// +// +// uint8_t bgr_tab[256][3] = { 0 }; +// +// ColorTable colortype = ColorTable(colorIndex); //ǰɫ +// +// get_bgr_tab(colortype, bgr_tab, false); +// if (colortype != Gray) +// { +// pseudo_color_processing(cvPseImage, cvRenderpseImage, max, min, bgr_tab); // α õαͼ +// +// Mat r = render_mask_image(cvmarkImage, cvRenderpseImage, brightness_offset, contrast_factor, opacity_factor); +// int byteCount = r.rows * r.cols * r.channels(); +// cvtColor(r, r, COLOR_BGR2RGB); +// std::memcpy(mergepseImage, r.data, byteCount); +// cvtColor(cvRenderpseImage, cvRenderpseImage, COLOR_BGR2RGB); +// /*imshow("a", cvRenderpseImage); +// waitKey(1);*/ +// } +// else +// { +// +// } +// +// +// Mat bgr_tab_img = bgr_tab_image(colorbarWW, h_onecolor, bgr_tab); +// // std::cout << "w = " << bgr_tab_img.cols << "c= " << bgr_tab_img.rows << "c = " << bgr_tab_img.channels() << std::endl; +// Mat bgr_scale_img = bgr_scale_image(bgr_tab_img, max, min); //õͼ +// //std::cout << "w = " << bgr_scale_img.cols << "c= " << bgr_scale_img.rows<<"c = "<