加载多个大图像时如何使用内存映射文件

How to work with memory mapped files when loading multiple large images

我有许多 png 和 tiff 格式的美国地理参考图像。我想使用大约 12 个。每张图片约60mb,分辨率约18000*12000像素。我正在尝试创建一个 windows 表单应用程序来加载所有图像以创建地图。 (请查看下方的 link——上图)。该程序还具有 zoom/pan 功能。我试过加载大约 4 张图片,应用程序变得非常慢,甚至多次崩溃。所以我想知道我是否可以使用内存映射文件(或任何其他方式)。我想要做的是只加载可见的图像部分而不是所有图像。当您缩放或平移时,只有可见的地图部分应该加载。我想为此使用内存映射文件,但不知道从哪里开始。

What I am trying to create

我们在消息中的对话有点长,所以我会把它变成一个答案。

不要使用内存映射文件,使用平铺地图系统。

现在我只处理一张 18000*12000 的图像,但您可以将此逻辑扩展到您拥有的多张图像。您要做的是需要将其分解成较小的低分辨率块,以便在给定时间向用户显示。

假设您有 3 个缩放级别 100%、66% 和 33%。 100% 将是原始分辨率。

因此,为了 100%,我们将图像分解为较小的 250x250 像素图像,所以现在您有 3,456 张 250x250 的小图像(72 幅图像横向 48 幅图像向下)。

对于 66%,您可以使用不同的源图像来表示 "zoom level"(例如,您可能不会在地图上显示较小的道路),或者您可以减小原始图像的大小。假设您缩小了图像,您使用绘画程序将源图像的分辨率降低到 12000x8000,我们再次将图像分解为更小的 250x250 像素图像,所以现在您有 1,536 张 250x250 的小图像(48 张图像乘以 32图片向下)。

我们再次重复该过程,将源图像的分辨率降低 33% 至 6000x4000,我们再次将图像分解为更小的 250x250 像素图像,因此现在您有 384 张 250x250 的小图像(24 张图像乘以 16图片向下)。

所以在您的数据库中您保留了您生成的 5,376 张图像 (3,456 + 1,536 + 384) 假设用户的可用屏幕分辨率为 1920x1080,您将在内存中加载 40 张 250x250 的图块(8 张图像乘以 5图像向下)以获得适当的缩放级别并将它们显示在屏幕上。如果您的用户平移或更改缩放级别,则加载新图块而您让旧图块卸载,因此在任何给定时间您只需要在内存中保留 40 张 250x250 图像。

我将不得不对此发表评论。当答案进入 "zoom levels" 时,我立即看到了一个危险信号。从程序员的角度来看,这是一种惰性方法,可以避免处理额外的图像计算,但从用户的角度来看,如果他们想要一个连续的缩放范围,这是一个非常糟糕的方法。 Google 这样做是为了速度和带宽,这对特定应用程序来说很好。具有讽刺意味的是,我来到这个线程是因为我有一张地图已经分解成瓷砖(625 1009x1009!),我只想平移。当唯一的解决方案甚至没有触及原始问题时,这是一种痛苦。

编辑:如果版主看到此内容,请将其转换为评论。我不知道它是如何成为答案的。