我有这种方法从磁盘上的图像中获取缩略图:
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方法中,我确实将Image缩略图转换为BitmapImage,我确实尝试将SourceUri和BaseUri设置为:
new Uri(dialog.FileName);
但是当我调用imagenNueva.ToString()时,我没有得到有效的Uri。
答案 0 :(得分:2)
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位操作系统上运行。否则就是避免处理位图的理由。