解锁从位图对象生成的文件

本文关键字:文件 对象 位图 解锁 | 更新日期: 2023-09-27 18:24:22

我有一种从磁盘上的图像中获取缩略图的方法:

public static BitmapImage GetThumbnail()
{
    var dlg = new OpenFileDialog {Filter = "Imágenes|" + extensionesImagenes};
    var result = dlg.ShowDialog();
    if (result == true)
    {
        var tempFolder = Path.GetTempPath() + "MyTempFolder''";
        if (!Directory.Exists(tempFolder))
            Directory.CreateDirectory(tempFolder);
        using (var thumbnail = new Bitmap(170, 170))
        {
            using (var gr = Graphics.FromImage(thumbnail))
            {
                gr.SmoothingMode = SmoothingMode.HighQuality;
                gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
                gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
                gr.DrawImage(new Bitmap(dlg.FileName), new Rectangle(0, 0, 170, 170));
            }
            thumbnail.Save(tempFolder + "foto.jpg", ImageFormat.Jpeg);
        }
        return new BitmapImage(new Uri(tempFolder + "foto.jpg"));
    }
    return null;
}

如果我第一次运行它,没有问题。但当我第二次运行它时,我得到了"GDI+中发生了一般错误"异常,因为我的应用程序正在使用该文件。

根据用户所做的操作,可以多次调用该方法,并且应该覆盖该文件。事实上,如果文件在我第一次调用该方法时存在,它就会被成功覆盖。

该文件是由Bitmap类的Save()方法生成的,我没有使用任何流。

如何解锁文件?

TIA-

编辑

我不使用MemoryStream,因为我需要另一种方法中的文件:当用户调用GetThumbnail方法时,缩略图将显示在StackPanel中(缩略图是StackPanel的ImageSource。)

稍后,用户可以将WPF表单中显示的信息(包括图像)保存到数据库中,并且保存到数据库的方法需要从保存的图像中读取字节。

编辑2

在使用缩略图之前,我使用了这种方法:

public static BitmapImage GetImage()
{
    var dlg = new OpenFileDialog {Filter = "Imágenes|" + extensionesImagenes};
    var result = dlg.ShowDialog();
    return result == true ? new BitmapImage(new Uri(dlg.FileName)) : null;
}

一切正常。

现在我使用缩略图,MemoryStream的问题是我无法设置图像的Uri。

例如,我使用的是:

imagenNueva = InterfazUtil.GetImage(); // GetImage() is now GetThumbnail()
var rutaFoto = (imagenNueva != null) ? imagenNueva.ToString() : null;

字符串rutaFoto被传递给将信息保存到数据库的方法,该方法使用该变量从磁盘读取图像。

在GetThumbnail方法中,我确实将图像缩略图转换为BitmapImage,并尝试使用设置SourceUri和BaseUri

新的Uri(dialog.FileName);

但是当我调用imagenNueva.ToString()时,我没有得到有效的Uri。

解锁从位图对象生成的文件

 gr.DrawImage(new Bitmap(dlg.FileName), new Rectangle(0, 0, 170, 170));

使用这样的位图非常麻烦。它锁定了"dlg.FileName"文件,垃圾收集器需要一段时间才能释放它

 using (var bmp = new Bitmap(dlg.FileName)) {
     gr.DrawImage(bmp, new Rectangle(0, 0, 170, 170));
 }

现在,它在使用后立即被释放,这也释放了对文件的锁定。

顺便说一句,如果你使用MemoryStream,你可以完全避免写这样的代码。只需将图像保存到MemoryStream,这样您就不需要文件了。假设图像没有那么大,或者你可以指望在64位操作系统上运行。这不是避免处理位图的理由。