问题描述
我正在尝试在Winforms应用程序中显示各种文件类型(包括动画.gif 文件)的图像.我还必须能够修改显示的文件.(更改文件名,将其删除).
I'm trying to display images of various file types (including animated .gif files) in my Winforms application. I also have to be able to modify the files that are shown. (change the file name, delete them).
问题是图片盒在使用应用程序时会锁定图像文件,直到关闭应用程序为止.正常方式.
这意味着我不能这样做:
That means I can't do this:
private void Form1_Load(object sender, EventArgs e)
{
PictureBox pic = new PictureBox();
pic.Size = new Size(250, 250);
pic.Image = Image.FromFile("someImage.gif");
this.Controls.Add(pic);
//No use to call pic.Image = null or .Dispose of it
File.Delete("someImage.gif"); //throws exception
}
上面的链接中的解决方法如下:
The workaround in the link above is as follows:
private void Form1_Load2(object sender, EventArgs e)
{
PictureBox pic = new PictureBox();
pic.Size = new Size(250, 250);
//using a FileStream
var fs = new System.IO.FileStream("someImage.gif", System.IO.FileMode.Open, System.IO.FileAccess.Read);
pic.Image = System.Drawing.Image.FromStream(fs);
fs.Close();
this.Controls.Add(pic);
pic.MouseClick += pic_MouseClick;
}
对于正常的图像类型来说效果很好,但是不会加载动画的.gifs,这对我很重要.尝试加载一个将使其看起来像此.
That works fine for normal image types, but it won't load animated .gifs, which is important to me. Trying to load one will make it look like this.
我发现了其他一些相关主题(这个和这个),但它们都是关于WPF的,并使用BitmapImage.我已经搜索过有关如何在Winforms应用程序中使用BitmapImage的信息,但是没有发现任何可以正常工作的东西.
I've found a few other topics about it (this and this) but they're all about WPF and use BitmapImage. I've searched about how to use BitmapImage in a Winforms application, but haven't found anything apart from that it is supposed to somehow work.
我想继续使用Winforms,因为我已经习惯了,但这不是必须的.
I would like to stay with Winforms because I'm just getting used to it, but that's not a necessity.
总结一下:我需要一种方法来显示常见的图像类型(png,jpg,bmp和gif动画),同时仍然能够在HDD上修改文件.如果这意味着卸载->修改->重新加载文件,则可以.我更喜欢Winforms,但其他框架可以.
感谢您的帮助.
我尝试过的另一种方式
using (System.IO.FileStream fs = new System.IO.FileStream("E:\\Pics\\small.gif", System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
fs.CopyTo(ms);
pic.Image = Image.FromStream(ms);
}
但是显示出与第二个示例相同的问题.gif无法加载.
But shows the same problem as the second example. The gif doesn't load.
推荐答案
使用MemoryStream确实是避免文件锁定的正确方法.首先,这是一个强大的优化,它是由内存映射文件创建的锁,Image类使用该内存映射文件将像素数据保留在页面文件之外.当位图很大时,这很重要.希望不要在动画gif上使用:)
Using a MemoryStream is indeed the right way to avoid the file lock. Which is a strong optimization btw, the lock is created by the memory-mapped file that the Image class uses to keep the pixel data out of the paging file. That matters a great deal when the bitmap is large. Hopefully not on an animated gif :)
您的代码段中有一个小错误,您忘记将流重置为数据的开头.修复:
A small mistake in your code snippet, you forgot to reset the stream back to the start of the data. Fix:
using (var fs = new System.IO.FileStream(...)) {
var ms = new System.IO.MemoryStream();
fs.CopyTo(ms);
ms.Position = 0; // <=== here
if (pic.Image != null) pic.Image.Dispose();
pic.Image = Image.FromStream(ms);
}
如果需要这样说:不处理内存流.这会导致以后很难诊断随机崩溃,而懒惰地读取像素数据.
In case it needs to be said: do not dispose the memory stream. That causes very hard to diagnose random crashes later, pixel data is read lazily.
这篇关于在Winforms中显示动画gif而不锁定文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!