diff --git a/Ink Canvas/InkCanvasForClass_mlbp2gn0_wpftmp.csproj b/Ink Canvas/InkCanvasForClass_mlbp2gn0_wpftmp.csproj
index 97db535e..ddd440ee 100644
--- a/Ink Canvas/InkCanvasForClass_mlbp2gn0_wpftmp.csproj
+++ b/Ink Canvas/InkCanvasForClass_mlbp2gn0_wpftmp.csproj
@@ -134,6 +134,7 @@
+
@@ -405,6 +406,7 @@
+
diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml
index af843d29..23e01666 100644
--- a/Ink Canvas/MainWindow.xaml
+++ b/Ink Canvas/MainWindow.xaml
@@ -2323,7 +2323,7 @@
FontFamily="Microsoft YaHei UI" FontWeight="Bold"
Toggled="ToggleSwitchSaveFullPageStrokes_Toggled" />
-
+
diff --git a/Ink Canvas/MainWindow_cs/MW_Save&OpenStrokes.cs b/Ink Canvas/MainWindow_cs/MW_Save&OpenStrokes.cs
index 17d5356e..41d013a0 100644
--- a/Ink Canvas/MainWindow_cs/MW_Save&OpenStrokes.cs
+++ b/Ink Canvas/MainWindow_cs/MW_Save&OpenStrokes.cs
@@ -10,6 +10,8 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Forms;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
+using System.Collections.Generic;
+using System.Windows.Controls;
namespace Ink_Canvas {
public partial class MainWindow : Window {
@@ -38,76 +40,75 @@ namespace Ink_Canvas {
//savePathWithName = savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".icstk";
savePathWithName = savePath + @"\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") + ".icstk";
- var fs = new FileStream(savePathWithName, FileMode.Create);
-
if (Settings.Automation.IsSaveFullPageStrokes)
{
- // 全页面保存模式 - 保存整个墨迹页面的图像
- var bitmap = new System.Drawing.Bitmap(
- (int)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
- (int)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height);
+ // 全页面保存模式 - 检查是否存在多页面墨迹
+ bool hasMultiplePages = false;
+ List allPageStrokes = new List();
- using (var g = System.Drawing.Graphics.FromImage(bitmap))
+ // 检查PPT放映模式下的多页面墨迹
+ if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible && pptApplication != null)
{
- // 创建黑色或透明背景
- System.Drawing.Color bgColor = Settings.Canvas.UsingWhiteboard
- ? System.Drawing.Color.White
- : System.Drawing.Color.FromArgb(22, 41, 36); // 黑板背景色
- g.Clear(bgColor);
-
- // 将InkCanvas墨迹渲染到Visual
- var visual = new DrawingVisual();
- using (var dc = visual.RenderOpen())
+ hasMultiplePages = true;
+ // 收集PPT放映模式下的所有页面墨迹
+ for (int i = 1; i <= pptApplication.SlideShowWindows[1].Presentation.Slides.Count; i++)
{
- // 创建一个VisualBrush,使用inkCanvas作为源
- var visualBrush = new VisualBrush(inkCanvas);
- // 绘制矩形并填充为inkCanvas的内容
- dc.DrawRectangle(visualBrush, null, new Rect(0, 0, inkCanvas.ActualWidth, inkCanvas.ActualHeight));
+ if (memoryStreams[i] != null && memoryStreams[i].Length > 8)
+ {
+ memoryStreams[i].Position = 0;
+ allPageStrokes.Add(new StrokeCollection(memoryStreams[i]));
+ }
+ else if (i == previousSlideID && inkCanvas.Strokes.Count > 0)
+ {
+ // 当前页面的墨迹
+ allPageStrokes.Add(inkCanvas.Strokes.Clone());
+ }
+ else
+ {
+ allPageStrokes.Add(new StrokeCollection()); // 空页面
+ }
}
-
- // 创建适合墨迹画布尺寸的渲染位图
- var rtb = new RenderTargetBitmap(
- (int)inkCanvas.ActualWidth, (int)inkCanvas.ActualHeight,
- 96, 96,
- PixelFormats.Pbgra32);
- rtb.Render(visual);
-
- // 转换为GDI+ Bitmap并保存
- var encoder = new PngBitmapEncoder();
- encoder.Frames.Add(BitmapFrame.Create(rtb));
-
- using (var ms = new MemoryStream())
+ }
+ // 检查白板模式下的多页面墨迹
+ else if (currentMode != 0 && WhiteboardTotalCount > 1)
+ {
+ hasMultiplePages = true;
+ // 收集白板模式下的所有页面墨迹
+ for (int i = 1; i <= WhiteboardTotalCount; i++)
{
- encoder.Save(ms);
- ms.Seek(0, SeekOrigin.Begin);
- var imgBitmap = new System.Drawing.Bitmap(ms);
-
- // 将生成的墨迹图像绘制到屏幕截图上
- // 居中绘制,确保墨迹位于屏幕中央
- int x = (bitmap.Width - imgBitmap.Width) / 2;
- int y = (bitmap.Height - imgBitmap.Height) / 2;
- g.DrawImage(imgBitmap, x, y);
-
- // 保存为PNG
- string imagePathWithName = Path.ChangeExtension(savePathWithName, "png");
- bitmap.Save(imagePathWithName, System.Drawing.Imaging.ImageFormat.Png);
-
- // 仍然保存墨迹文件以兼容旧版本
- inkCanvas.Strokes.Save(fs);
+ if (TimeMachineHistories[i] != null)
+ {
+ // 从历史记录中恢复墨迹
+ var strokes = ApplyHistoriesToNewStrokeCollection(TimeMachineHistories[i]);
+ allPageStrokes.Add(strokes);
+ }
+ else
+ {
+ allPageStrokes.Add(new StrokeCollection()); // 空页面
+ }
}
}
- // 显示提示
- if (newNotice) ShowNotification("墨迹成功全页面保存至 " + Path.ChangeExtension(savePathWithName, "png"));
+ if (hasMultiplePages && allPageStrokes.Count > 0)
+ {
+ // 多页面墨迹保存为压缩包
+ string zipFileName = Path.ChangeExtension(savePathWithName, "zip");
+ SaveMultiPageStrokesAsZip(allPageStrokes, zipFileName, newNotice);
+ }
+ else
+ {
+ // 单页面墨迹保存为图像
+ SaveSinglePageStrokesAsImage(savePathWithName, newNotice);
+ }
}
else
{
// 常规保存模式 - 仅保存墨迹对象
+ var fs = new FileStream(savePathWithName, FileMode.Create);
inkCanvas.Strokes.Save(fs);
+ fs.Close();
if (newNotice) ShowNotification("墨迹成功保存至 " + savePathWithName);
}
-
- fs.Close();
}
catch (Exception ex) {
ShowNotification("墨迹保存失败");
@@ -115,6 +116,193 @@ namespace Ink_Canvas {
}
}
+ ///
+ /// 将多页面墨迹保存为压缩包
+ ///
+ private void SaveMultiPageStrokesAsZip(List allPageStrokes, string zipFileName, bool newNotice)
+ {
+ try
+ {
+ // 创建临时目录来存放文件
+ string tempDir = Path.Combine(Path.GetTempPath(), $"InkCanvas_MultiPage_{DateTime.Now:yyyyMMdd_HHmmss}");
+ Directory.CreateDirectory(tempDir);
+
+ try
+ {
+ // 保存所有页面的文件到临时目录
+ for (int i = 0; i < allPageStrokes.Count; i++)
+ {
+ var strokes = allPageStrokes[i];
+ if (strokes.Count > 0)
+ {
+ // 保存墨迹文件
+ string strokeFileName = Path.Combine(tempDir, $"page_{i + 1:D4}.icstk");
+ using (var fs = new FileStream(strokeFileName, FileMode.Create))
+ {
+ strokes.Save(fs);
+ }
+
+ // 保存页面图像
+ string imageFileName = Path.Combine(tempDir, $"page_{i + 1:D4}.png");
+ using (var fs = new FileStream(imageFileName, FileMode.Create))
+ {
+ SavePageAsImage(strokes, fs);
+ }
+ }
+ }
+
+ // 保存元数据信息
+ string metadataFile = Path.Combine(tempDir, "metadata.txt");
+ using (var writer = new StreamWriter(metadataFile, false, System.Text.Encoding.UTF8))
+ {
+ writer.WriteLine($"保存时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
+ writer.WriteLine($"总页数: {allPageStrokes.Count}");
+ writer.WriteLine($"模式: {(currentMode == 0 ? "PPT放映" : "白板")}");
+ if (currentMode != 0)
+ {
+ writer.WriteLine($"当前页面: {CurrentWhiteboardIndex}");
+ writer.WriteLine($"总页面数: {WhiteboardTotalCount}");
+ }
+ else if (pptApplication != null)
+ {
+ writer.WriteLine($"PPT名称: {pptApplication.SlideShowWindows[1].Presentation.Name}");
+ writer.WriteLine($"PPT总页数: {pptApplication.SlideShowWindows[1].Presentation.Slides.Count}");
+ }
+
+ for (int i = 0; i < allPageStrokes.Count; i++)
+ {
+ writer.WriteLine($"页面 {i + 1}: {allPageStrokes[i].Count} 条墨迹");
+ }
+ }
+
+ // 使用.NET Framework内置的压缩功能创建ZIP文件
+ if (File.Exists(zipFileName))
+ File.Delete(zipFileName);
+
+ // 使用System.IO.Compression.FileSystem来创建ZIP
+ System.IO.Compression.ZipFile.CreateFromDirectory(tempDir, zipFileName);
+
+ if (newNotice) ShowNotification($"多页面墨迹成功保存至压缩包 {zipFileName}");
+ }
+ finally
+ {
+ // 清理临时目录
+ try
+ {
+ if (Directory.Exists(tempDir))
+ Directory.Delete(tempDir, true);
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"清理临时目录失败: {ex.ToString()}", LogHelper.LogType.Warning);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"保存多页面墨迹压缩包失败: {ex.ToString()}", LogHelper.LogType.Error);
+ throw;
+ }
+ }
+
+ ///
+ /// 将单页面墨迹保存为图像
+ ///
+ private void SaveSinglePageStrokesAsImage(string savePathWithName, bool newNotice)
+ {
+ // 全页面保存模式 - 保存整个墨迹页面的图像
+ var bitmap = new System.Drawing.Bitmap(
+ (int)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
+ (int)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height);
+
+ using (var g = System.Drawing.Graphics.FromImage(bitmap))
+ {
+ // 创建黑色或透明背景
+ System.Drawing.Color bgColor = Settings.Canvas.UsingWhiteboard
+ ? System.Drawing.Color.White
+ : System.Drawing.Color.FromArgb(22, 41, 36); // 黑板背景色
+ g.Clear(bgColor);
+
+ // 将InkCanvas墨迹渲染到Visual
+ var visual = new DrawingVisual();
+ using (var dc = visual.RenderOpen())
+ {
+ // 创建一个VisualBrush,使用inkCanvas作为源
+ var visualBrush = new VisualBrush(inkCanvas);
+ // 绘制矩形并填充为inkCanvas的内容
+ dc.DrawRectangle(visualBrush, null, new Rect(0, 0, inkCanvas.ActualWidth, inkCanvas.ActualHeight));
+ }
+
+ // 创建适合墨迹画布尺寸的渲染位图
+ var rtb = new RenderTargetBitmap(
+ (int)inkCanvas.ActualWidth, (int)inkCanvas.ActualHeight,
+ 96, 96,
+ PixelFormats.Pbgra32);
+ rtb.Render(visual);
+
+ // 转换为GDI+ Bitmap并保存
+ var encoder = new PngBitmapEncoder();
+ encoder.Frames.Add(BitmapFrame.Create(rtb));
+
+ using (var ms = new MemoryStream())
+ {
+ encoder.Save(ms);
+ ms.Seek(0, SeekOrigin.Begin);
+ var imgBitmap = new System.Drawing.Bitmap(ms);
+
+ // 将生成的墨迹图像绘制到屏幕截图上
+ // 居中绘制,确保墨迹位于屏幕中央
+ int x = (bitmap.Width - imgBitmap.Width) / 2;
+ int y = (bitmap.Height - imgBitmap.Height) / 2;
+ g.DrawImage(imgBitmap, x, y);
+
+ // 保存为PNG
+ string imagePathWithName = Path.ChangeExtension(savePathWithName, "png");
+ bitmap.Save(imagePathWithName, System.Drawing.Imaging.ImageFormat.Png);
+
+ // 仍然保存墨迹文件以兼容旧版本
+ var fs = new FileStream(savePathWithName, FileMode.Create);
+ inkCanvas.Strokes.Save(fs);
+ fs.Close();
+ }
+ }
+
+ // 显示提示
+ if (newNotice) ShowNotification("墨迹成功全页面保存至 " + Path.ChangeExtension(savePathWithName, "png"));
+ }
+
+ ///
+ /// 将指定墨迹集合保存为图像到指定流
+ ///
+ private void SavePageAsImage(StrokeCollection strokes, Stream outputStream)
+ {
+ try
+ {
+ // 创建临时InkCanvas来渲染墨迹
+ var tempCanvas = new InkCanvas();
+ tempCanvas.Strokes = strokes;
+ tempCanvas.Width = inkCanvas.ActualWidth;
+ tempCanvas.Height = inkCanvas.ActualHeight;
+
+ // 创建渲染位图
+ var rtb = new RenderTargetBitmap(
+ (int)tempCanvas.Width, (int)tempCanvas.Height,
+ 96, 96,
+ PixelFormats.Pbgra32);
+ rtb.Render(tempCanvas);
+
+ // 保存为PNG
+ var encoder = new PngBitmapEncoder();
+ encoder.Frames.Add(BitmapFrame.Create(rtb));
+ encoder.Save(outputStream);
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"保存页面图像失败: {ex.ToString()}", LogHelper.LogType.Error);
+ throw;
+ }
+ }
+
private void SymbolIconOpenStrokes_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
AnimationsHelper.HideWithSlideAndFade(BorderTools);