我正在做一个指纹图像处理的简单项目。
我正在尝试在处理过程中使用线程,以便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;
}
}
答案 0 :(得分:0)
您可以在将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);
}
这也意味着您无需将BitmapImage
转换为Bitmap
内的BackgroundWorker
:
// 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);
}