diff --git a/Ink Canvas/Helpers/CameraService.cs b/Ink Canvas/Helpers/CameraService.cs
index 9e18fb96..894fe496 100644
--- a/Ink Canvas/Helpers/CameraService.cs
+++ b/Ink Canvas/Helpers/CameraService.cs
@@ -154,51 +154,91 @@ namespace Ink_Canvas.Helpers
}
///
- /// 获取当前帧的Bitmap
- ///
- public Bitmap GetCurrentFrame()
- {
- lock (_frameLock)
- {
- return _currentFrame?.Clone() as Bitmap;
- }
- }
-
- ///
- /// 获取当前帧的BitmapSource(WPF格式)
+ /// 获取当前帧的BitmapSource(WPF格式),直接返回可用的WPF位图
///
public BitmapSource GetCurrentFrameAsBitmapSource()
{
lock (_frameLock)
{
if (_currentFrame == null)
+ {
+ LogHelper.WriteLogToFile("GetCurrentFrameAsBitmapSource: _currentFrame为null");
return null;
+ }
try
{
- using (var memory = new MemoryStream())
+ LogHelper.WriteLogToFile($"GetCurrentFrameAsBitmapSource: 开始处理帧,类型={_currentFrame.GetType().FullName}");
+ LogHelper.WriteLogToFile($"GetCurrentFrameAsBitmapSource: 帧HashCode={_currentFrame.GetHashCode()}");
+
+ // 验证当前帧的有效性
+ var width = _currentFrame.Width;
+ var height = _currentFrame.Height;
+ LogHelper.WriteLogToFile($"GetCurrentFrameAsBitmapSource: 当前帧尺寸={width}x{height}");
+
+ // 验证位图有效性
+ if (width <= 0 || height <= 0)
{
- _currentFrame.Save(memory, ImageFormat.Png);
- memory.Position = 0;
+ LogHelper.WriteLogToFile("当前帧无效: 尺寸为0", LogHelper.LogType.Warning);
+ return null;
+ }
- var bitmapImage = new BitmapImage();
- bitmapImage.BeginInit();
- bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
- bitmapImage.StreamSource = memory;
- bitmapImage.EndInit();
- bitmapImage.Freeze();
+ // 使用更安全的方法转换位图
+ var bitmapData = _currentFrame.LockBits(
+ new Rectangle(0, 0, width, height),
+ ImageLockMode.ReadOnly,
+ _currentFrame.PixelFormat);
- return bitmapImage;
+ try
+ {
+ // 根据像素格式选择合适的WPF像素格式
+ System.Windows.Media.PixelFormat wpfPixelFormat;
+ switch (_currentFrame.PixelFormat)
+ {
+ case PixelFormat.Format24bppRgb:
+ wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr24;
+ break;
+ case PixelFormat.Format32bppArgb:
+ wpfPixelFormat = System.Windows.Media.PixelFormats.Bgra32;
+ break;
+ case PixelFormat.Format32bppRgb:
+ wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr32;
+ break;
+ default:
+ wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr24;
+ break;
+ }
+
+ var bitmapSource = System.Windows.Media.Imaging.BitmapSource.Create(
+ bitmapData.Width,
+ bitmapData.Height,
+ _currentFrame.HorizontalResolution,
+ _currentFrame.VerticalResolution,
+ wpfPixelFormat,
+ null,
+ bitmapData.Scan0,
+ bitmapData.Stride * bitmapData.Height,
+ bitmapData.Stride);
+
+ bitmapSource.Freeze();
+ LogHelper.WriteLogToFile($"GetCurrentFrameAsBitmapSource: 成功创建BitmapSource");
+ return bitmapSource;
+ }
+ finally
+ {
+ _currentFrame.UnlockBits(bitmapData);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"转换帧为BitmapSource失败: {ex.Message}", LogHelper.LogType.Error);
+ LogHelper.WriteLogToFile($"异常详情: {ex}", LogHelper.LogType.Error);
return null;
}
}
}
+
///
/// 视频源新帧事件处理
///
@@ -206,13 +246,52 @@ namespace Ink_Canvas.Helpers
{
try
{
+ LogHelper.WriteLogToFile($"VideoSource_NewFrame: 接收到新帧");
+
lock (_frameLock)
{
// 释放之前的帧
_currentFrame?.Dispose();
- // 克隆新帧
- _currentFrame = eventArgs.Frame.Clone() as Bitmap;
+ // 创建新的位图,避免Clone的问题
+ var sourceFrame = eventArgs.Frame;
+ LogHelper.WriteLogToFile($"VideoSource_NewFrame: 源帧类型={sourceFrame?.GetType().FullName}");
+ LogHelper.WriteLogToFile($"VideoSource_NewFrame: 源帧HashCode={sourceFrame?.GetHashCode()}");
+
+ if (sourceFrame != null)
+ {
+ try
+ {
+ var width = sourceFrame.Width;
+ var height = sourceFrame.Height;
+ LogHelper.WriteLogToFile($"VideoSource_NewFrame: 源帧尺寸={width}x{height}");
+
+ if (width > 0 && height > 0)
+ {
+ _currentFrame = new Bitmap(width, height, PixelFormat.Format24bppRgb);
+ using (var graphics = Graphics.FromImage(_currentFrame))
+ {
+ graphics.DrawImage(sourceFrame, 0, 0);
+ }
+ LogHelper.WriteLogToFile($"VideoSource_NewFrame: 成功创建新帧,HashCode={_currentFrame.GetHashCode()}");
+ }
+ else
+ {
+ LogHelper.WriteLogToFile($"VideoSource_NewFrame: 源帧尺寸无效");
+ _currentFrame = null;
+ }
+ }
+ catch (Exception frameEx)
+ {
+ LogHelper.WriteLogToFile($"VideoSource_NewFrame: 处理源帧失败: {frameEx.Message}", LogHelper.LogType.Error);
+ _currentFrame = null;
+ }
+ }
+ else
+ {
+ LogHelper.WriteLogToFile($"VideoSource_NewFrame: 源帧为null");
+ _currentFrame = null;
+ }
}
// 在UI线程中触发事件
diff --git a/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs b/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs
index 2848ae09..b7352fa1 100644
--- a/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs
+++ b/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs
@@ -28,12 +28,14 @@ namespace Ink_Canvas
public Rectangle Area;
public List Path;
public Bitmap CameraImage;
+ public System.Windows.Media.Imaging.BitmapSource CameraBitmapSource;
- public ScreenshotResult(Rectangle area, List path = null, Bitmap cameraImage = null)
+ public ScreenshotResult(Rectangle area, List path = null, Bitmap cameraImage = null, System.Windows.Media.Imaging.BitmapSource cameraBitmapSource = null)
{
Area = area;
Path = path;
CameraImage = cameraImage;
+ CameraBitmapSource = cameraBitmapSource;
}
}
@@ -60,9 +62,14 @@ namespace Ink_Canvas
if (screenshotResult.HasValue)
{
// 检查是否是摄像头截图
- if (screenshotResult.Value.CameraImage != null)
+ if (screenshotResult.Value.CameraBitmapSource != null)
{
- // 摄像头截图
+ // 摄像头截图(使用BitmapSource)
+ await InsertBitmapSourceToCanvas(screenshotResult.Value.CameraBitmapSource);
+ }
+ else if (screenshotResult.Value.CameraImage != null)
+ {
+ // 摄像头截图(使用Bitmap)
await InsertScreenshotToCanvas(screenshotResult.Value.CameraImage);
}
else if (screenshotResult.Value.Area.Width > 0 && screenshotResult.Value.Area.Height > 0)
@@ -164,7 +171,16 @@ namespace Ink_Canvas
if (selectorWindow.ShowDialog() == true)
{
// 检查是否是摄像头截图
- if (selectorWindow.CameraImage != null)
+ if (selectorWindow.CameraBitmapSource != null)
+ {
+ result = new ScreenshotResult(
+ Rectangle.Empty, // 摄像头截图不需要区域
+ null, // 摄像头截图不需要路径
+ null, // 不再使用Bitmap
+ selectorWindow.CameraBitmapSource // 摄像头BitmapSource
+ );
+ }
+ else if (selectorWindow.CameraImage != null)
{
result = new ScreenshotResult(
Rectangle.Empty, // 摄像头截图不需要区域
@@ -236,8 +252,40 @@ namespace Ink_Canvas
{
try
{
+ // 验证位图有效性
+ if (bitmap == null)
+ {
+ ShowNotification("截图数据无效");
+ return;
+ }
+
+ // 添加详细的位图调试信息
+ LogHelper.WriteLogToFile($"InsertScreenshotToCanvas: 开始处理位图");
+ LogHelper.WriteLogToFile($"位图对象类型: {bitmap.GetType().FullName}");
+ LogHelper.WriteLogToFile($"位图对象HashCode: {bitmap.GetHashCode()}");
+
+ // 检查位图是否已被释放
+ try
+ {
+ var testWidth = bitmap.Width;
+ var testHeight = bitmap.Height;
+ LogHelper.WriteLogToFile($"位图尺寸验证成功: {testWidth}x{testHeight}");
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"位图验证失败: {ex.Message}", LogHelper.LogType.Error);
+ ShowNotification("截图数据已损坏");
+ return;
+ }
+
// 将Bitmap转换为WPF BitmapSource
var bitmapSource = ConvertBitmapToBitmapSource(bitmap);
+
+ if (bitmapSource == null)
+ {
+ ShowNotification("转换截图失败");
+ return;
+ }
// 创建WPF Image控件
var image = new Image
@@ -293,6 +341,67 @@ namespace Ink_Canvas
}
}
+ // 将BitmapSource插入到画布(用于摄像头截图)
+ private async Task InsertBitmapSourceToCanvas(System.Windows.Media.Imaging.BitmapSource bitmapSource)
+ {
+ try
+ {
+ LogHelper.WriteLogToFile($"InsertBitmapSourceToCanvas: 开始处理BitmapSource");
+
+ // 创建WPF Image控件
+ var image = new Image
+ {
+ Source = bitmapSource,
+ Stretch = Stretch.Uniform
+ };
+ RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.HighQuality);
+
+ // 生成唯一名称
+ string timestamp = "camera_" + DateTime.Now.ToString("yyyyMMdd_HH_mm_ss_fff");
+ image.Name = timestamp;
+
+ // 初始化TransformGroup
+ InitializeScreenshotTransform(image);
+
+ // 设置截图属性,避免被InkCanvas选择系统处理
+ image.IsHitTestVisible = true;
+ image.Focusable = false;
+
+ // 初始化InkCanvas选择设置
+ InitializeInkCanvasSelectionSettings();
+
+ // 等待图片加载完成后再进行居中处理
+ image.Loaded += (sender, e) =>
+ {
+ // 确保在UI线程中执行
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ CenterAndScaleScreenshot(image);
+ // 绑定事件处理器
+ BindScreenshotEvents(image);
+ }), DispatcherPriority.Loaded);
+ };
+
+ // 添加到画布
+ inkCanvas.Children.Add(image);
+
+ // 提交历史记录
+ timeMachine.CommitElementInsertHistory(image);
+
+ // 插入图片后切换到选择模式并刷新浮动栏高光显示
+ SetCurrentToolMode(InkCanvasEditingMode.Select);
+ UpdateCurrentToolMode("select");
+ HideSubPanels("select");
+
+ ShowNotification("摄像头截图已插入到画布");
+ }
+ catch (Exception ex)
+ {
+ ShowNotification($"插入摄像头截图失败: {ex.Message}");
+ LogHelper.WriteLogToFile($"插入摄像头截图失败: {ex.Message}", LogHelper.LogType.Error);
+ }
+ }
+
// 初始化截图的TransformGroup
private void InitializeScreenshotTransform(Image image)
{
@@ -501,24 +610,235 @@ namespace Ink_Canvas
{
try
{
- using (var memory = new MemoryStream())
+ // 验证位图有效性
+ if (bitmap == null)
{
- bitmap.Save(memory, ImageFormat.Png);
- memory.Position = 0;
+ LogHelper.WriteLogToFile("位图无效: 位图为null", LogHelper.LogType.Warning);
+ return null;
+ }
- var bitmapImage = new BitmapImage();
- bitmapImage.BeginInit();
- bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
- bitmapImage.StreamSource = memory;
- bitmapImage.EndInit();
- bitmapImage.Freeze();
+ // 尝试访问位图属性,如果失败说明位图已损坏
+ int width, height;
+ try
+ {
+ width = bitmap.Width;
+ height = bitmap.Height;
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"位图已损坏,无法访问属性: {ex.Message}", LogHelper.LogType.Error);
+ return null;
+ }
- return bitmapImage;
+ if (width <= 0 || height <= 0)
+ {
+ LogHelper.WriteLogToFile($"位图无效: 尺寸为{width}x{height}", LogHelper.LogType.Warning);
+ return null;
+ }
+
+ LogHelper.WriteLogToFile($"开始转换位图: 尺寸={width}x{height}, 格式={bitmap.PixelFormat}, DPI={bitmap.HorizontalResolution}x{bitmap.VerticalResolution}");
+
+ // 使用更安全的方法转换位图
+ var bitmapData = bitmap.LockBits(
+ new Rectangle(0, 0, bitmap.Width, bitmap.Height),
+ ImageLockMode.ReadOnly,
+ bitmap.PixelFormat);
+
+ try
+ {
+ LogHelper.WriteLogToFile($"LockBits成功: Stride={bitmapData.Stride}, Scan0={bitmapData.Scan0}");
+
+ // 根据像素格式选择合适的WPF像素格式
+ System.Windows.Media.PixelFormat wpfPixelFormat;
+ switch (bitmap.PixelFormat)
+ {
+ case PixelFormat.Format24bppRgb:
+ wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr24;
+ LogHelper.WriteLogToFile("使用Bgr24像素格式");
+ break;
+ case PixelFormat.Format32bppArgb:
+ wpfPixelFormat = System.Windows.Media.PixelFormats.Bgra32;
+ LogHelper.WriteLogToFile("使用Bgra32像素格式");
+ break;
+ case PixelFormat.Format32bppRgb:
+ wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr32;
+ LogHelper.WriteLogToFile("使用Bgr32像素格式");
+ break;
+ default:
+ // 默认使用Bgr24,如果格式不匹配则转换
+ wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr24;
+ LogHelper.WriteLogToFile($"未知像素格式{bitmap.PixelFormat},使用默认Bgr24");
+ break;
+ }
+
+ var bitmapSource = System.Windows.Media.Imaging.BitmapSource.Create(
+ bitmapData.Width,
+ bitmapData.Height,
+ bitmap.HorizontalResolution,
+ bitmap.VerticalResolution,
+ wpfPixelFormat,
+ null,
+ bitmapData.Scan0,
+ bitmapData.Stride * bitmapData.Height,
+ bitmapData.Stride);
+
+ bitmapSource.Freeze();
+ LogHelper.WriteLogToFile("位图转换成功");
+ return bitmapSource;
+ }
+ finally
+ {
+ bitmap.UnlockBits(bitmapData);
}
}
catch (Exception ex)
{
- LogHelper.WriteLogToFile($"转换位图失败: {ex.Message}", LogHelper.LogType.Error);
+ LogHelper.WriteLogToFile($"直接转换位图失败: {ex.Message}", LogHelper.LogType.Error);
+ LogHelper.WriteLogToFile($"异常详情: {ex}", LogHelper.LogType.Error);
+
+ // 尝试使用备用方法:内存流转换
+ try
+ {
+ LogHelper.WriteLogToFile("尝试使用内存流方式转换位图", LogHelper.LogType.Info);
+ return ConvertBitmapToBitmapSourceFallback(bitmap);
+ }
+ catch (Exception fallbackEx)
+ {
+ LogHelper.WriteLogToFile($"备用转换方法也失败: {fallbackEx.Message}", LogHelper.LogType.Error);
+ LogHelper.WriteLogToFile($"备用方法异常详情: {fallbackEx}", LogHelper.LogType.Error);
+
+ // 最后尝试:使用最简单的转换方法
+ try
+ {
+ LogHelper.WriteLogToFile("尝试最简单的转换方法", LogHelper.LogType.Info);
+ return ConvertBitmapToBitmapSourceSimple(bitmap);
+ }
+ catch (Exception simpleEx)
+ {
+ LogHelper.WriteLogToFile($"简单转换方法也失败: {simpleEx.Message}", LogHelper.LogType.Error);
+ throw;
+ }
+ }
+ }
+ }
+
+ // 备用的位图转换方法(使用内存流)
+ private BitmapSource ConvertBitmapToBitmapSourceFallback(Bitmap bitmap)
+ {
+ try
+ {
+ LogHelper.WriteLogToFile("开始备用转换方法");
+
+ // 验证位图有效性
+ if (bitmap == null)
+ {
+ LogHelper.WriteLogToFile("备用方法:位图为null", LogHelper.LogType.Warning);
+ return null;
+ }
+
+ if (bitmap.Width <= 0 || bitmap.Height <= 0)
+ {
+ LogHelper.WriteLogToFile($"备用方法:位图尺寸无效 {bitmap.Width}x{bitmap.Height}", LogHelper.LogType.Warning);
+ return null;
+ }
+
+ LogHelper.WriteLogToFile($"备用方法:位图尺寸={bitmap.Width}x{bitmap.Height}, 格式={bitmap.PixelFormat}");
+
+ // 创建一个新的位图,确保格式正确
+ using (var convertedBitmap = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format24bppRgb))
+ {
+ LogHelper.WriteLogToFile("创建转换位图成功");
+
+ using (var graphics = Graphics.FromImage(convertedBitmap))
+ {
+ LogHelper.WriteLogToFile("开始绘制到转换位图");
+ graphics.DrawImage(bitmap, 0, 0);
+ LogHelper.WriteLogToFile("绘制完成");
+ }
+
+ using (var memory = new MemoryStream())
+ {
+ LogHelper.WriteLogToFile("开始保存到内存流");
+ convertedBitmap.Save(memory, ImageFormat.Png);
+ LogHelper.WriteLogToFile($"保存完成,内存流大小={memory.Length}");
+
+ memory.Position = 0;
+
+ var bitmapImage = new BitmapImage();
+ bitmapImage.BeginInit();
+ bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
+ bitmapImage.StreamSource = memory;
+ bitmapImage.EndInit();
+ bitmapImage.Freeze();
+
+ LogHelper.WriteLogToFile("备用转换方法成功");
+ return bitmapImage;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"备用转换方法失败: {ex.Message}", LogHelper.LogType.Error);
+ LogHelper.WriteLogToFile($"备用方法异常详情: {ex}", LogHelper.LogType.Error);
+ throw;
+ }
+ }
+
+ // 最简单的位图转换方法
+ private BitmapSource ConvertBitmapToBitmapSourceSimple(Bitmap bitmap)
+ {
+ try
+ {
+ LogHelper.WriteLogToFile("开始简单转换方法");
+
+ if (bitmap == null)
+ {
+ LogHelper.WriteLogToFile("简单方法:位图为null", LogHelper.LogType.Warning);
+ return null;
+ }
+
+ LogHelper.WriteLogToFile($"简单方法:位图尺寸={bitmap.Width}x{bitmap.Height}");
+
+ // 使用最基础的方法:直接保存为PNG然后加载
+ var tempFile = System.IO.Path.GetTempFileName() + ".png";
+
+ try
+ {
+ LogHelper.WriteLogToFile($"保存临时文件到: {tempFile}");
+ bitmap.Save(tempFile, ImageFormat.Png);
+
+ LogHelper.WriteLogToFile("开始加载临时文件");
+ var bitmapImage = new BitmapImage();
+ bitmapImage.BeginInit();
+ bitmapImage.UriSource = new Uri(tempFile);
+ bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
+ bitmapImage.EndInit();
+ bitmapImage.Freeze();
+
+ LogHelper.WriteLogToFile("简单转换方法成功");
+ return bitmapImage;
+ }
+ finally
+ {
+ // 清理临时文件
+ try
+ {
+ if (System.IO.File.Exists(tempFile))
+ {
+ System.IO.File.Delete(tempFile);
+ LogHelper.WriteLogToFile("临时文件已删除");
+ }
+ }
+ catch (Exception deleteEx)
+ {
+ LogHelper.WriteLogToFile($"删除临时文件失败: {deleteEx.Message}", LogHelper.LogType.Warning);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"简单转换方法失败: {ex.Message}", LogHelper.LogType.Error);
+ LogHelper.WriteLogToFile($"简单方法异常详情: {ex}", LogHelper.LogType.Error);
throw;
}
}
diff --git a/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml.cs b/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml.cs
index 57bd9f8b..7f2f6c72 100644
--- a/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml.cs
+++ b/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml.cs
@@ -49,6 +49,7 @@ namespace Ink_Canvas
public DrawingRectangle? SelectedArea { get; private set; }
public List SelectedPath { get; private set; }
public Bitmap CameraImage { get; private set; }
+ public System.Windows.Media.Imaging.BitmapSource CameraBitmapSource { get; private set; }
public ScreenshotSelectorWindow()
{
@@ -156,18 +157,35 @@ namespace Ink_Canvas
{
if (_isCameraMode && CameraPreviewImage != null && frame != null)
{
- // 克隆帧以避免在转换过程中被释放
- using (var clonedFrame = frame.Clone() as Bitmap)
+ try
{
- if (clonedFrame != null)
+ // 验证帧的有效性
+ if (frame.Width <= 0 || frame.Height <= 0)
{
- var bitmapSource = ConvertBitmapToBitmapSource(clonedFrame);
- if (bitmapSource != null)
- {
- CameraPreviewImage.Source = bitmapSource;
- CameraStatusText.Text = "摄像头已连接";
- }
+ LogHelper.WriteLogToFile($"无效的摄像头帧: {frame.Width}x{frame.Height}", LogHelper.LogType.Warning);
+ return;
}
+
+ // 创建新的位图,避免Clone的问题
+ var clonedFrame = new Bitmap(frame.Width, frame.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
+ using (var graphics = System.Drawing.Graphics.FromImage(clonedFrame))
+ {
+ graphics.DrawImage(frame, 0, 0);
+ }
+
+ var bitmapSource = ConvertBitmapToBitmapSource(clonedFrame);
+ if (bitmapSource != null)
+ {
+ CameraPreviewImage.Source = bitmapSource;
+ CameraStatusText.Text = "摄像头已连接";
+ }
+
+ // 释放临时位图
+ clonedFrame.Dispose();
+ }
+ catch (Exception frameEx)
+ {
+ LogHelper.WriteLogToFile($"处理摄像头帧时出错: {frameEx.Message}", LogHelper.LogType.Error);
}
}
}));
@@ -197,19 +215,57 @@ namespace Ink_Canvas
{
try
{
- using (var memory = new System.IO.MemoryStream())
+ // 验证位图有效性
+ if (bitmap == null || bitmap.Width <= 0 || bitmap.Height <= 0)
{
- bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
- memory.Position = 0;
+ LogHelper.WriteLogToFile("位图无效: 空位图或尺寸为0", LogHelper.LogType.Warning);
+ return null;
+ }
- var bitmapImage = new System.Windows.Media.Imaging.BitmapImage();
- bitmapImage.BeginInit();
- bitmapImage.CacheOption = System.Windows.Media.Imaging.BitmapCacheOption.OnLoad;
- bitmapImage.StreamSource = memory;
- bitmapImage.EndInit();
- bitmapImage.Freeze();
+ // 使用更安全的方法转换位图
+ var bitmapData = bitmap.LockBits(
+ new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
+ System.Drawing.Imaging.ImageLockMode.ReadOnly,
+ bitmap.PixelFormat);
- return bitmapImage;
+ try
+ {
+ // 根据像素格式选择合适的WPF像素格式
+ System.Windows.Media.PixelFormat wpfPixelFormat;
+ switch (bitmap.PixelFormat)
+ {
+ case System.Drawing.Imaging.PixelFormat.Format24bppRgb:
+ wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr24;
+ break;
+ case System.Drawing.Imaging.PixelFormat.Format32bppArgb:
+ wpfPixelFormat = System.Windows.Media.PixelFormats.Bgra32;
+ break;
+ case System.Drawing.Imaging.PixelFormat.Format32bppRgb:
+ wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr32;
+ break;
+ default:
+ // 默认使用Bgr24,如果格式不匹配则转换
+ wpfPixelFormat = System.Windows.Media.PixelFormats.Bgr24;
+ break;
+ }
+
+ var bitmapSource = System.Windows.Media.Imaging.BitmapSource.Create(
+ bitmapData.Width,
+ bitmapData.Height,
+ bitmap.HorizontalResolution,
+ bitmap.VerticalResolution,
+ wpfPixelFormat,
+ null,
+ bitmapData.Scan0,
+ bitmapData.Stride * bitmapData.Height,
+ bitmapData.Stride);
+
+ bitmapSource.Freeze();
+ return bitmapSource;
+ }
+ finally
+ {
+ bitmap.UnlockBits(bitmapData);
}
}
catch (Exception ex)
@@ -430,12 +486,12 @@ namespace Ink_Canvas
{
if (_cameraService != null && _cameraService.IsCapturing)
{
- // 获取当前帧
- var currentFrame = _cameraService.GetCurrentFrame();
- if (currentFrame != null)
+ // 直接获取BitmapSource,避免Bitmap传递问题
+ var bitmapSource = _cameraService.GetCurrentFrameAsBitmapSource();
+ if (bitmapSource != null)
{
- // 保存摄像头图像
- CameraImage = currentFrame.Clone() as Bitmap;
+ // 保存BitmapSource而不是Bitmap
+ CameraBitmapSource = bitmapSource;
// 停止摄像头预览
_cameraService.StopPreview();