improve:展台功能
This commit is contained in:
@@ -10540,7 +10540,7 @@
|
||||
</Border>
|
||||
|
||||
<!-- 底部按钮区域 -->
|
||||
<Grid Grid.Row="4" Height="Auto" Margin="0,0,0,6">
|
||||
<Grid Grid.Row="4" Margin="0,0,0,6">
|
||||
<WrapPanel
|
||||
Margin="10,5"
|
||||
HorizontalAlignment="Center"
|
||||
@@ -10563,14 +10563,14 @@
|
||||
Text="上屏" />
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
x:Name="CheckBoxEnablePhotoCorrection"
|
||||
x:Name="ToggleBtnPhotoCorrection"
|
||||
Height="40"
|
||||
Margin="3,0"
|
||||
Background="{DynamicResource FloatBarBackground}"
|
||||
BorderBrush="{DynamicResource FloatBarBorderBrush}"
|
||||
BorderThickness="1"
|
||||
Checked="CheckBoxEnablePhotoCorrection_Checked"
|
||||
Unchecked="CheckBoxEnablePhotoCorrection_Unchecked">
|
||||
Checked="ToggleBtnPhotoCorrection_Checked"
|
||||
Unchecked="ToggleBtnPhotoCorrection_Unchecked">
|
||||
<TextBlock
|
||||
FontSize="12"
|
||||
FontWeight="SemiBold"
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace Ink_Canvas
|
||||
private Bitmap _lastFrame;
|
||||
|
||||
private readonly List<CapturedImage> _capturedPhotos = new List<CapturedImage>();
|
||||
private const int MaxCapturedPhotos = 50; // 容量上限:比 UI 显示的 30 项多一些,避免频繁清理
|
||||
|
||||
// 按页绑定:每一页对应一个“实时画面”元素与布局/设备信息
|
||||
private readonly Dictionary<int, System.Windows.Controls.Image> _liveFrameImageByPage = new Dictionary<int, System.Windows.Controls.Image>();
|
||||
@@ -59,9 +60,9 @@ namespace Ink_Canvas
|
||||
if (BtnCapturePhoto != null) BtnCapturePhoto.IsEnabled = false;
|
||||
RefreshVideoPresenterDeviceList();
|
||||
|
||||
if (CheckBoxEnablePhotoCorrection != null)
|
||||
if (ToggleBtnPhotoCorrection != null)
|
||||
{
|
||||
CheckBoxEnablePhotoCorrection.IsChecked = Settings?.Automation?.IsEnablePhotoCorrection ?? false;
|
||||
ToggleBtnPhotoCorrection.IsChecked = Settings?.Automation?.IsEnablePhotoCorrection ?? false;
|
||||
}
|
||||
|
||||
// 同步“上屏”按钮状态(按页绑定)
|
||||
@@ -447,6 +448,13 @@ namespace Ink_Canvas
|
||||
{
|
||||
var ci = new CapturedImage(bmpImage);
|
||||
_capturedPhotos.Insert(0, ci);
|
||||
|
||||
while (_capturedPhotos.Count > MaxCapturedPhotos)
|
||||
{
|
||||
var oldPhoto = _capturedPhotos[_capturedPhotos.Count - 1];
|
||||
_capturedPhotos.RemoveAt(_capturedPhotos.Count - 1);
|
||||
}
|
||||
|
||||
UpdateCapturedPhotosDisplay();
|
||||
}));
|
||||
}
|
||||
@@ -476,14 +484,14 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckBoxEnablePhotoCorrection_Checked(object sender, RoutedEventArgs e)
|
||||
private void ToggleBtnPhotoCorrection_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (Settings?.Automation == null) return;
|
||||
Settings.Automation.IsEnablePhotoCorrection = true;
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void CheckBoxEnablePhotoCorrection_Unchecked(object sender, RoutedEventArgs e)
|
||||
private void ToggleBtnPhotoCorrection_Unchecked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (Settings?.Automation == null) return;
|
||||
Settings.Automation.IsEnablePhotoCorrection = false;
|
||||
|
||||
@@ -14,20 +14,28 @@ namespace Ink_Canvas.Models
|
||||
|
||||
public CapturedImage(BitmapImage image)
|
||||
{
|
||||
Image = image;
|
||||
Thumbnail = CreateThumbnail(image);
|
||||
if (image == null)
|
||||
throw new ArgumentNullException(nameof(image), "图像不能为空");
|
||||
|
||||
// 确保 Image 被冻结,避免跨线程访问风险
|
||||
Image = EnsureFrozen(image);
|
||||
Thumbnail = CreateThumbnail(Image);
|
||||
Strokes = new StrokeCollection();
|
||||
Timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
Timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
FilePath = null;
|
||||
}
|
||||
|
||||
public CapturedImage(BitmapImage image, string filePath)
|
||||
{
|
||||
Image = image;
|
||||
Thumbnail = CreateThumbnail(image);
|
||||
if (image == null)
|
||||
throw new ArgumentNullException(nameof(image), "图像不能为空");
|
||||
|
||||
// 确保 Image 被冻结,避免跨线程访问风险
|
||||
Image = EnsureFrozen(image);
|
||||
Thumbnail = CreateThumbnail(Image);
|
||||
Strokes = new StrokeCollection();
|
||||
FilePath = filePath;
|
||||
Timestamp = TryExtractTimestampFromFilePath(filePath) ?? DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
Timestamp = TryExtractTimestampFromFilePath(filePath) ?? DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
}
|
||||
|
||||
private static string TryExtractTimestampFromFilePath(string filePath)
|
||||
@@ -43,7 +51,7 @@ namespace Ink_Canvas.Models
|
||||
System.Globalization.DateTimeStyles.None,
|
||||
out var dt))
|
||||
{
|
||||
return dt.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
return dt.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
}
|
||||
if (name.Length >= 23)
|
||||
{
|
||||
@@ -55,7 +63,7 @@ namespace Ink_Canvas.Models
|
||||
System.Globalization.DateTimeStyles.None,
|
||||
out var dt2))
|
||||
{
|
||||
return dt2.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
return dt2.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -66,11 +74,53 @@ namespace Ink_Canvas.Models
|
||||
}
|
||||
}
|
||||
|
||||
private BitmapImage CreateThumbnail(BitmapImage original)
|
||||
private static BitmapImage EnsureFrozen(BitmapImage image)
|
||||
{
|
||||
if (image == null)
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
|
||||
if (image.IsFrozen)
|
||||
return image;
|
||||
|
||||
var encoder = new System.Windows.Media.Imaging.PngBitmapEncoder();
|
||||
encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(image));
|
||||
|
||||
var stream = new System.IO.MemoryStream();
|
||||
encoder.Save(stream);
|
||||
stream.Position = 0;
|
||||
|
||||
var frozenCopy = new BitmapImage();
|
||||
frozenCopy.BeginInit();
|
||||
frozenCopy.CacheOption = BitmapCacheOption.OnLoad;
|
||||
frozenCopy.StreamSource = stream;
|
||||
frozenCopy.EndInit();
|
||||
frozenCopy.Freeze();
|
||||
|
||||
return frozenCopy;
|
||||
}
|
||||
|
||||
private static BitmapImage CreateThumbnail(BitmapImage original)
|
||||
{
|
||||
if (original == null)
|
||||
throw new ArgumentNullException(nameof(original));
|
||||
|
||||
if (original.PixelWidth <= 0 || original.PixelHeight <= 0)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"图像尺寸无效:宽度={original.PixelWidth}, 高度={original.PixelHeight}。图像必须具有有效的像素尺寸。",
|
||||
nameof(original));
|
||||
}
|
||||
|
||||
double targetWidth = 290.0;
|
||||
double targetHeight = 180.0;
|
||||
double scale = Math.Min(targetWidth / original.PixelWidth, targetHeight / original.PixelHeight);
|
||||
|
||||
if (double.IsInfinity(scale) || double.IsNaN(scale) || scale <= 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"无法计算有效的缩放比例:scale={scale}, 图像尺寸={original.PixelWidth}x{original.PixelHeight}");
|
||||
}
|
||||
|
||||
var thumbnail = new TransformedBitmap(original, new System.Windows.Media.ScaleTransform(scale, scale));
|
||||
|
||||
var bmp = new JpegBitmapEncoder { QualityLevel = 85 };
|
||||
|
||||
Reference in New Issue
Block a user