improve:墨迹延迟

This commit is contained in:
2025-09-13 21:38:03 +08:00
parent ec3bcddc9d
commit 5361f8ae6f
10 changed files with 79 additions and 45 deletions
+2 -2
View File
@@ -299,12 +299,12 @@ namespace Ink_Canvas
try try
{ {
// 获取主窗口实例并清理PowerPoint进程守护 // 获取主窗口实例并清理PowerPoint进程守护
var mainWindow = Application.Current.MainWindow as MainWindow; var mainWindow = Current.MainWindow as MainWindow;
if (mainWindow != null) if (mainWindow != null)
{ {
// 通过反射调用StopPowerPointProcessMonitoring方法 // 通过反射调用StopPowerPointProcessMonitoring方法
var method = mainWindow.GetType().GetMethod("StopPowerPointProcessMonitoring", var method = mainWindow.GetType().GetMethod("StopPowerPointProcessMonitoring",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); BindingFlags.NonPublic | BindingFlags.Instance);
method?.Invoke(mainWindow, null); method?.Invoke(mainWindow, null);
WriteCrashLog("PowerPoint进程守护已在系统关机时清理"); WriteCrashLog("PowerPoint进程守护已在系统关机时清理");
+1 -1
View File
@@ -194,7 +194,7 @@ namespace Ink_Canvas.Helpers
break; break;
} }
var bitmapSource = System.Windows.Media.Imaging.BitmapSource.Create( var bitmapSource = BitmapSource.Create(
bitmapData.Width, bitmapData.Width,
bitmapData.Height, bitmapData.Height,
_currentFrame.HorizontalResolution, _currentFrame.HorizontalResolution,
+18 -12
View File
@@ -78,30 +78,36 @@ namespace Ink_Canvas.Helpers
switch (Quality) switch (Quality)
{ {
case SmoothingQuality.Performance: case SmoothingQuality.Performance:
SmoothingStrength = 0.2; SmoothingStrength = 0.15;
ResampleInterval = 4.0; ResampleInterval = 5.0;
InterpolationSteps = 6; InterpolationSteps = 4;
UseAdaptiveInterpolation = false; UseAdaptiveInterpolation = false;
CurveTension = 0.2; CurveTension = 0.15;
MaxConcurrentTasks = Math.Max(1, Environment.ProcessorCount / 2); MaxConcurrentTasks = Math.Max(1, Environment.ProcessorCount / 2);
UseHardwareAcceleration = true;
UseAsyncProcessing = true;
break; break;
case SmoothingQuality.Balanced: case SmoothingQuality.Balanced:
SmoothingStrength = 0.4; SmoothingStrength = 0.3;
ResampleInterval = 2.5; ResampleInterval = 3.0;
InterpolationSteps = 12; InterpolationSteps = 8;
UseAdaptiveInterpolation = true; UseAdaptiveInterpolation = true;
CurveTension = 0.3; CurveTension = 0.25;
MaxConcurrentTasks = Environment.ProcessorCount; MaxConcurrentTasks = Environment.ProcessorCount;
UseHardwareAcceleration = true;
UseAsyncProcessing = true;
break; break;
case SmoothingQuality.Quality: case SmoothingQuality.Quality:
SmoothingStrength = 0.6; SmoothingStrength = 0.5;
ResampleInterval = 1.5; ResampleInterval = 2.0;
InterpolationSteps = 20; InterpolationSteps = 15;
UseAdaptiveInterpolation = true; UseAdaptiveInterpolation = true;
CurveTension = 0.4; CurveTension = 0.35;
MaxConcurrentTasks = Environment.ProcessorCount; MaxConcurrentTasks = Environment.ProcessorCount;
UseHardwareAcceleration = true;
UseAsyncProcessing = true;
break; break;
} }
} }
+35 -4
View File
@@ -25,10 +25,14 @@ namespace Ink_Canvas.Helpers
} }
/// <summary> /// <summary>
/// 用于显示笔迹的类 /// 用于显示笔迹的类
/// </summary> /// </summary>
public class StrokeVisual : DrawingVisual public class StrokeVisual : DrawingVisual
{ {
private bool _needsRedraw = true;
private int _lastPointCount = 0;
private const int REDRAW_THRESHOLD = 3;
/// <summary> /// <summary>
/// 创建显示笔迹的类 /// 创建显示笔迹的类
/// </summary> /// </summary>
@@ -49,15 +53,20 @@ namespace Ink_Canvas.Helpers
public StrokeVisual(DrawingAttributes drawingAttributes) public StrokeVisual(DrawingAttributes drawingAttributes)
{ {
_drawingAttributes = drawingAttributes; _drawingAttributes = drawingAttributes;
// 启用硬件加速
RenderOptions.SetBitmapScalingMode(this, BitmapScalingMode.HighQuality);
RenderOptions.SetEdgeMode(this, EdgeMode.Aliased);
RenderOptions.SetCachingHint(this, CachingHint.Cache);
} }
/// <summary> /// <summary>
/// 设置或获取显示的笔迹 /// 设置或获取显示的笔迹
/// </summary> /// </summary>
public Stroke Stroke { set; get; } public Stroke Stroke { set; get; }
/// <summary> /// <summary>
/// 在笔迹中添加点 /// 在笔迹中添加点
/// </summary> /// </summary>
/// <param name="point"></param> /// <param name="point"></param>
public void Add(StylusPoint point) public void Add(StylusPoint point)
@@ -66,28 +75,50 @@ namespace Ink_Canvas.Helpers
{ {
var collection = new StylusPointCollection { point }; var collection = new StylusPointCollection { point };
Stroke = new Stroke(collection) { DrawingAttributes = _drawingAttributes }; Stroke = new Stroke(collection) { DrawingAttributes = _drawingAttributes };
_lastPointCount = 1;
} }
else else
{ {
Stroke.StylusPoints.Add(point); Stroke.StylusPoints.Add(point);
_lastPointCount++;
} }
// 标记需要重绘
_needsRedraw = true;
} }
/// <summary> /// <summary>
/// 重新画出笔迹 /// 重新画出笔迹
/// </summary> /// </summary>
public void Redraw() public void Redraw()
{ {
if (!_needsRedraw || Stroke == null) return;
if (_lastPointCount % REDRAW_THRESHOLD != 0 && _lastPointCount > REDRAW_THRESHOLD)
{
return;
}
try try
{ {
using (var dc = RenderOpen()) using (var dc = RenderOpen())
{ {
Stroke.Draw(dc); Stroke.Draw(dc);
} }
_needsRedraw = false;
} }
catch { } catch { }
} }
/// <summary>
/// 强制重绘
/// </summary>
public void ForceRedraw()
{
_needsRedraw = true;
Redraw();
}
private readonly DrawingAttributes _drawingAttributes; private readonly DrawingAttributes _drawingAttributes;
public static implicit operator Stroke(StrokeVisual v) public static implicit operator Stroke(StrokeVisual v)
+3 -3
View File
@@ -291,7 +291,7 @@
</Image> </Image>
</Button> </Button>
<!-- 新增:个性化设置 --> <!-- 个性化设置 -->
<Button Width="40" Height="40" Margin="0,5,0,0" Style="{StaticResource NavButton}" <Button Width="40" Height="40" Margin="0,5,0,0" Style="{StaticResource NavButton}"
Click="NavTheme_Click" Tag="theme" ToolTip="个性化设置"> Click="NavTheme_Click" Tag="theme" ToolTip="个性化设置">
<Image Width="24" Height="24"> <Image Width="24" Height="24">
@@ -306,7 +306,7 @@
</Image> </Image>
</Button> </Button>
<!-- 新增:快捷键设置 --> <!-- 快捷键设置 -->
<Button Width="40" Height="40" Margin="0,5,0,0" Style="{StaticResource NavButton}" <Button Width="40" Height="40" Margin="0,5,0,0" Style="{StaticResource NavButton}"
Click="NavShortcuts_Click" Tag="shortcuts" ToolTip="快捷键设置"> Click="NavShortcuts_Click" Tag="shortcuts" ToolTip="快捷键设置">
<Image Width="24" Height="24"> <Image Width="24" Height="24">
@@ -821,7 +821,7 @@
</ui:SimpleStackPanel> </ui:SimpleStackPanel>
</GroupBox> </GroupBox>
<!-- 新增:崩溃后操作设置 --> <!-- 崩溃后操作设置 -->
<GroupBox> <GroupBox>
<GroupBox.Header> <GroupBox.Header>
<TextBlock Margin="0,12,0,0" Text="崩溃后操作" FontWeight="Bold" Foreground="#fafafa" <TextBlock Margin="0,12,0,0" Text="崩溃后操作" FontWeight="Bold" Foreground="#fafafa"
+11 -11
View File
@@ -28,9 +28,9 @@ namespace Ink_Canvas
public Rectangle Area; public Rectangle Area;
public List<Point> Path; public List<Point> Path;
public Bitmap CameraImage; public Bitmap CameraImage;
public System.Windows.Media.Imaging.BitmapSource CameraBitmapSource; public BitmapSource CameraBitmapSource;
public ScreenshotResult(Rectangle area, List<Point> path = null, Bitmap cameraImage = null, System.Windows.Media.Imaging.BitmapSource cameraBitmapSource = null) public ScreenshotResult(Rectangle area, List<Point> path = null, Bitmap cameraImage = null, BitmapSource cameraBitmapSource = null)
{ {
Area = area; Area = area;
Path = path; Path = path;
@@ -327,7 +327,7 @@ namespace Ink_Canvas
} }
// 将BitmapSource插入到画布(用于摄像头截图) // 将BitmapSource插入到画布(用于摄像头截图)
private async Task InsertBitmapSourceToCanvas(System.Windows.Media.Imaging.BitmapSource bitmapSource) private async Task InsertBitmapSourceToCanvas(BitmapSource bitmapSource)
{ {
try try
{ {
@@ -614,20 +614,20 @@ namespace Ink_Canvas
switch (bitmap.PixelFormat) switch (bitmap.PixelFormat)
{ {
case PixelFormat.Format24bppRgb: case PixelFormat.Format24bppRgb:
wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr24; wpfPixelFormat = PixelFormats.Bgr24;
break; break;
case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppArgb:
wpfPixelFormat = System.Windows.Media.PixelFormats.Bgra32; wpfPixelFormat = PixelFormats.Bgra32;
break; break;
case PixelFormat.Format32bppRgb: case PixelFormat.Format32bppRgb:
wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr32; wpfPixelFormat = PixelFormats.Bgr32;
break; break;
default: default:
wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr24; wpfPixelFormat = PixelFormats.Bgr24;
break; break;
} }
var bitmapSource = System.Windows.Media.Imaging.BitmapSource.Create( var bitmapSource = BitmapSource.Create(
bitmapData.Width, bitmapData.Width,
bitmapData.Height, bitmapData.Height,
bitmap.HorizontalResolution, bitmap.HorizontalResolution,
@@ -722,7 +722,7 @@ namespace Ink_Canvas
return null; return null;
// 使用最基础的方法:直接保存为PNG然后加载 // 使用最基础的方法:直接保存为PNG然后加载
var tempFile = System.IO.Path.GetTempFileName() + ".png"; var tempFile = Path.GetTempFileName() + ".png";
try try
{ {
@@ -742,9 +742,9 @@ namespace Ink_Canvas
// 清理临时文件 // 清理临时文件
try try
{ {
if (System.IO.File.Exists(tempFile)) if (File.Exists(tempFile))
{ {
System.IO.File.Delete(tempFile); File.Delete(tempFile);
} }
} }
catch (Exception deleteEx) catch (Exception deleteEx)
+1 -4
View File
@@ -337,14 +337,11 @@ namespace Ink_Canvas
{ {
try try
{ {
var stroke = GetStrokeVisual(e.StylusDevice.Id).Stroke; var stroke = GetStrokeVisual(e.StylusDevice.Id).Stroke;
// 正常模式:添加到画布并参与墨迹纠正 // 正常模式:添加到画布并参与墨迹纠正
// 墨迹渐隐功能现在在 StrokeCollected 事件中统一处理所有输入方式
inkCanvas.Strokes.Add(stroke); inkCanvas.Strokes.Add(stroke);
await Task.Delay(5); // 避免渲染墨迹完成前预览墨迹被删除导致墨迹闪烁 await Task.Delay(5);
inkCanvas.Children.Remove(GetVisualCanvas(e.StylusDevice.Id)); inkCanvas.Children.Remove(GetVisualCanvas(e.StylusDevice.Id));
inkCanvas_StrokeCollected(inkCanvas, inkCanvas_StrokeCollected(inkCanvas,
+1 -1
View File
@@ -222,7 +222,7 @@ namespace Ink_Canvas
var menuItem = sender as MenuItem; var menuItem = sender as MenuItem;
if (menuItem != null) if (menuItem != null)
{ {
var headerPanel = menuItem.Header as iNKORE.UI.WPF.Modern.Controls.SimpleStackPanel; var headerPanel = menuItem.Header as SimpleStackPanel;
if (headerPanel != null) if (headerPanel != null)
{ {
var textBlock = headerPanel.Children[0] as TextBlock; var textBlock = headerPanel.Children[0] as TextBlock;
@@ -164,7 +164,7 @@ namespace Ink_Canvas
// 创建新的位图,避免Clone的问题 // 创建新的位图,避免Clone的问题
var clonedFrame = new Bitmap(frame.Width, frame.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); var clonedFrame = new Bitmap(frame.Width, frame.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
using (var graphics = System.Drawing.Graphics.FromImage(clonedFrame)) using (var graphics = Graphics.FromImage(clonedFrame))
{ {
graphics.DrawImage(frame, 0, 0); graphics.DrawImage(frame, 0, 0);
} }
@@ -224,20 +224,20 @@ namespace Ink_Canvas
try try
{ {
// 根据像素格式选择合适的WPF像素格式 // 根据像素格式选择合适的WPF像素格式
System.Windows.Media.PixelFormat wpfPixelFormat; PixelFormat wpfPixelFormat;
switch (bitmap.PixelFormat) switch (bitmap.PixelFormat)
{ {
case System.Drawing.Imaging.PixelFormat.Format24bppRgb: case System.Drawing.Imaging.PixelFormat.Format24bppRgb:
wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr24; wpfPixelFormat = PixelFormats.Bgr24;
break; break;
case System.Drawing.Imaging.PixelFormat.Format32bppArgb: case System.Drawing.Imaging.PixelFormat.Format32bppArgb:
wpfPixelFormat = System.Windows.Media.PixelFormats.Bgra32; wpfPixelFormat = PixelFormats.Bgra32;
break; break;
case System.Drawing.Imaging.PixelFormat.Format32bppRgb: case System.Drawing.Imaging.PixelFormat.Format32bppRgb:
wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr32; wpfPixelFormat = PixelFormats.Bgr32;
break; break;
default: default:
wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr24; wpfPixelFormat = PixelFormats.Bgr24;
break; break;
} }