代码之家  ›  专栏  ›  技术社区  ›  srboisvert

在图片框中快速加载和显示图像

  •  0
  • srboisvert  · 技术社区  · 14 年前

    我需要从文件系统中加载101个位图(它们不能作为资源内置到应用程序中,因为它们在程序每次运行时都会发生更改),并根据短时间计时器事件(500ms give或take)顺序加载到Windows窗体应用程序PictureBox中。

    本质上,它应该像一个缓慢的动画一样工作,但关键是要显示每个图像。

    我在C语言中设计了一个简单的应用程序来完成这项工作,但是看起来图像加载和显示的时间比500毫秒长,所以一些图像永远不会显示。

    有什么方法可以避免这个吗?预加载或创建101个图片框并显示和隐藏?

    有人有什么建议吗?

    5 回复  |  直到 14 年前
        1
  •  1
  •   Origamiguy    14 年前

    什么是最长的?图像加载或显示?当需要显示每个图像时,是否加载它?看看你的代码是非常有价值的。

    如果您确定它总是正好是101个图像,请将它们全部加载到 System.Drawing.Bitmap 第一 然后有一个迭代器变量,该变量在每次调用 Tick A事件 Timer . 让此勾选事件使用将图像从数组加载到PictureBox中 PictureBox.Image = myBitmapArray[iterator] 如果使用 ++i%=101; 你不会得到越界错误,动画会循环。

        2
  •  1
  •   SLaks    14 年前

    填充数组 Bitmap 启动动画前的对象。

        3
  •  1
  •   James King    14 年前

    有几个选择…选择一个或组合它们:

    (1)使用一个锁和一个计数器来确保当事件触发时,它正在加载行中的下一个图像。

    (2)禁用 Tick 事件,然后在加载图像后重新启用它。结果是,图像在最后一个图像绘制后到达500ms,因此如果一张图片需要一秒钟的时间来加载,则图像在t=1000ms、t=1500ms、t=3000ms等条件下绘制。所有图像都被绘制,并且保证500ms在图片之间通过,但动画可能看起来很慢。

    (3)执行上述操作,但跟踪事件开始的时间,并在绘制图像后,将下一个计时器刻度设置为500-(现在为-eventstart)…因此,如果图像需要250毫秒来绘制,则下一个计时器刻度将在250毫秒后触发。如果现在是-eventstart<0,则下一个计时器刻度应立即触发。动画将花费尽可能短的时间,但图像可能会闪烁,只出现几毫秒。

    (4)使用 PictureBox.LoadAsync() 给你一些多线程…下一个事件可以在绘制上一个事件时加载图像。但你需要一个 Mutex 你释放在 LoadCompleted 如果需要确保所有图像都已绘制,则在调用loadAsync()之前等待的事件。

    (5)我不确定图片的绘图是否属于布局类别,但您可以尝试调用 SuspendLayout() ResumeLayout() 加载图像之前/之后

    (6)使用图像数组,锁定计数器,并使用 .Image 性质 PictureBox 以便预加载图像。我相信这是在另一个答案中提出的

    HTH
    詹姆斯

        4
  •  0
  •   Dave    14 年前

    我没有一个具体的答案给你,但我会首先确定它是图像加载、图像显示,还是两个动作都花费了太多时间。

    我可以想象,如果图像是本地的,并且您有相对不错的硬件,那么图像加载将相对较快,即使图像大小相当大。我的第一次尝试将涉及按顺序从线程加载所有图像,这样应用程序就不必在加载下一个图像之前等待图像显示完成。

    如果图像显示需要很长时间(即使在我功能强大的工作站上,对大图像来说也不是那么快),那么您是否可以在应用程序显示所有内容之前缩放图像?您的应用程序需要处理全分辨率图像吗?现在有了百万像素的照相机,我无法想象你无论如何都想在图像文件中显示所有的数据,因为这些数据的大小很容易超过显示器分辨率的6倍。

        5
  •  0
  •   Jason    14 年前

    另一个可能引起关注的问题是图像的大小。如果这些都是1800万像素的图像,我可以看到它占用了很多时间或空间。

    当您最初加载它们时,您可能希望将它们调整到显示区域的大小,这样您就不会使用2 Gigs的RAM,也不会等待读取磁盘,这取决于您如何实现它。