5

我正在尝试创建一个用户 perfil 编辑窗口,在这个窗口中有一个图像控件
当我选择一个图像文件时,它将显示在这个图像控件中并将这个文件复制到我的图像文件夹中,第一次没问题,但第二次,它显示一个错误

“该进程无法访问文件 '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));
    }
}
4

3 回答 3

6

如果要加载和显示图像,并使文件适合文件系统中的操作(例如重新加载或将其移动到另一个目录),则 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;
    }
}
于 2013-08-10T23:50:15.130 回答
2

下面显示的方法从文件加载 BitmapImage 并在加载后立即关闭文件。请注意,BitmapCacheOption.OnLoad当源流在 之后立即关闭时,必须设置标志EndInit

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 将自动创建适当的解码器。

于 2013-08-11T05:38:02.150 回答
0

非常简单的解决方案:

System.GC.Collect();  
System.GC.WaitForPendingFinalizers();

File.Copy(od.FileName, imageLocal, true);
于 2014-10-20T18:53:23.093 回答