#0019 修复ProcessImageAsync 跨线程问题
This commit is contained in:
@@ -10,6 +10,19 @@ namespace XplorePlane.Services
|
|||||||
{
|
{
|
||||||
public static class ImageConverter
|
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)
|
public static Image<Gray, byte> ToEmguCV(BitmapSource bitmapSource)
|
||||||
{
|
{
|
||||||
if (bitmapSource == null) throw new ArgumentNullException(nameof(bitmapSource));
|
if (bitmapSource == null) throw new ArgumentNullException(nameof(bitmapSource));
|
||||||
@@ -26,6 +39,13 @@ namespace XplorePlane.Services
|
|||||||
return image;
|
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)
|
public static BitmapSource ToBitmapSource(Image<Gray, byte> emguImage)
|
||||||
{
|
{
|
||||||
if (emguImage == null) throw new ArgumentNullException(nameof(emguImage));
|
if (emguImage == null) throw new ArgumentNullException(nameof(emguImage));
|
||||||
|
|||||||
@@ -99,13 +99,16 @@ namespace XplorePlane.Services
|
|||||||
if (!_processorRegistry.TryGetValue(processorName, out var processor))
|
if (!_processorRegistry.TryGetValue(processorName, out var processor))
|
||||||
throw new ArgumentException($"Processor not registered: {processorName}", nameof(processorName));
|
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(() =>
|
return await Task.Run(() =>
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var emguImage = ImageConverter.ToEmguCV(source);
|
var emguImage = ImageConverter.ToEmguCVFromPixels(rawPixels, imgWidth, imgHeight);
|
||||||
|
|
||||||
if (parameters != null)
|
if (parameters != null)
|
||||||
{
|
{
|
||||||
@@ -118,6 +121,7 @@ namespace XplorePlane.Services
|
|||||||
progress?.Report(0.9);
|
progress?.Report(0.9);
|
||||||
|
|
||||||
var result = ImageConverter.ToBitmapSource(processedEmgu);
|
var result = ImageConverter.ToBitmapSource(processedEmgu);
|
||||||
|
result.Freeze(); // must freeze before crossing thread boundary
|
||||||
progress?.Report(1.0);
|
progress?.Report(1.0);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -111,7 +111,6 @@ namespace XplorePlane.ViewModels
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SelectedProcessor = processorName;
|
|
||||||
var parameters = _imageProcessingService.GetProcessorParameters(processorName);
|
var parameters = _imageProcessingService.GetProcessorParameters(processorName);
|
||||||
CurrentParameters.Clear();
|
CurrentParameters.Clear();
|
||||||
foreach (var param in parameters)
|
foreach (var param in parameters)
|
||||||
|
|||||||
Reference in New Issue
Block a user