简体   繁体   English

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

[英]Speed up loading an image from disk in a windows forms (c#.net) app

I'm currently working on an app that allows the user to play (automatically scroll) through a series of local images. 我目前正在开发一款应用程序,允许用户播放(自动滚动)一系列本地图像。 Usually there will be five or six on screen at once. 通常一次屏幕上会有五六个。

The major bottleneck at the moment seems to be the actual loading of the image data from disk. 目前的主要瓶颈似乎是从磁盘实际加载图像数据。 A timer thread calls for the images to be updated every 1/6 of a second and the app is struggling to keep up with that speed. 计时器线程要求每1/6秒更新一次图像,应用程序正在努力跟上这个速度。 Each image is around 25Kb. 每张图片大约25Kb。

I tried creating a rolling cache to try and preload images but this was also getting caught up with itself so ended up slowing down just as much. 我尝试创建一个滚动缓存来尝试和预加载图像,但这也被赶上了自己,所以最终放慢了同样的速度。

Every beat of the timer, I'm looping through the six image placeholders loading the next image using the standard 计时器的每个节拍,我循环使用标准加载下一个图像的六个图像占位符

Image img = Image.FromFile("filename");

method but thought someone might know of a faster way to get the images off disk. 方法,但认为有人可能知道更快的方式从磁盘上获取图像。

There are between 500 and 20,000 images in each of the six sets so it's too large to load the whole thing into memory at the start. 在六组中的每一组中都有500到20,000个图像,所以它太大而无法在开始时将整个内容加载到内存中。

If anyone has suggestions for a faster way to pull these images through, it would be greatly appreciated. 如果有人建议以更快的方式拉动这些图像,那将非常感激。


Edit to add some more detail of application flow. 编辑以添加应用程序流的更多细节。

Okay, this is what's happening: 好的,这就是发生的事情:

User hits 'play' button. 用户点击“播放”按钮。 Timer thread starts with 1/6 second timeout. 定时器线程以1/6秒超时开始。

Timer callback: 定时器回调:

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
}

That's obviously going across a few layers - the image loading goes on in the services layer and then passes this through to presentation and then to the UI but that's the gist of what's happening. 这显然是跨越几层 - 图像加载在服务层继续,然后将其传递到演示文稿,然后传递到UI,但这是发生的事情的要点。

I came across this page which describes how to use the GDI+ API directly to load images. 我遇到了这个页面 ,它描述了如何直接使用GDI + API来加载图像。 Very simple to use: 使用非常简单:

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

Added to show speed of ImageFast over Image From File method 添加以显示ImageFast over Image From File方法的速度

This uses the source code found here . 这使用了此处的源代码。 The code was copied and pasted and required no changes. 代码已复制并粘贴,无需更改。

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

The console output was 控制台输出是

Image.FromFile     Ticks = 19,281,605.00

ImageFast.FromFile Ticks = 7,557,403.00

fromFileTicks - fastFileTicks = 11,724,202.00

You can see the impact of the ImageFast. 您可以看到ImageFast的影响。 Over time those 11 million saved ticks will add up. 随着时间的推移,这1100万个节省的蜱将加起来。

最简单的可能是放置“下一个”和“上一个”按钮来限制图像数量和预加载。

Check out the concept of double buffering . 看看双缓冲的概念。 What you want to be doing is have a second thread that can be loading the next set of images while you are displaying the first set. 你想要做的是有第二个线程,可以在显示第一组加载下一组图像。 Once the 1/6 time gate hits, you switch the one set of images out and start loading the next set. 一旦1/6时间门命中,您将一组图像切换出来并开始加载下一组图像。

I think concept of double buffering will be useful. 我认为双缓冲的概念将是有用的。 Set "Double Buffer" property of the form to True. 将窗体的“Double Buffer”属性设置为True。 This will help you little bit. 这对你有所帮助。 Following links may be useful to you 以下链接可能对您有用

If you have 6 images displayed at once, and you change them all every 1/6 of a second, you should be running into performance issues. 如果一次显示6张图像,并且每1/6秒更改一次,则应该遇到性能问题。 Loading 150 kb from disk should be a trivial activity even without caching. 即使没有缓存,从磁盘加载150 kb应该是一项微不足道的活动。 It sounds like you may be overdoing the file loads. 听起来你可能会过度负载文件。 Are you sure you are only loading 6 images at a time? 您确定一次只能加载6张图片吗? Are you reading images from disk that are not displayed? 您是否正在从磁盘读取未显示的图像?

If you can you provide a little more detail of the application flow, I may be able to be a little more helpful. 如果您能提供更多应用程序流程的详细信息,我可能会更有帮助。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何重新调整图像C#.net Windows窗体的大小 - How To Re-size An Image C#.net Windows Forms C#.NET-如何从现有的Windows窗体控件继承 - C#.NET - How to inherit from an existing windows forms control 在C#.NET和Windows窗体中将照片转换为灰度 - Photo to grayscale in C#.NET and Windows Forms 使用 c#.net 可以使用控制台应用程序打开 Excel 工作簿,但不能使用 Windows 窗体应用程序打开 - Using c#.net can open excel workbook with console app but not with a windows forms app 加速PathGeometry.Combine(c#.net)? - Speed up PathGeometry.Combine (c#.net)? Windows 通过ADFS C#.NET认证后出现认证框 Web Forms App - Windows authentication box appears after authenticating through ADFS C#.NET Web Forms App 如何使用 USB 电缆 C#.net 将文件从 Windows 表格申请传输到 Xamarin Forms - How to transfer the file from Windows Form Application to Xamarin Forms using USB cable C#.net Image.FromFile没有加载到设计时间视图c#.net中 - Image.FromFile not loading into design time view c#.net 在Windows应用程序中,如何使用C#.Net 2.0从PictureBox中的网络摄像头保存实时图像 - In windows application how can i save a live image from webcam in picturebox using C#.Net 2.0 使用C#.NET从另一个类访问Windows App对象 - Accessing a Windows App Object from another Class using C#.NET
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM