C# 另一进程正在使用映像文件副本
我正在尝试创建一个用户perfil编辑窗口,该窗口中有一个图像控件C# 另一进程正在使用映像文件副本,c#,wpf,image,file,process,C#,Wpf,Image,File,Process,我正在尝试创建一个用户perfil编辑窗口,该窗口中有一个图像控件 当我选择一个图像文件时,它将显示在此图像控件中,并将此文件复制到我的图像文件夹中,第一次可以,但第二次显示错误 “进程无法访问文件'C:\1.jpg',因为另一个进程正在使用它。” 我想这是因为我的图像控件正在使用这个文件,所以,我不知道我能做什么 private void Select_Click(object sender, RoutedEventArgs e) { OpenFileDialog od = new O
当我选择一个图像文件时,它将显示在此图像控件中,并将此文件复制到我的图像文件夹中,第一次可以,但第二次显示错误 “进程无法访问文件'C:\1.jpg',因为另一个进程正在使用它。” 我想这是因为我的图像控件正在使用这个文件,所以,我不知道我能做什么
private void Select_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog od = new OpenFileDialog();
if (od.ShowDialog() == true)
{
string imageLocal = @"C:/1.jpg";
File.Copy(od.FileName, imageLocal, true);
image1.Source = new BitmapImage(new Uri(imageLocal));
}
}
如果要加载和显示图像,并使文件适合文件系统中的操作(如重新加载或将其移动到另一个目录),Uri构造函数将无法工作,因为(如您所指出的)BitmapImage类挂起文件句柄 相反,使用这样的方法
private static BitmapImage ByStream(FileInfo info)
{ //http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/dee7cb68-aca3-402b-b159-2de933f933f1
try
{
if (info.Exists)
{
// do this so that the image file can be moved in the file system
BitmapImage result = new BitmapImage();
// Create new BitmapImage
Stream stream = new MemoryStream(); // Create new MemoryStream
Bitmap bitmap = new Bitmap(info.FullName);
// Create new Bitmap (System.Drawing.Bitmap) from the existing image file
(albumArtSource set to its path name)
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
// Save the loaded Bitmap into the MemoryStream - Png format was the only one I
tried that didn't cause an error (tried Jpg, Bmp, MemoryBmp)
bitmap.Dispose(); // Dispose bitmap so it releases the source image file
result.BeginInit(); // Begin the BitmapImage's initialisation
result.StreamSource = stream;
// Set the BitmapImage's StreamSource to the MemoryStream containing the image
result.EndInit(); // End the BitmapImage's initialisation
return result; // Finally, set the WPF Image component's source to the
BitmapImage
}
return null;
}
catch
{
return null;
}
}
此方法获取FileInfo并返回BitmapImage,您可以显示它,同时将其移动到另一个目录或再次显示
从下面的另一个答案复制过来的一个更简单的方法是:
public static BitmapImage LoadBitmapImage(string fileName)
{
using (var stream = new FileStream(fileName, FileMode.Open))
{
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = stream;
bitmapImage.EndInit();
bitmapImage.Freeze();
return bitmapImage;
}
}
下面显示的方法从文件加载BitmapImage,并在加载后立即关闭该文件。请注意,当源流在
EndInit
之后立即关闭时,有必要设置BitmapCacheOption.OnLoad
标志
public static BitmapImage LoadBitmapImage(string fileName)
{
using (var stream = new FileStream(fileName, FileMode.Open))
{
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = stream;
bitmapImage.EndInit();
bitmapImage.Freeze(); // just in case you want to load the image in another thread
return bitmapImage;
}
}
此代码适用于WPF支持的任何图像格式。将图像文件内容作为流传递到StreamSource
属性时,WPF将自动创建相应的解码器。非常简单的解决方案:
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
File.Copy(od.FileName, imageLocal, true);
这里的问题在于如何加载文件并将其转换为图像。使用您正在使用的构造函数方法将不起作用。如果要避免“被另一个进程使用”异常,可以使用其他方法。我可以为解决程序解决此问题做些什么?我正在尝试打开JPG文件,我已编辑了此格式的代码;保存(流,ImageFormat.Jpeg)。但它将运行FileFormatException。“无法解码图像。图像标题可能已损坏。”请使用未损坏的文件尝试。是的,当我尝试ImageFormat.PNG和PNG文件时,没有问题,只是在使用JPEG时出现问题。对于任何JPEG或jpg文件,如果jpg文件未损坏,PNG编码器也适用于jpg文件。所有类型都精确地渲染到屏幕上。在核心问题上,你不会再遇到例外情况了?@Lai32290没有必要明确选择解码器。您只需将文件内容作为流传递给BitmapImage
StreamSource
属性。WPF将自动选择正确的解码器,如我的答案所示。此外,这里显示的解决方案涉及一个System.Drawing.Bitmap
,它不是WPF,而是WinForms。它将图像文件解码为位图
,然后将其编码回内存流,最后将其解码为位图图像。与直接将文件流解码为位图图像相比,这是非常低效的。