add:pdf插入
This commit is contained in:
@@ -20,7 +20,6 @@ namespace Ink_Canvas.Controls
|
|||||||
private uint _currentIndex;
|
private uint _currentIndex;
|
||||||
private bool _compressLargePictures;
|
private bool _compressLargePictures;
|
||||||
private bool _isPagingBusy;
|
private bool _isPagingBusy;
|
||||||
private bool _layoutSizeLocked;
|
|
||||||
|
|
||||||
/// <summary>页码或可翻页状态变化(用于更新侧栏)。</summary>
|
/// <summary>页码或可翻页状态变化(用于更新侧栏)。</summary>
|
||||||
public event EventHandler PageNavigationStateChanged;
|
public event EventHandler PageNavigationStateChanged;
|
||||||
@@ -42,14 +41,18 @@ namespace Ink_Canvas.Controls
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化并显示第一页;由 MainWindow 在 UI 线程创建后调用。
|
/// 初始化并显示指定页;由 MainWindow 在 UI 线程创建后调用。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task InitializeAsync(string pdfFilePath, uint pageCount, bool compressLargePictures)
|
/// <param name="initialPageIndex">从 0 开始的页码,超出范围时夹紧到合法区间。</param>
|
||||||
|
public async Task InitializeAsync(string pdfFilePath, uint pageCount, bool compressLargePictures, uint initialPageIndex = 0)
|
||||||
{
|
{
|
||||||
_pdfPath = pdfFilePath ?? throw new ArgumentNullException(nameof(pdfFilePath));
|
_pdfPath = pdfFilePath ?? throw new ArgumentNullException(nameof(pdfFilePath));
|
||||||
_pageCount = pageCount;
|
_pageCount = pageCount;
|
||||||
_compressLargePictures = compressLargePictures;
|
_compressLargePictures = compressLargePictures;
|
||||||
_currentIndex = 0;
|
if (_pageCount == 0)
|
||||||
|
_currentIndex = 0;
|
||||||
|
else
|
||||||
|
_currentIndex = initialPageIndex >= _pageCount ? _pageCount - 1 : initialPageIndex;
|
||||||
|
|
||||||
await ShowPageAsync(_currentIndex);
|
await ShowPageAsync(_currentIndex);
|
||||||
}
|
}
|
||||||
@@ -104,12 +107,9 @@ namespace Ink_Canvas.Controls
|
|||||||
|
|
||||||
BitmapSource display = ApplyCompressionIfNeeded(raw);
|
BitmapSource display = ApplyCompressionIfNeeded(raw);
|
||||||
_pageImage.Source = display;
|
_pageImage.Source = display;
|
||||||
if (!_layoutSizeLocked)
|
// 每页尺寸可能不同,与图片一致按当前页位图更新布局,避免翻页后内容被裁切或“消失”
|
||||||
{
|
Width = display.PixelWidth;
|
||||||
Width = display.PixelWidth;
|
Height = display.PixelHeight;
|
||||||
Height = display.PixelHeight;
|
|
||||||
_layoutSizeLocked = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Ink_Canvas.Controls;
|
||||||
using Ink_Canvas.Helpers;
|
using Ink_Canvas.Helpers;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -81,7 +82,7 @@ namespace Ink_Canvas
|
|||||||
var missingElements = 0;
|
var missingElements = 0;
|
||||||
foreach (UIElement child in inkCanvas.Children)
|
foreach (UIElement child in inkCanvas.Children)
|
||||||
{
|
{
|
||||||
if (child is Image || child is MediaElement)
|
if (child is Image || child is MediaElement || child is PdfEmbeddedView)
|
||||||
{
|
{
|
||||||
if (child is Image img && img.Tag is string tag && tag == VideoPresenterLiveFrameTag)
|
if (child is Image img && img.Tag is string tag && tag == VideoPresenterLiveFrameTag)
|
||||||
{
|
{
|
||||||
@@ -310,6 +311,16 @@ namespace Ink_Canvas
|
|||||||
}
|
}
|
||||||
BindElementEvents(media);
|
BindElementEvents(media);
|
||||||
}
|
}
|
||||||
|
else if (element is PdfEmbeddedView pdf)
|
||||||
|
{
|
||||||
|
double left = InkCanvas.GetLeft(pdf);
|
||||||
|
double top = InkCanvas.GetTop(pdf);
|
||||||
|
if (double.IsNaN(left) || double.IsNaN(top))
|
||||||
|
{
|
||||||
|
CenterAndScaleElement(pdf);
|
||||||
|
}
|
||||||
|
BindElementEvents(pdf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1021,6 +1021,46 @@ namespace Ink_Canvas
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>从保存的 <see cref="CanvasElementInfo"/> 恢复 PDF(与打开墨迹时的图片恢复流程一致,不单独写入时间轴)。</summary>
|
||||||
|
private async Task RestorePdfFromElementInfoAsync(CanvasElementInfo info)
|
||||||
|
{
|
||||||
|
if (info == null || inkCanvas == null) return;
|
||||||
|
if (!string.Equals(info.Type, "Pdf", StringComparison.OrdinalIgnoreCase)) return;
|
||||||
|
if (string.IsNullOrEmpty(info.SourcePath) || !File.Exists(info.SourcePath)) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
uint pageCount = await PdfWinRtHelper.GetPageCountAsync(info.SourcePath);
|
||||||
|
if (pageCount == 0) return;
|
||||||
|
|
||||||
|
bool compress = isLoaded && Settings.Canvas.IsCompressPicturesUploaded;
|
||||||
|
uint initial = 0;
|
||||||
|
if (info.PdfCurrentPage.HasValue)
|
||||||
|
initial = (uint)Math.Max(0, Math.Min(info.PdfCurrentPage.Value, (int)pageCount - 1));
|
||||||
|
|
||||||
|
var view = new PdfEmbeddedView
|
||||||
|
{
|
||||||
|
Name = "pdf_" + DateTime.Now.ToString("yyyyMMdd_HH_mm_ss_fff")
|
||||||
|
};
|
||||||
|
await view.InitializeAsync(info.SourcePath, pageCount, compress, initial);
|
||||||
|
|
||||||
|
if (info.Width > 0) view.Width = info.Width;
|
||||||
|
if (info.Height > 0) view.Height = info.Height;
|
||||||
|
|
||||||
|
InkCanvas.SetLeft(view, info.Left);
|
||||||
|
InkCanvas.SetTop(view, info.Top);
|
||||||
|
|
||||||
|
InitializeElementTransform(view);
|
||||||
|
BindElementEvents(view);
|
||||||
|
inkCanvas.Children.Add(view);
|
||||||
|
SyncPdfPageSidebarWithCanvas();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"从 .elements.json 恢复 PDF 失败: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Media
|
#region Media
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Ink_Canvas.Controls;
|
|
||||||
using Ink_Canvas.Helpers;
|
using Ink_Canvas.Helpers;
|
||||||
using iNKORE.UI.WPF.Modern;
|
using iNKORE.UI.WPF.Modern;
|
||||||
using System;
|
using System;
|
||||||
@@ -19,7 +18,6 @@ using Application = System.Windows.Application;
|
|||||||
using Button = System.Windows.Controls.Button;
|
using Button = System.Windows.Controls.Button;
|
||||||
using Cursors = System.Windows.Input.Cursors;
|
using Cursors = System.Windows.Input.Cursors;
|
||||||
using HorizontalAlignment = System.Windows.HorizontalAlignment;
|
using HorizontalAlignment = System.Windows.HorizontalAlignment;
|
||||||
using Image = System.Windows.Controls.Image;
|
|
||||||
using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox;
|
using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox;
|
||||||
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
||||||
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
|
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Ink_Canvas.Controls;
|
||||||
using Ink_Canvas.Helpers;
|
using Ink_Canvas.Helpers;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
@@ -16,6 +17,7 @@ using System.Windows.Ink;
|
|||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Threading;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Color = System.Drawing.Color;
|
using Color = System.Drawing.Color;
|
||||||
@@ -28,16 +30,58 @@ namespace Ink_Canvas
|
|||||||
// 1. 定义元素信息结构
|
// 1. 定义元素信息结构
|
||||||
public class CanvasElementInfo
|
public class CanvasElementInfo
|
||||||
{
|
{
|
||||||
public string Type { get; set; } // "Image"
|
public string Type { get; set; } // "Image" | "Pdf"
|
||||||
public string SourcePath { get; set; }
|
public string SourcePath { get; set; }
|
||||||
public double Left { get; set; }
|
public double Left { get; set; }
|
||||||
public double Top { get; set; }
|
public double Top { get; set; }
|
||||||
public double Width { get; set; }
|
public double Width { get; set; }
|
||||||
public double Height { get; set; }
|
public double Height { get; set; }
|
||||||
public string Stretch { get; set; } = "Fill"; // 默认为Fill
|
public string Stretch { get; set; } = "Fill"; // 默认为Fill
|
||||||
|
/// <summary>PDF 当前页(从 0 开始),仅 Type == Pdf 时有效。</summary>
|
||||||
|
public int? PdfCurrentPage { get; set; }
|
||||||
|
/// <summary>保存时的 PDF 总页数,用于校验;仅 Type == Pdf 时有效。</summary>
|
||||||
|
public int? PdfPageCount { get; set; }
|
||||||
}
|
}
|
||||||
public partial class MainWindow : Window
|
public partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
|
/// <summary>收集画布上图片与 PDF 的元数据,写入 .elements.json(与墨迹文件同路径)。</summary>
|
||||||
|
private void CollectCanvasElementsMetadata(List<CanvasElementInfo> elementInfos)
|
||||||
|
{
|
||||||
|
if (elementInfos == null || inkCanvas == null) return;
|
||||||
|
|
||||||
|
foreach (var child in inkCanvas.Children)
|
||||||
|
{
|
||||||
|
if (child is Image img && img.Source is BitmapImage bmp)
|
||||||
|
{
|
||||||
|
elementInfos.Add(new CanvasElementInfo
|
||||||
|
{
|
||||||
|
Type = "Image",
|
||||||
|
SourcePath = bmp.UriSource?.LocalPath ?? "",
|
||||||
|
Left = InkCanvas.GetLeft(img),
|
||||||
|
Top = InkCanvas.GetTop(img),
|
||||||
|
Width = img.Width,
|
||||||
|
Height = img.Height,
|
||||||
|
Stretch = img.Stretch.ToString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (child is PdfEmbeddedView pdf && !string.IsNullOrEmpty(pdf.PdfPath))
|
||||||
|
{
|
||||||
|
elementInfos.Add(new CanvasElementInfo
|
||||||
|
{
|
||||||
|
Type = "Pdf",
|
||||||
|
SourcePath = pdf.PdfPath,
|
||||||
|
Left = InkCanvas.GetLeft(pdf),
|
||||||
|
Top = InkCanvas.GetTop(pdf),
|
||||||
|
Width = pdf.Width,
|
||||||
|
Height = pdf.Height,
|
||||||
|
Stretch = "Uniform",
|
||||||
|
PdfCurrentPage = (int)pdf.CurrentPageIndex,
|
||||||
|
PdfPageCount = (int)pdf.PageCount
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 保存墨迹的鼠标释放事件处理
|
/// 保存墨迹的鼠标释放事件处理
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -419,22 +463,7 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
// 保存元素信息
|
// 保存元素信息
|
||||||
var elementInfos = new List<CanvasElementInfo>();
|
var elementInfos = new List<CanvasElementInfo>();
|
||||||
foreach (var child in inkCanvas.Children)
|
CollectCanvasElementsMetadata(elementInfos);
|
||||||
{
|
|
||||||
if (child is Image img && img.Source is BitmapImage bmp)
|
|
||||||
{
|
|
||||||
elementInfos.Add(new CanvasElementInfo
|
|
||||||
{
|
|
||||||
Type = "Image",
|
|
||||||
SourcePath = bmp.UriSource?.LocalPath ?? "",
|
|
||||||
Left = InkCanvas.GetLeft(img),
|
|
||||||
Top = InkCanvas.GetTop(img),
|
|
||||||
Width = img.Width,
|
|
||||||
Height = img.Height,
|
|
||||||
Stretch = img.Stretch.ToString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
string elementsPath = Settings.Automation.IsSaveStrokesAsXML ? Path.ChangeExtension(savePathWithName, ".elements.json") : Path.ChangeExtension(savePathWithName, ".elements.json");
|
string elementsPath = Settings.Automation.IsSaveStrokesAsXML ? Path.ChangeExtension(savePathWithName, ".elements.json") : Path.ChangeExtension(savePathWithName, ".elements.json");
|
||||||
File.WriteAllText(elementsPath, JsonConvert.SerializeObject(elementInfos, Newtonsoft.Json.Formatting.Indented));
|
File.WriteAllText(elementsPath, JsonConvert.SerializeObject(elementInfos, Newtonsoft.Json.Formatting.Indented));
|
||||||
}
|
}
|
||||||
@@ -485,22 +514,7 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
// 同时保存元素信息
|
// 同时保存元素信息
|
||||||
var elementInfos = new List<CanvasElementInfo>();
|
var elementInfos = new List<CanvasElementInfo>();
|
||||||
foreach (var child in inkCanvas.Children)
|
CollectCanvasElementsMetadata(elementInfos);
|
||||||
{
|
|
||||||
if (child is Image img && img.Source is BitmapImage bmp)
|
|
||||||
{
|
|
||||||
elementInfos.Add(new CanvasElementInfo
|
|
||||||
{
|
|
||||||
Type = "Image",
|
|
||||||
SourcePath = bmp.UriSource?.LocalPath ?? "",
|
|
||||||
Left = InkCanvas.GetLeft(img),
|
|
||||||
Top = InkCanvas.GetTop(img),
|
|
||||||
Width = img.Width,
|
|
||||||
Height = img.Height,
|
|
||||||
Stretch = img.Stretch.ToString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File.WriteAllText(Path.ChangeExtension(xmlPath, ".elements.json"), JsonConvert.SerializeObject(elementInfos, Newtonsoft.Json.Formatting.Indented));
|
File.WriteAllText(Path.ChangeExtension(xmlPath, ".elements.json"), JsonConvert.SerializeObject(elementInfos, Newtonsoft.Json.Formatting.Indented));
|
||||||
|
|
||||||
// 异步上传到Dlass
|
// 异步上传到Dlass
|
||||||
@@ -1266,6 +1280,10 @@ namespace Ink_Canvas
|
|||||||
InkCanvas.SetTop(img, info.Top);
|
InkCanvas.SetTop(img, info.Top);
|
||||||
inkCanvas.Children.Add(img);
|
inkCanvas.Children.Add(img);
|
||||||
}
|
}
|
||||||
|
else if (string.Equals(info.Type, "Pdf", StringComparison.OrdinalIgnoreCase) && File.Exists(info.SourcePath))
|
||||||
|
{
|
||||||
|
Dispatcher.BeginInvoke(new Action(() => { _ = RestorePdfFromElementInfoAsync(info); }), DispatcherPriority.Loaded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1416,6 +1434,10 @@ namespace Ink_Canvas
|
|||||||
InkCanvas.SetTop(img, info.Top);
|
InkCanvas.SetTop(img, info.Top);
|
||||||
inkCanvas.Children.Add(img);
|
inkCanvas.Children.Add(img);
|
||||||
}
|
}
|
||||||
|
else if (string.Equals(info.Type, "Pdf", StringComparison.OrdinalIgnoreCase) && File.Exists(info.SourcePath))
|
||||||
|
{
|
||||||
|
Dispatcher.BeginInvoke(new Action(() => { _ = RestorePdfFromElementInfoAsync(info); }), DispatcherPriority.Loaded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user