在windows窗体(c#.net)应用程序中加速从磁盘加载图像

在windows窗体(c#.net)应用程序中加速从磁盘加载图像,c#,winforms,image,C#,Winforms,Image,我目前正在开发一个应用程序,允许用户在一系列本地图像中播放(自动滚动)。通常一次屏幕上会有五六个 目前的主要瓶颈似乎是从磁盘实际加载图像数据。计时器线程要求每1/6秒更新一次图像,而应用程序正努力跟上这一速度。每个图像大约25Kb 我尝试创建一个滚动缓存来尝试和预加载图像,但这也被它自己所困扰,所以最终速度也慢了很多 计时器的每一个节拍,我都会循环通过六个图像占位符,使用标准的 Image img = Image.FromFile("filename"); 方法,但认为有人可能知道一种更快的方

我目前正在开发一个应用程序,允许用户在一系列本地图像中播放(自动滚动)。通常一次屏幕上会有五六个

目前的主要瓶颈似乎是从磁盘实际加载图像数据。计时器线程要求每1/6秒更新一次图像,而应用程序正努力跟上这一速度。每个图像大约25Kb

我尝试创建一个滚动缓存来尝试和预加载图像,但这也被它自己所困扰,所以最终速度也慢了很多

计时器的每一个节拍,我都会循环通过六个图像占位符,使用标准的

Image img = Image.FromFile("filename");
方法,但认为有人可能知道一种更快的方法来从磁盘上获取图像

这六组图像中的每一组都有500到20000张图像,因此它太大,无法在开始时将整个图像加载到内存中

如果有人对如何更快地通过这些图片提出建议,我们将不胜感激


编辑以添加应用程序流的更多详细信息

好吧,事情就是这样:

用户点击“播放”按钮。计时器线程以1/6秒超时开始

计时器回调:

Update image index (_index++)
for each viewer in list of visible viewers (the forms to display images)
{
    get the filename from the id stored in the viewer
    check to see if the file exists
    if it does exist,
        create new bitmap from image
        and return that image
    otherwise return null

    if returned image isn't null, display it on screen
}

这显然是跨几个层的-图像加载在服务层中进行,然后传递到演示文稿,然后传递到UI,但这就是发生的要点。

最简单的方法可能是放置“下一步”和“上一步”按钮,以限制图像数量并预加载。

如果一次显示6个图像,如果每1/6秒更改一次,就会遇到性能问题。即使没有缓存,从磁盘加载150 kb也应该是一项微不足道的活动。听起来你可能加载文件太多了。您确定一次只加载6个图像吗?您正在从磁盘读取未显示的图像吗

如果您能提供应用程序流程的更多细节,我可能会提供更多帮助。

我遇到了一个描述如何直接使用GDI+API加载图像的程序。使用非常简单:

ImageFast.FromFile(@"C:\MyPhoto.JPG");

添加以显示ImageFast在文件法图像上的速度

这将使用找到的源代码。代码被复制和粘贴,不需要任何更改

Stopwatch watch = Stopwatch.StartNew();

string filePath = @"C:\TestImage25k.png";

Image fromFile = Image.FromFile(filePath);

watch.Stop();

Console.WriteLine("Image.FromFile     Ticks = {0:n}", watch.ElapsedTicks);

long fromFileTicks = watch.ElapsedTicks;

watch.Reset();
watch.Start();

Image fastImage = ImageFast.FromFile(filePath);

watch.Stop();

long fastFileTicks = watch.ElapsedTicks;

Console.WriteLine("ImageFast.FromFile Ticks = {0:n}", watch.ElapsedTicks);

Console.WriteLine("fromFileTicks - fastFileTicks = {0:n}", fromFileTicks - fastFileTicks);
控制台输出为

Image.FromFile Ticks = 19,281,605.00 ImageFast.FromFile Ticks = 7,557,403.00 fromFileTicks - fastFileTicks = 11,724,202.00 Image.FromFile Ticks=19281605.00 ImageFast.FromFile Ticks=7557403.00 fromFileTicks-fastFileTicks=11724202.00
您可以看到ImageFast的影响。随着时间的推移,保存的1100万个滴答声将累加起来。

我可能会创建一个后台线程,不断从磁盘获取所有图像(保持ui响应),然后通过一个事件发布每个新加载的图像。

查看。您要做的是有第二个线程,在显示第一组图像时,可以加载下一组图像。一旦1/6时间门命中,您将切换一组图像并开始加载下一组图像。

我认为双缓冲的概念将非常有用。将窗体的“双缓冲区”属性设置为True。这对你有点帮助。以下链接可能对您有用


我编写了一个快速测试应用程序来测试这一点,ImageFast的速度快了1100万次。图像的from文件需要1900万,而ImageFast只需要700万。谢谢测试结果,大卫:)没问题。我喜欢ImageFast的结果。非常感谢,我已经更新了加载机制,使用它从磁盘读取数据。我可能会把这个和双缓冲一起使用,看看我能以多快的速度运行它。嗨,我已经编辑了这个问题来展示一些应用程序流程。它肯定一次只加载6个图像。如果我开始关闭一些“查看器”窗口,速度会明显加快。我还试着在播放前将每组的前50张图像读入内存,这完全消除了瓶颈,所以似乎只是加载减慢了速度。