gpt4 book ai didi

c# - 如何将图像更新到不同的线程?

转载 作者:太空宇宙 更新时间:2023-11-03 15:53:16 24 4
gpt4 key购买 nike

我正在做一个简单的指纹图像处理项目。

我正在尝试在处理部分使用线程,以便 UI 保持流畅。

当我在尝试处理直方图均衡时尝试显示指纹图像时,我收到一个错误,提示该图像仍在被另一个线程使用。

我一直在尝试查找解决方案,比如使用 Freeze() 方法,但我不知道该把它放在哪里。

这是我的代码。

private void btnLoadImage_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openImg = new OpenFileDialog();
openImg.FileName = "Fingerprint Image";
openImg.DefaultExt = ".tif" ;
openImg.Filter = "Image File (*.tif)|*.tif*|" +
"JPEG Files (*.jpg, *.jpeg)|*.jpeg, *.jpeg|" +
"PNG Files (*.png)|*.png";

Nullable<bool> result = openImg.ShowDialog();

if (result == true)
{
imgDisp.Source = new BitmapImage(new Uri(openImg.FileName));
}
}

private void btnGenKey_Click(object sender, RoutedEventArgs e)
{
if (imgDisp.Source == null)
{
MessageBox.Show("Upload Image First!");
}
else
{
imgDisp.Source.Freeze();
BackgroundWorker doImg = new BackgroundWorker();
doImg.DoWork += new DoWorkEventHandler(doImg_DoWork);
doImg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(doImg_RunWorkerCompleted);
doImg.RunWorkerAsync(imgDisp.Source);
}
}

void doImg_DoWork(object sender, DoWorkEventArgs e)
{
ImageProcessor.BasicImgPro bip = new ImageProcessor.BasicImgPro();
BitmapImage srcImg = (BitmapImage)imgDisp.Source;
using (MemoryStream outImg = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(srcImg));
enc.Save(outImg);
Bitmap newBitmap = new Bitmap(outImg);
Bitmap he = bip.HistoEqualize(newBitmap);
using (var memory = new MemoryStream())
{
he.Save(memory, ImageFormat.Png);
memory.Position = 0;

var displayImg = new BitmapImage();
displayImg.BeginInit();
displayImg.StreamSource = memory;
displayImg.CacheOption = BitmapCacheOption.OnLoad;
displayImg.EndInit();
e.Result = displayImg;
}
}
}

void doImg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else
{
imgDisp.Source = (ImageSource)e.Result;
}
}

最佳答案

您可以在将 BitmapImage 传递给 worker 之前克隆它,但是使用普通的 Image(即 Bitmap)会更简单) 进行处理(因为这是图像处理库使用的),并保留 BitmapImage 仅用于 WPF 显示:

private void btnLoadImage_Click(object sender, RoutedEventArgs e)
{
using (var openImg = new OpenFileDialog())
{
...

if (openImg.ShowDialog() == DialogResult.Ok)
LoadImage(openImg.FileName);
}
}

private Bitmap _bitmap;
void LoadImage(string uri)
{
// use a BitmapImage for display
imgDisp.Source = new BitmapImage(new Uri(openImg.FileName));

// use a Bitmap for processing
_bitmap = new Bitmap(openImg.FileName);
}

这也意味着您不需要在 BackgroundWorker 中将 BitmapImage 转换为 Bitmap:

// simply pass the bitmap instance to the worker
doImg.RunWorkerAsync(_bitmap);

// worker method gets simplified a bit
void doImg_DoWork(object sender, DoWorkEventArgs e)
{
var bip = new ImageProcessor.BasicImgPro();
var bitmap = (Bitmap)e.Argument;
var result = bip.HistoEqualize(bitmap);
e.Result = result;
}

// convert to an image source when done
void doImg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
return;
}

imgDisp.Source = ConvertBitmapToImageSource((Bitmap)e.Result);
}

关于c# - 如何将图像更新到不同的线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24901434/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com