#0019 修复ProcessImageAsync 跨线程问题

This commit is contained in:
zhengxuan.zhang
2026-03-14 21:35:30 +08:00
parent d5f32bfadb
commit e89767d976
3 changed files with 25 additions and 2 deletions
+20
View File
@@ -10,6 +10,19 @@ namespace XplorePlane.Services
{
public static class ImageConverter
{
public static byte[] ExtractGray8Pixels(BitmapSource bitmapSource, out int width, out int height)
{
if (bitmapSource == null) throw new ArgumentNullException(nameof(bitmapSource));
var formatted = new FormatConvertedBitmap(bitmapSource, PixelFormats.Gray8, null, 0);
width = formatted.PixelWidth;
height = formatted.PixelHeight;
int stride = width;
byte[] pixels = new byte[height * stride];
formatted.CopyPixels(pixels, stride, 0);
return pixels;
}
public static Image<Gray, byte> ToEmguCV(BitmapSource bitmapSource)
{
if (bitmapSource == null) throw new ArgumentNullException(nameof(bitmapSource));
@@ -26,6 +39,13 @@ namespace XplorePlane.Services
return image;
}
public static Image<Gray, byte> ToEmguCVFromPixels(byte[] pixels, int width, int height)
{
var image = new Image<Gray, byte>(width, height);
image.Bytes = pixels;
return image;
}
public static BitmapSource ToBitmapSource(Image<Gray, byte> emguImage)
{
if (emguImage == null) throw new ArgumentNullException(nameof(emguImage));
@@ -99,13 +99,16 @@ namespace XplorePlane.Services
if (!_processorRegistry.TryGetValue(processorName, out var processor))
throw new ArgumentException($"Processor not registered: {processorName}", nameof(processorName));
// Extract pixels on the UI thread (BitmapSource / FormatConvertedBitmap are DependencyObjects)
var rawPixels = ImageConverter.ExtractGray8Pixels(source, out int imgWidth, out int imgHeight);
return await Task.Run(() =>
{
cancellationToken.ThrowIfCancellationRequested();
try
{
var emguImage = ImageConverter.ToEmguCV(source);
var emguImage = ImageConverter.ToEmguCVFromPixels(rawPixels, imgWidth, imgHeight);
if (parameters != null)
{
@@ -118,6 +121,7 @@ namespace XplorePlane.Services
progress?.Report(0.9);
var result = ImageConverter.ToBitmapSource(processedEmgu);
result.Freeze(); // must freeze before crossing thread boundary
progress?.Report(1.0);
return result;
@@ -111,7 +111,6 @@ namespace XplorePlane.ViewModels
try
{
SelectedProcessor = processorName;
var parameters = _imageProcessingService.GetProcessorParameters(processorName);
CurrentParameters.Clear();
foreach (var param in parameters)