c# - 在不锁定文件的情况下在 Winforms 中显示动画 gif

标签 c# .net winforms visual-studio-2010 window

我试图在我的 Winforms 应用程序中显示各种文件类型的图像(包括动画 .gif 文件)。我还必须能够修改显示的文件。 (更改文件名,删除它们)。

问题是 Picturebox locks the image file until the application is closed当使用正常方式时。

这意味着我不能这样做:

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
    }

上面链接中的解决方法如下:

    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;
    }

这适用于普通图像类型,但它不会加载动画 .gif,这对我来说很重要。尝试加载一个会使它看起来像 this .

我发现了一些关于它的其他主题(thisthis),但它们都是关于 WPF 和使用 BitmapImage 的。我已经搜索过如何在 Winforms 应用程序中使用 BitmapImage,但除了它应该以某种方式工作之外没有发现任何东西。

我想继续使用 Winforms,因为我只是习惯了它,但这不是必需的。

总而言之:我需要一种方法来显示常见的图像类型(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 未加载。

最佳答案

使用 MemoryStream 确实是避免文件锁定的正确方法。顺便说一句,这是一个强大的优化,锁是由内存映射文件创建的,Image 类使用该文件将像素数据保留在页面文件之外。当位图很大时,这很重要。希望不是动画 gif :)

代码片段中的一个小错误,您忘记将流重置回数据的开头。修复:

 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);
 } 

以防万一:不要释放内存流。这导致以后很难诊断随机崩溃,延迟读取像素数据。

关于c# - 在不锁定文件的情况下在 Winforms 中显示动画 gif,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22016544/

相关文章:

mysql - .Net MySQL 驱动程序未正确处理“

.net - .NET PDB文件的格式(模式)是什么?

c# - 如何将数据集添加到报表中 C#

c# - 文本框自动完成(多行)

c# - 使用标记方法将 Item Sourcing 转换为 ComboBox

c# - 通过 [] 运算符访问字符串中的 char 是更快还是通过 [] 运算符访问 char[] 中的 char 更快?

c# - byte[] 并有效地通过引用传递

c# - 无法安装 Service Fabric 运行时

c# - SQLDataReader C#、SQL Server 2005、VS 2008

.net - 最大化屏幕忽略任务栏