【问题标题】:Are there standard patterns for implementing a class to dynamically load images?是否有实现类以动态加载图像的标准模式?
【发布时间】:2010-12-02 21:27:45
【问题描述】:

我的任务是创建一个可以处理数千张图像的应用程序,这些图像太多了,无法一次全部加载到 RAM 中。我想它有点类似于像 Picassa 这样的照片查看器,因为在任何给定时刻,应用程序只需要来自总目录图像的少数几个像素数据。该应用程序还必须处理非常大的图像,其中在任何给定时间实际上只需要像素数据的一小部分子集来进行图像分析或显示,我想这有点类似于谷歌地球。简而言之,应用程序必须只动态加载在任何给定时间实际需要的像素数据部分。

只处理了 OpenCV、CImg 或 Magick++ 等图像库的典型静态图像加载,我有点不知如何最好地解决这个问题。所以我的问题是:是否有针对此要求的标准设计模式,或解决此(或类似)问题的方法?

顺便说一句,对于小图像,我意识到我可以简单地延迟加载图像,直到需要它,但是这种方法有两个关键问题。 (1) 这并不能解决大图像问题。 (2) 由于在使用后立即卸载图像可能效率低下,因此我需要在应用程序中使用某种类型的内存管理处理程序,仅在加载新图像并且已通过某些内存阈值时才卸载图像。显然,对于加载到内存中的较大图像的一部分,仍然存在类似的内存管理问题。我会坦率地承认,这样的工具超出了我的知识和经验,所以如果这是这个问题的普遍答案,那么我有一个补充问题。谁能推荐一些关于内存管理的基本教程?

感谢您的帮助!

更新:对于那些好奇的人,我想我会分享我采用的方法。我创建的图像类延迟加载图像数据。为了解决加载数千张图像的问题,我创建了一个类来跟踪文件句柄(Windows 有限制 - 请参阅 _getmaxstdio),以及加载的图像内存量,并根据需要卸载。为了处理非常大的图像,我使用了 VXL 图像库作为后端,它能够加载大图像的一部分。当然,这对于某些图像(尤其是压缩图像)来说效率不高,但由于我主要使用平铺的 TIFF 图像,所以效果很好。

【问题讨论】:

  • 其实缓存和这个人需要的正好相反。
  • 缓存是使用很少的快速内存来加速对大量慢速内存的访问。在这种情况下,主内存和慢内存将是 HDD,而 RAM 将是快内存。缓存还意味着选择要关闭的内容和丢弃的内容:)

标签: c++ image memory-management dynamic


【解决方案1】:

如果较大的图像非常大,以至于无法显示在屏幕上,那么将它们分成更小的部分可能是合理的。

如果您通常必须显示缩小(缩小)的图像,那么您可以通过创建和存储较大图像的缩小版本来简化您的工作。边 x 0.707、x 0.5 等的整个级联缩小图像占用的存储空间与原始图像一样多。

对于延迟卸载,您可以加载图像(或片段,或缩减版本)并记住这些图像最近显示的时间以及它们占用的大量内存。一旦达到阈值但需要加载更多图像,您可以从最旧的开始卸载以释放空间。

【讨论】:

  • +1 用于缩小创意。通过使用简单的小波变换可以更进一步,这样就不会浪费空间。
【解决方案2】:

第一个要求似乎很容易满足。只需创建一个执行延迟加载的类 - 这意味着它仅在需要时加载其数据。

如果您使用任何可以通过偏移量处理的数据,第二个要求将很容易。尽管大多数图像格式都使用压缩,因此除非您想将自己限制在那些不使用的格式,否则您的工作将为您完成。一个更简单的选择可能是将较大的图像拆分为较小的图像,并仅加载可见/正在处理的那些部分。

【讨论】:

  • 阅读一些关于延迟加载的内容(这里martinfowler.com/eaaCatalog/lazyLoad.html 是一个快速总结)。我想“幽灵”方法是我想到的(但未表达),因此即使未加载像素数据,也可以访问图像高度和宽度等字段。但是,如果以及何时卸载延迟加载的对象(或对象的数据),延迟加载是否有一个补充?如果您在每次使用数据后立即卸载,对同一对象的多次顺序查询将非常低效。
【解决方案3】:

第 2 部分 - 少数图像格式支持有效加载图像的一部分

您可能必须对图像进行预处理,读取它们并将它们拆分为单个文件(或数据库)中的图块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-18
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    • 1970-01-01
    • 2012-05-23
    相关资源
    最近更新 更多