在Winforms中显示动画gif而不锁定文件 [英] Showing animated gif in Winforms without locking the file

查看:59
本文介绍了在Winforms中显示动画gif而不锁定文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在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而不锁定文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆