From 13396f418be9869deb288f16bca9927c05b822c3 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 22 Feb 2026 12:20:37 +0800 Subject: [PATCH] =?UTF-8?q?improve:=E7=99=BD=E6=9D=BF=E7=BF=BB=E9=A1=B5?= =?UTF-8?q?=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow_cs/MW_BoardControls.cs | 8 +- Ink Canvas/MainWindow_cs/MW_Screenshot.cs | 104 +++++++++++++++++++ 2 files changed, 109 insertions(+), 3 deletions(-) diff --git a/Ink Canvas/MainWindow_cs/MW_BoardControls.cs b/Ink Canvas/MainWindow_cs/MW_BoardControls.cs index f37f4333..dca963c2 100644 --- a/Ink Canvas/MainWindow_cs/MW_BoardControls.cs +++ b/Ink Canvas/MainWindow_cs/MW_BoardControls.cs @@ -383,9 +383,10 @@ namespace Ink_Canvas /// 事件参数。 private void BtnWhiteBoardSwitchNext_Click(object sender, EventArgs e) { - if (Settings.Automation.IsAutoSaveStrokesAtClear && - inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) SaveScreenShot(true); + inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) + CaptureAndEnqueueScreenshotSave(isHideNotification: true); + if (CurrentWhiteboardIndex >= WhiteboardTotalCount) { // 在最后一页时,点击"新页面"按钮直接新增一页 @@ -430,7 +431,8 @@ namespace Ink_Canvas { if (WhiteboardTotalCount >= 99) return; if (Settings.Automation.IsAutoSaveStrokesAtClear && - inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) SaveScreenShot(true); + inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) + CaptureAndEnqueueScreenshotSave(isHideNotification: true); // 隐藏图片选择工具栏 if (currentSelectedElement != null) diff --git a/Ink Canvas/MainWindow_cs/MW_Screenshot.cs b/Ink Canvas/MainWindow_cs/MW_Screenshot.cs index 56d5a4ea..2738517d 100644 --- a/Ink Canvas/MainWindow_cs/MW_Screenshot.cs +++ b/Ink Canvas/MainWindow_cs/MW_Screenshot.cs @@ -6,11 +6,115 @@ using System.IO; using System.Threading.Tasks; using System.Windows; using System.Windows.Forms; +using System.Windows.Ink; +using Ink_Canvas.Helpers; namespace Ink_Canvas { public partial class MainWindow : Window { + /// + /// 在切页/加页场景下使用:先捕获当前画面到内存并克隆墨迹,然后立即返回;截图与墨迹保存在后台异步执行,不阻塞切页。 + /// 调用方应在调用本方法后立即执行 SaveStrokes、ClearStrokes、切页、RestoreStrokes 等逻辑。 + /// + /// 是否隐藏保存成功通知 + /// 截图文件名(可选) + private void CaptureAndEnqueueScreenshotSave(bool isHideNotification, string fileName = null) + { + var savePath = Settings.Automation.IsSaveScreenshotsInDateFolders + ? GetDateFolderPath(fileName) + : GetDefaultFolderPath(); + + System.Drawing.Bitmap bitmap = null; + StrokeCollection strokesToSave = null; + int pageIndexForStrokes = 0; + string strokeSavePath = null; + + try + { + bitmap = CaptureScreenshotToBitmap(); + if (bitmap == null) return; + + if (Settings.Automation.IsAutoSaveStrokesAtScreenshot && inkCanvas.Strokes.Count > 0) + { + strokesToSave = inkCanvas.Strokes.Clone(); + pageIndexForStrokes = CurrentWhiteboardIndex; + var basePath = Settings.Automation.AutoSavedStrokesLocation + + @"\Auto Saved - BlackBoard Strokes"; + if (!Directory.Exists(basePath)) Directory.CreateDirectory(basePath); + strokeSavePath = Path.Combine(basePath, + $"{DateTime.Now:yyyy-MM-dd HH-mm-ss-fff} Page-{pageIndexForStrokes} StrokesCount-{strokesToSave.Count}.icstk"); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"CaptureAndEnqueueScreenshotSave 捕获失败: {ex}", LogHelper.LogType.Error); + bitmap?.Dispose(); + return; + } + + var bitmapToSave = bitmap; + var path = savePath; + var hideNotification = isHideNotification; + + _ = Task.Run(() => + { + try + { + if (bitmapToSave != null) + { + var directory = Path.GetDirectoryName(path); + if (!Directory.Exists(directory)) + Directory.CreateDirectory(directory); + bitmapToSave.Save(path, ImageFormat.Png); + bitmapToSave.Dispose(); + } + + if (strokesToSave != null && !string.IsNullOrEmpty(strokeSavePath)) + { + using (var fs = new FileStream(strokeSavePath, FileMode.Create)) + { + strokesToSave.Save(fs); + } + } + + if (!hideNotification && !string.IsNullOrEmpty(path)) + { + Dispatcher.Invoke(() => ShowNotification($"截图成功保存至 {path}")); + } + + if (Settings?.Dlass?.AutoUploadDelayMinutes > 0) + { + Task.Delay(TimeSpan.FromMinutes(Settings.Dlass.AutoUploadDelayMinutes)).GetAwaiter().GetResult(); + Helpers.DlassNoteUploader.UploadNoteFileAsync(path).GetAwaiter().GetResult(); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"后台保存截图/墨迹失败: {ex}", LogHelper.LogType.Error); + bitmapToSave?.Dispose(); + } + }); + } + + /// + /// 将当前屏幕内容捕获为位图(仅内存,不写文件)。调用方或后台任务负责 Dispose。 + /// + private System.Drawing.Bitmap CaptureScreenshotToBitmap() + { + var rc = SystemInformation.VirtualScreen; + var bitmap = new System.Drawing.Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb); + using (var memoryGraphics = Graphics.FromImage(bitmap)) + { + memoryGraphics.CompositingQuality = CompositingQuality.HighQuality; + memoryGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic; + memoryGraphics.SmoothingMode = SmoothingMode.HighQuality; + memoryGraphics.CompositingMode = CompositingMode.SourceOver; + memoryGraphics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy); + } + return bitmap; + } + /// /// 保存截图 ///