是否有实现动态加载图像的类的标准模式?
我的任务是创建一个可处理数千张图像的应用程序,这些图像太多而无法一次加载到 RAM 中。我想它有点类似于像 Picassa 这样的照片查看器,因为在任何给定时刻,应用程序只需要来自全部编目图像中的少数图像的像素数据。该应用程序还必须处理非常大的图像,在任何给定时间实际上只需要像素数据的一小部分来进行图像分析或显示,我认为这有点类似于 Google 地球。简而言之,应用程序必须动态地仅加载在任何给定时间实际需要的像素数据部分。
由于只处理了 OpenCV、CImg 或 Magick++ 等图像库中典型的静态图像加载问题,我有点不知如何最好地解决这个问题。所以我的问题是:是否有针对此需求的标准设计模式,或者解决此(或类似)问题的方法?
顺便说一句,对于小图像,我意识到我可以简单地延迟图像的加载,直到需要它为止,但是这种方法会引起两个关键问题。 (1) 这并不能解决大图像问题。 (2) 由于在使用图像后立即卸载图像可能效率低下,因此我需要在应用程序中使用某种类型的内存管理处理程序,仅在加载新图像并且超过某些内存阈值时才卸载图像。显然,加载到内存中的较大图像的部分仍然存在类似的内存管理问题。我坦率地承认这样的工具超出了我的知识和经验,所以如果这是这个问题的普遍答案,那么我有一个补充问题。有人可以推荐一些关于内存管理的基本教程吗?
谢谢您的帮助!
更新:对于那些好奇的人,我想我会分享我所采取的方法。我创建的图像类延迟加载图像数据。为了解决加载数千个图像的问题,我创建了一个类来跟踪文件句柄(Windows 有限制 - 请参阅 _getmaxstdio)以及已加载的图像内存量,并根据需要卸载。为了处理非常大的图像,我使用 VXL 图像库作为后端,它能够加载大图像的一小部分。当然,这对于某些图像(尤其是压缩图像)来说效率不高,但由于我主要处理平铺的 TIFF 图像,因此它的效果非常好。
I've been tasked with creating an application that works with thousands of images, far too many to load into RAM all at once. I guess it's somewhat analogous to a photo viewer like Picassa, in that at any given moment the application needs the pixel data from only a handful of the total cataloged images. The application must also handle extremely large images, where only some small subset of the pixel data would actually be required at any given time for image analysis or display, which, I suppose, is somewhat analogous to Google Earth. In short, the application must dynamically load only the portion of the pixel data that is actually required at any given time.
Having dealt only with static image loading typical of image libraries like OpenCV, CImg, or Magick++, I'm at a bit of a loss how I might best approach the problem. So my question is: are there any standard design patterns for this requirement, or approaches to solving this (or a similar) problem?
BTW, for small images, I realize that I could simply delay loading of the image until it is needed, but there are two key problems that spring to mind with that approach. (1) This doesn't solve the large image problem. (2) Since unloading the image immediately after it is used could be inefficient, I would need some type of memory management handler in the application that only unloads images when new images are loaded and some memory threshold has been passed. Clearly a similar memory management issue remains for portions of a larger image loaded into memory. I will plainly admit that such a tool is beyond my knowledge and experience, so if that is the prevailing answer to this question, then I have a supplemental question. Could anyone recommended some basic tutorials on memory management?
Thank you for the help!
UPDATE: For those who are curious, I thought I'd share the approach I took. The image class I created lazy loads the image data. To solve the problem with loading thousands of images, I created a class that would keep track of the file handles (Windows has a limit - see _getmaxstdio), and the amount of image memory that was loaded, unloading as necessary. To handle very large images, I used the VXL image library as a back-end, which is able to load a subsection of a large image. Granted this isn't so efficient for some images (compressed images especially), but since I'm mostly working with tiled TIFF images, it works very well.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果较大的图像确实很大,以至于不适合屏幕,那么将它们分成较小的部分可能是合理的。
如果您通常需要显示缩小(缩小)的图像,那么您可以通过创建和存储较大图像的缩小版本来简化您的工作。边长为 x 0.707、x 0.5 等的整个级联缩小图像最多占用与原始图像一样多的存储空间。
对于延迟卸载,您可以加载图像(或片段或简化版本)并记住这些图像最新显示的时间以及它们占用的内存量。一旦达到阈值但需要加载更多图像,您可以从最旧的图像开始卸载以释放空间。
If the larger images are really large, such that do not fit onto screen, then it may be reasonable to split them into smaller pieces.
If you have usually to display the images reduced (zoomed out) then you can ease your work by creating and storing the reduced versions of larger images. The whole cascade of reduced images with sides x 0.707, x 0.5 etc takes maximally as lot of storage as original image.
For lazy unloading you can load images (or fragments, or reduced versions) and remember the time when these were latest displayed and as lot of memory they take. Once you hit threshold but need to load more images you can unload starting from oldest to free up space.
第一个要求似乎很容易满足。只需创建一个执行延迟加载的类 - 这意味着它仅在需要时加载数据。
如果您正在处理可以通过偏移处理的任何类型的数据,第二个要求会很容易。大多数图像格式都使用压缩,因此除非您想限制自己使用那些不使用压缩的图像格式,否则您的工作将会为您完成。一个更简单的替代方案可能是将较大的图像分割成较小的图像,并仅加载那些可见/正在处理的部分。
The first requirement seems pretty easy to meet. Just create a class that does lazy loading - meaning it only loads its data when it needs it.
The second requirement WOULD be easy if you were working with any kind of data that can be processed by offset. Most image formats use compression though so unless you want to limit yourself to those that do not, you're going to have your work cut out for you. An easier alternative might be to split the larger images into smaller ones and only load those pieces that are visible/being processed.
第 2 部分 - 很少有图像格式支持有效加载图像的一部分
您可能必须预处理图像、读取它们并将它们分割成单个文件(或数据库)中的图块。
Part 2 - few image formats support loading a section of the image efficently
You are probably going to have to pre-process the images, reading them and splitting them into tiles in individual files (or a database).