1- using AForge ; // IntPoint
1+ /*
2+ * =====================================================================================
3+ * _______ _______ _______ _______ _______ _______ _______ _______
4+ * | | | | | | | | | | | | | | | |
5+ * | _ | | _ | | _ | | _ | | _ | | _ | | _ | | _ |
6+ * | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
7+ * | |_| | | |_| | | |_| | | |_| | | |_| | | |_| | | |_| | | |_| |
8+ * | | | | | | | | | | | | | | | |
9+ * |_______| |_______| |_______| |_______| |_______| |_______| |_______| |_______|
10+ *
11+ * C# 之父:Anders Hejlsberg 保佑符文阵
12+ * (丹麦剑客の代码圣剑已出鞘)
13+ *
14+ * .'''. __...__ .'''.
15+ * ' .-'``-..'' ``-..-' `
16+ * / .'. .'. \
17+ * / / \ \ \ / / \ \
18+ * | | \ '. `. .' .' | |
19+ * | | \ '. `' .' .' | |
20+ * | | \ '.' .' | |
21+ * | | \ .'.' | |
22+ * | | \ / \ | |
23+ * \ \ \ / \ / /
24+ * \ '-. '-' '. .- /
25+ * '. ``''-. .''-'' .'
26+ * '-..__ `````''''' __..-'
27+ * ````-...-''''
28+ *
29+ * 符文真言:#️⃣🔥 C#之父赐我类型安全 🔥#️⃣
30+ * 愿编译器如明镜,运行时无惊惶
31+ * 所有指针皆安全,所有异常早预防
32+ * 内存永不泄漏,线程永不争抢
33+ * 十年代码如新铸,永无BUG镇八方!
34+ *
35+ * LINQ查询如流水,数据操作似神仙
36+ * 异步等待无挂碍,多线程中定如山
37+ * 模式匹配断真假,空值安全避深渊
38+ * 属性封装护数据,对象设计有章循
39+ *
40+ * 垃圾回收自动清,资源管理自闭环
41+ * 接口抽象定规范,继承多态展神通
42+ * 单元测试全覆盖,发布上线心不慌
43+ * 框架更新随主升,技术永不过时新
44+ *
45+ * 代码整洁如诗画,注释清晰胜经文
46+ * 需求变更随风去,架构稳定万年青
47+ * 调试轻松无烦恼,日志清晰查问题
48+ * 绩效评估A+满,升职加薪步步高
49+ *
50+ * 愿智能感知常相伴,代码补全如神助
51+ * 愿NuGet包永稳定,依赖冲突不复存
52+ * 愿Git提交无冲突,版本历史如明镜
53+ * 愿需求文档写得清,产品经理是神仙
54+ *
55+ * C#之父显圣光,扫尽人间所有BUG
56+ * 代码如剑斩混沌,架构如塔镇乾坤
57+ * 从此无有崩溃事,唯有成功报佳音
58+ * 今以符文镇此卷,万年代码永安宁!
59+ *
60+ * =====================================================================================
61+ */
62+ using AForge ;
263using AForge . Imaging . Filters ;
364using Newtonsoft . Json ;
465using ShowWrite . Models ;
2990
3091namespace ShowWrite
3192{
32- // 配置模型:保存摄像头索引与透视校正
93+ // 更新后的配置模型
3394 public class AppConfig
3495 {
3596 public int CameraIndex { get ; set ; } = 0 ;
3697 public List < IntPoint > ? CorrectionPoints { get ; set ; } // AForge.IntPoint(长度=4)
3798 public int SourceWidth { get ; set ; }
3899 public int SourceHeight { get ; set ; }
100+
101+ // 新增设置项
102+ public bool StartMaximized { get ; set ; } = true ;
103+ public bool AutoStartCamera { get ; set ; } = true ;
104+ public double DefaultPenWidth { get ; set ; } = 2.0 ;
105+ public string DefaultPenColor { get ; set ; } = "#FF0000FF" ; // 蓝色
106+ public bool EnableHardwareAcceleration { get ; set ; } = true ;
107+
108+ // 添加缺少的属性
109+ public bool EnableFrameProcessing { get ; set ; } = true ; // 新增
110+ public int FrameRateLimit { get ; set ; } = 2 ; // 默认选择25 FPS
39111 }
40112
41113 public partial class MainWindow : Window
@@ -49,6 +121,9 @@ public partial class MainWindow : Window
49121 // 透视校正过滤器
50122 private QuadrilateralTransformation ? _perspectiveCorrectionFilter ;
51123
124+ // 配置对象
125+ private AppConfig config = new AppConfig ( ) ;
126+
52127 private enum ToolMode { None , Move , Pen , Eraser }
53128 private ToolMode _currentMode = ToolMode . None ;
54129
@@ -88,8 +163,17 @@ public MainWindow()
88163 InitializeComponent ( ) ;
89164 PhotoList . ItemsSource = _photos ;
90165
166+ // 加载配置(包含新增的设置项)
167+ LoadConfig ( ) ;
168+
169+ // 应用窗口设置
91170 WindowStyle = WindowStyle . None ;
92- WindowState = WindowState . Maximized ;
171+ WindowState = config . StartMaximized ? WindowState . Maximized : WindowState . Normal ;
172+
173+ // 应用画笔设置
174+ var penColor = ( System . Windows . Media . Color ) System . Windows . Media . ColorConverter . ConvertFromString ( config . DefaultPenColor ) ;
175+ Ink . DefaultDrawingAttributes . Color = penColor ;
176+ userPenWidth = config . DefaultPenWidth ;
93177
94178 // —— 捕捉画笔/橡皮事件 —— //
95179 Ink . StrokeCollected += Ink_StrokeCollected ; // 画笔:落笔->抬笔后收集(一次性)
@@ -118,10 +202,8 @@ public MainWindow()
118202 } ) ;
119203 } ;
120204
121- // 先加载配置(摄像头索引 + 透视校正)
122- LoadConfig ( ) ;
123-
124- if ( ! _videoService . Start ( currentCameraIndex ) )
205+ // 如果配置为自动启动摄像头,则尝试启动
206+ if ( config . AutoStartCamera && ! _videoService . Start ( currentCameraIndex ) )
125207 {
126208 MessageBox . Show ( "未找到可用摄像头。" , "错误" , MessageBoxButton . OK , MessageBoxImage . Error ) ;
127209 }
@@ -525,16 +607,16 @@ private void VideoArea_MouseDoubleClick(object sender, MouseButtonEventArgs e)//
525607 // 更“努力”的识别 + 常见格式
526608 var reader = new MultiFormatReader ( ) ;
527609 var hints = new Dictionary < DecodeHintType , object >
528- {
529- { DecodeHintType . TRY_HARDER , true } ,
530- { DecodeHintType . POSSIBLE_FORMATS , new [ ]
531610 {
532- BarcodeFormat . QR_CODE , BarcodeFormat . DATA_MATRIX , BarcodeFormat . AZTEC ,
533- BarcodeFormat . PDF_417 , BarcodeFormat . CODE_128 , BarcodeFormat . CODE_39 ,
534- BarcodeFormat . EAN_13 , BarcodeFormat . EAN_8 , BarcodeFormat . UPC_A
535- }
536- }
537- } ;
611+ { DecodeHintType . TRY_HARDER , true } ,
612+ { DecodeHintType . POSSIBLE_FORMATS , new [ ]
613+ {
614+ BarcodeFormat . QR_CODE , BarcodeFormat . DATA_MATRIX , BarcodeFormat . AZTEC ,
615+ BarcodeFormat . PDF_417 , BarcodeFormat . CODE_128 , BarcodeFormat . CODE_39 ,
616+ BarcodeFormat . EAN_13 , BarcodeFormat . EAN_8 , BarcodeFormat . UPC_A
617+ }
618+ }
619+ } ;
538620
539621 return reader . decode ( binary , hints ) ;
540622 }
@@ -583,7 +665,7 @@ private void ScanQRCode_Click(object sender, RoutedEventArgs e)
583665 }
584666 }
585667
586- private void ScanDocument_Click ( object sender , RoutedEventArgs e ) // 扫描文档
668+ private void ScanDocument_Click ( object sender , RoutedEventArgs e )
587669 {
588670 var bmp = _videoService . GetFrameCopy ( ) ;
589671 if ( bmp == null ) return ;
@@ -620,6 +702,7 @@ private void ScanDocument_Click(object sender, RoutedEventArgs e)// 扫描文档
620702 }
621703 }
622704
705+
623706 // =========================
624707 // 画面调节窗口(不写入 config)
625708 // =========================
@@ -685,19 +768,29 @@ private void SwitchCamera_Click(object sender, RoutedEventArgs e)
685768 }
686769
687770 // =========================
688- // 配置保存/加载(摄像头索引 + 透视校正)
771+ // 配置保存/加载(摄像头索引 + 透视校正 + 新增设置 )
689772 // =========================
690773 private void LoadConfig ( )
691774 {
692775 try
693776 {
694- if ( ! File . Exists ( configPath ) ) return ;
777+ if ( ! File . Exists ( configPath ) )
778+ {
779+ // 使用默认配置
780+ config = new AppConfig ( ) ;
781+ return ;
782+ }
695783
696784 var json = File . ReadAllText ( configPath , Encoding . UTF8 ) ;
697785 var cfg = JsonConvert . DeserializeObject < AppConfig > ( json ) ;
698- if ( cfg == null ) return ;
786+ if ( cfg == null )
787+ {
788+ config = new AppConfig ( ) ;
789+ return ;
790+ }
699791
700792 currentCameraIndex = cfg . CameraIndex ;
793+ config = cfg ;
701794
702795 if ( cfg . CorrectionPoints != null && cfg . CorrectionPoints . Count == 4 )
703796 {
@@ -708,6 +801,7 @@ private void LoadConfig()
708801 catch ( Exception ex )
709802 {
710803 Console . WriteLine ( "加载配置失败: " + ex . Message ) ;
804+ config = new AppConfig ( ) ; // 使用默认配置
711805 }
712806 }
713807
@@ -717,17 +811,21 @@ private void SaveConfig()
717811 {
718812 var cfg = new AppConfig
719813 {
720- CameraIndex = currentCameraIndex
814+ CameraIndex = currentCameraIndex ,
815+ CorrectionPoints = _perspectiveCorrectionFilter != null ?
816+ new List < IntPoint > ( _perspectiveCorrectionFilter . SourceQuadrilateral ) : null ,
817+ SourceWidth = _perspectiveCorrectionFilter ? . NewWidth ?? 0 ,
818+ SourceHeight = _perspectiveCorrectionFilter ? . NewHeight ?? 0 ,
819+
820+ // 新增设置项
821+ StartMaximized = config . StartMaximized ,
822+ AutoStartCamera = config . AutoStartCamera ,
823+ DefaultPenWidth = userPenWidth ,
824+ DefaultPenColor = Ink . DefaultDrawingAttributes . Color . ToString ( ) ,
825+ EnableHardwareAcceleration = config . EnableHardwareAcceleration ,
826+ FrameRateLimit = config . FrameRateLimit
721827 } ;
722828
723- if ( _perspectiveCorrectionFilter != null )
724- {
725- // 保存校正点与目标尺寸
726- cfg . CorrectionPoints = new List < IntPoint > ( _perspectiveCorrectionFilter . SourceQuadrilateral ) ;
727- cfg . SourceWidth = _perspectiveCorrectionFilter . NewWidth ;
728- cfg . SourceHeight = _perspectiveCorrectionFilter . NewHeight ;
729- }
730-
731829 var json = JsonConvert . SerializeObject ( cfg , Formatting . Indented ) ;
732830 File . WriteAllText ( configPath , json , Encoding . UTF8 ) ;
733831 }
@@ -737,6 +835,49 @@ private void SaveConfig()
737835 }
738836 }
739837
838+ // =========================
839+ // 设置窗口功能
840+ // =========================
841+ // 在MainWindow类中添加
842+ private void OpenSettings_Click ( object sender , RoutedEventArgs e )
843+ {
844+ // 获取可用摄像头列表
845+ var cameras = _videoService . GetAvailableCameras ( ) ;
846+
847+ // 创建设置窗口并传入当前配置
848+ var settingsWindow = new SettingsWindow ( config , cameras )
849+ {
850+ Owner = this ,
851+ WindowStartupLocation = WindowStartupLocation . CenterOwner
852+ } ;
853+
854+ if ( settingsWindow . ShowDialog ( ) == true )
855+ {
856+ // 应用设置
857+ WindowState = config . StartMaximized ? WindowState . Maximized : WindowState . Normal ;
858+
859+ // 更新画笔设置
860+ var penColor = ( System . Windows . Media . Color ) System . Windows . Media . ColorConverter . ConvertFromString ( config . DefaultPenColor ) ;
861+ Ink . DefaultDrawingAttributes . Color = penColor ;
862+ userPenWidth = config . DefaultPenWidth ;
863+ UpdatePenAttributes ( ) ;
864+
865+ // 保存配置
866+ SaveConfig ( ) ;
867+
868+ // 如果摄像头变更,重新启动摄像头
869+ if ( currentCameraIndex != config . CameraIndex )
870+ {
871+ currentCameraIndex = config . CameraIndex ;
872+ _videoService . Stop ( ) ;
873+ if ( config . AutoStartCamera && ! _videoService . Start ( currentCameraIndex ) )
874+ {
875+ MessageBox . Show ( "切换摄像头失败。" , "错误" , MessageBoxButton . OK , MessageBoxImage . Error ) ;
876+ }
877+ }
878+ }
879+ }
880+
740881 // =========================
741882 // 视频帧统一处理:校正 + 调节
742883 // =========================
@@ -822,4 +963,4 @@ protected override void OnClosed(EventArgs e)
822963 base . OnClosed ( e ) ;
823964 }
824965 }
825- }
966+ }
0 commit comments