diff --git a/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs b/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs index 7ce92c94..bab3e578 100644 --- a/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs +++ b/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs @@ -9,7 +9,6 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Forms; -using System.Windows.Ink; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Threading; @@ -31,17 +30,15 @@ public struct ScreenshotResult public Bitmap CameraImage; public BitmapSource CameraBitmapSource; public bool AddToWhiteboard; - public bool IncludeInk; public ScreenshotResult(Rectangle area, List path = null, Bitmap cameraImage = null, - BitmapSource cameraBitmapSource = null, bool addToWhiteboard = false, bool includeInk = true) + BitmapSource cameraBitmapSource = null, bool addToWhiteboard = false) { Area = area; Path = path; CameraImage = cameraImage; CameraBitmapSource = cameraBitmapSource; AddToWhiteboard = addToWhiteboard; - IncludeInk = includeInk; } } @@ -98,7 +95,7 @@ private async Task CaptureScreenshotAndInsert() else if (screenshotResult.Value.Area.Width > 0 && screenshotResult.Value.Area.Height > 0) { // 屏幕截图 - using (var originalBitmap = CaptureScreenAreaWithOptionalInk(screenshotResult.Value.Area, screenshotResult.Value.IncludeInk)) + using (var originalBitmap = CaptureScreenArea(screenshotResult.Value.Area)) { if (originalBitmap != null) { @@ -210,16 +207,7 @@ private async Task CaptureFullScreenAndInsert() { await Application.Current.Dispatcher.InvokeAsync(() => { - var selectorWindow = new ScreenshotSelectorWindow(shouldIncludeInk => - { - if (inkCanvas == null) - { - return; - } - - inkCanvas.Visibility = shouldIncludeInk ? Visibility.Visible : Visibility.Collapsed; - Dispatcher.Invoke(() => { }, DispatcherPriority.Render); - }); + var selectorWindow = new ScreenshotSelectorWindow(); if (selectorWindow.ShowDialog() == true) { // 检查是否是摄像头截图 @@ -230,8 +218,7 @@ await Application.Current.Dispatcher.InvokeAsync(() => null, // 摄像头截图不需要路径 null, // 不再使用Bitmap selectorWindow.CameraBitmapSource, // 摄像头BitmapSource - selectorWindow.ShouldAddToWhiteboard, - selectorWindow.ShouldIncludeInk + selectorWindow.ShouldAddToWhiteboard ); } else if (selectorWindow.CameraImage != null) @@ -241,8 +228,7 @@ await Application.Current.Dispatcher.InvokeAsync(() => null, // 摄像头截图不需要路径 selectorWindow.CameraImage, // 摄像头图像 null, - selectorWindow.ShouldAddToWhiteboard, - selectorWindow.ShouldIncludeInk + selectorWindow.ShouldAddToWhiteboard ); } else @@ -252,8 +238,7 @@ await Application.Current.Dispatcher.InvokeAsync(() => selectorWindow.SelectedPath, null, null, - selectorWindow.ShouldAddToWhiteboard, - selectorWindow.ShouldIncludeInk + selectorWindow.ShouldAddToWhiteboard ); } } @@ -319,108 +304,6 @@ private Bitmap CaptureScreenArea(Rectangle area) } } - private Bitmap CaptureScreenAreaWithOptionalInk(Rectangle area, bool includeInk) - { - Bitmap bitmap = null; - StrokeCollection strokesForOverlay = null; - Point? inkCanvasTopLeftOnScreen = null; - System.Windows.Media.Matrix? dpiTransform = null; - var originalWindowVisibility = Visibility; - - try - { - if (includeInk && inkCanvas != null && inkCanvas.Strokes.Count > 0) - { - strokesForOverlay = inkCanvas.Strokes.Clone(); - - var source = PresentationSource.FromVisual(inkCanvas); - if (source?.CompositionTarget != null) - { - dpiTransform = source.CompositionTarget.TransformToDevice; - } - - inkCanvasTopLeftOnScreen = inkCanvas.PointToScreen(new Point(0, 0)); - } - - // 先隐藏主窗口再截取屏幕,确保基础截图不包含主线程 UI(含墨迹层)。 - Visibility = Visibility.Hidden; - Dispatcher.Invoke(() => { }, DispatcherPriority.Render); - - bitmap = CaptureScreenArea(area); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"准备截图时处理墨迹失败: {ex.Message}", LogHelper.LogType.Error); - bitmap?.Dispose(); - return null; - } - finally - { - Visibility = originalWindowVisibility; - Dispatcher.Invoke(() => { }, DispatcherPriority.Render); - } - - if (bitmap == null || !includeInk || strokesForOverlay == null || strokesForOverlay.Count == 0) - { - return bitmap; - } - - try - { - OverlayInkStrokesOnBitmap(bitmap, area, strokesForOverlay, inkCanvasTopLeftOnScreen, dpiTransform); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"叠加墨迹到截图失败: {ex.Message}", LogHelper.LogType.Error); - } - - return bitmap; - } - - private void OverlayInkStrokesOnBitmap( - Bitmap bitmap, - Rectangle area, - StrokeCollection strokes, - Point? inkCanvasTopLeftOnScreen = null, - System.Windows.Media.Matrix? dpiTransform = null) - { - if (bitmap == null || strokes == null || strokes.Count == 0) - { - return; - } - - var transform = dpiTransform ?? new System.Windows.Media.Matrix(1, 0, 0, 1, 0, 0); - var topLeft = inkCanvasTopLeftOnScreen ?? new Point(area.X, area.Y); - var offsetX = topLeft.X * transform.M11 - area.X; - var offsetY = topLeft.Y * transform.M22 - area.Y; - - var drawingVisual = new DrawingVisual(); - using (var drawingContext = drawingVisual.RenderOpen()) - { - drawingContext.PushTransform(new TranslateTransform(offsetX, offsetY)); - strokes.Draw(drawingContext); - drawingContext.Pop(); - } - - var renderBitmap = new RenderTargetBitmap(bitmap.Width, bitmap.Height, 96, 96, PixelFormats.Pbgra32); - renderBitmap.Render(drawingVisual); - - var encoder = new PngBitmapEncoder(); - encoder.Frames.Add(BitmapFrame.Create(renderBitmap)); - - using (var memoryStream = new MemoryStream()) - { - encoder.Save(memoryStream); - memoryStream.Position = 0; - using (var overlayBitmap = new Bitmap(memoryStream)) - using (var graphics = Graphics.FromImage(bitmap)) - { - graphics.CompositingMode = CompositingMode.SourceOver; - graphics.DrawImage(overlayBitmap, 0, 0, bitmap.Width, bitmap.Height); - } - } - } - /// /// 将截图插入到画布 /// diff --git a/Ink Canvas/MainWindow_cs/MW_Screenshot.cs b/Ink Canvas/MainWindow_cs/MW_Screenshot.cs index a599c5f9..61632332 100644 --- a/Ink Canvas/MainWindow_cs/MW_Screenshot.cs +++ b/Ink Canvas/MainWindow_cs/MW_Screenshot.cs @@ -14,8 +14,6 @@ namespace Ink_Canvas { public partial class MainWindow : Window { - private bool _isAreaScreenshotInProgress; - /// /// 在切页/加页场景下使用:先捕获当前画面到内存并克隆墨迹,然后立即返回;截图与墨迹保存在后台异步执行,不阻塞切页。 /// 调用方应在调用本方法后立即执行 SaveStrokes、ClearStrokes、切页、RestoreStrokes 等逻辑。 @@ -159,98 +157,13 @@ internal void SaveScreenShotToDesktop() SaveInkCanvasStrokes(false); } - private struct AnnotationSuspendState - { - public bool WasInAnnotationMode; - public int OriginalMode; - public System.Windows.Media.Brush OriginalFakeBackground; - public double OriginalFakeBackgroundOpacity; - public Visibility OriginalBackgroundCoverHolderVisibility; - public Visibility OriginalCanvasControlsVisibility; - public object OriginalHideInkCanvasContent; - } - - private AnnotationSuspendState SuspendAnnotationForAreaScreenshotIfNeeded() - { - var state = new AnnotationSuspendState - { - WasInAnnotationMode = GridTransparencyFakeBackground.Background != System.Windows.Media.Brushes.Transparent, - OriginalMode = currentMode, - OriginalFakeBackground = GridTransparencyFakeBackground.Background, - OriginalFakeBackgroundOpacity = GridTransparencyFakeBackground.Opacity, - OriginalBackgroundCoverHolderVisibility = GridBackgroundCoverHolder.Visibility, - OriginalCanvasControlsVisibility = StackPanelCanvasControls.Visibility, - OriginalHideInkCanvasContent = BtnHideInkCanvas.Content - }; - - if (!state.WasInAnnotationMode) - { - return state; - } - - // 仅暂停批注视觉态,避免调用 BtnHideInkCanvas_Click 触发自动截图/上传及白板状态读写。 - GridTransparencyFakeBackground.Opacity = 0; - GridTransparencyFakeBackground.Background = System.Windows.Media.Brushes.Transparent; - GridBackgroundCoverHolder.Visibility = Visibility.Collapsed; - StackPanelCanvasControls.Visibility = Visibility.Collapsed; - CheckEnableTwoFingerGestureBtnVisibility(false); - HideSubPanels("cursor"); - BtnHideInkCanvas.Content = "显示\n画板"; - - return state; - } - - private void RestoreAnnotationAfterAreaScreenshot(AnnotationSuspendState state) - { - if (!state.WasInAnnotationMode || currentMode != state.OriginalMode) - { - return; - } - - GridTransparencyFakeBackground.Opacity = state.OriginalFakeBackgroundOpacity; - GridTransparencyFakeBackground.Background = state.OriginalFakeBackground; - GridBackgroundCoverHolder.Visibility = state.OriginalBackgroundCoverHolderVisibility; - StackPanelCanvasControls.Visibility = state.OriginalCanvasControlsVisibility; - CheckEnableTwoFingerGestureBtnVisibility(state.OriginalCanvasControlsVisibility == Visibility.Visible); - BtnHideInkCanvas.Content = state.OriginalHideInkCanvasContent; - } - internal async Task SaveAreaScreenShotToDesktop() { - if (_isAreaScreenshotInProgress) - { - ShowNotification("截图进行中,请先完成当前截图"); - return; - } - - _isAreaScreenshotInProgress = true; - - var annotationState = SuspendAnnotationForAreaScreenshotIfNeeded(); - var originalFloatingBarVisibility = ViewboxFloatingBar.Visibility; - var shouldRestoreFloatingBarVisibility = true; + var originalVisibility = Visibility; try { - if (annotationState.WasInAnnotationMode) - { - // 等待一次 UI 刷新,确保批注暂停状态已完成。 - await System.Windows.Threading.Dispatcher.Yield(System.Windows.Threading.DispatcherPriority.Render); - } - - // 从浮动栏触发选区截图时,临时隐藏浮动栏,避免遮挡选区与误入截图。 - if (originalFloatingBarVisibility == Visibility.Visible) - { - ViewboxFloatingBar.Visibility = Visibility.Collapsed; - await System.Windows.Threading.Dispatcher.Yield(System.Windows.Threading.DispatcherPriority.Render); - } - - // 选区截图时确保墨迹层可见,避免从浮动栏触发时出现“先隐藏再截图”。 - if (inkCanvas.Visibility != Visibility.Visible) - { - inkCanvas.Visibility = Visibility.Visible; - } - - // 等待一次 UI 刷新,确保可见性状态已生效。 - await System.Windows.Threading.Dispatcher.Yield(System.Windows.Threading.DispatcherPriority.Render); + Visibility = Visibility.Hidden; + await Task.Delay(200); var screenshotResult = await ShowScreenshotSelector(); @@ -262,12 +175,7 @@ internal async Task SaveAreaScreenShotToDesktop() if (screenshotResult.Value.AddToWhiteboard) { - // 仅在白板接管流程已确认完成时,才跳过本方法对浮动栏可见性的恢复。 - var whiteboardHandoffCompleted = await AddScreenshotToNewWhiteboardPage(screenshotResult.Value); - if (whiteboardHandoffCompleted) - { - shouldRestoreFloatingBarVisibility = false; - } + await AddScreenshotToNewWhiteboardPage(screenshotResult.Value); return; } @@ -281,7 +189,7 @@ internal async Task SaveAreaScreenShotToDesktop() Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png"); - using (var originalBitmap = CaptureScreenAreaWithOptionalInk(screenshotResult.Value.Area, screenshotResult.Value.IncludeInk)) + using (var originalBitmap = CaptureScreenArea(screenshotResult.Value.Area)) { if (originalBitmap == null) { @@ -327,16 +235,11 @@ internal async Task SaveAreaScreenShotToDesktop() } finally { - _isAreaScreenshotInProgress = false; - if (shouldRestoreFloatingBarVisibility) - { - ViewboxFloatingBar.Visibility = originalFloatingBarVisibility; - } - RestoreAnnotationAfterAreaScreenshot(annotationState); + Visibility = originalVisibility; } } - private async Task AddScreenshotToNewWhiteboardPage(ScreenshotResult screenshotResult) + private async Task AddScreenshotToNewWhiteboardPage(ScreenshotResult screenshotResult) { // 先在当前场景准备截图数据,再进白板,避免误截到白板页面 BitmapSource bitmapSourceForClipboard = null; @@ -356,15 +259,15 @@ private async Task AddScreenshotToNewWhiteboardPage(ScreenshotResult scree if (screenshotResult.Area.Width <= 0 || screenshotResult.Area.Height <= 0) { ShowNotification("未选择有效截图区域"); - return false; + return; } - using (var originalBitmap = CaptureScreenAreaWithOptionalInk(screenshotResult.Area, screenshotResult.IncludeInk)) + using (var originalBitmap = CaptureScreenArea(screenshotResult.Area)) { if (originalBitmap == null) { ShowNotification("截图失败"); - return false; + return; } Bitmap finalBitmap = originalBitmap; @@ -393,7 +296,7 @@ private async Task AddScreenshotToNewWhiteboardPage(ScreenshotResult scree if (bitmapSourceForClipboard == null) { ShowNotification("截图转换失败"); - return false; + return; } // 图像已拷贝到内存后再进入白板 @@ -408,7 +311,6 @@ private async Task AddScreenshotToNewWhiteboardPage(ScreenshotResult scree BtnWhiteBoardAdd_Click(null, EventArgs.Empty); await InsertBitmapSourceToCanvas(bitmapSourceForClipboard); - return true; } /// diff --git a/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml b/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml index 1e198242..0e9584d8 100644 --- a/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml +++ b/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml @@ -139,17 +139,6 @@ - - -