【问题标题】:How to reduce memory usage for processing many images?如何减少处理许多图像的内存使用量?
【发布时间】:2015-09-12 04:24:58
【问题描述】:

我正在开发一个 C# WPF 应用程序,它使用来自许多图像的像素数据来处理一个图像。

  1. 需要用户打开多张任意格式的图片。
  2. 这些图像使用 System.Drawing.Bitmap 类使用 LockBits() 方法存储在内存中,它们的第一个像素数据的内存地址存储在 >字节*
  3. 新的 System.Drawing.Bitmap 是使用 LockBits() 方法创建和处理的,并在 unsafe 上下文中使用 直接访问内存System.Threading.Tasks.Parallel 类,其像素值是使用所有打开的图像的每个像素的像素值计算的,并保存到内存中。
  4. 已处理的 System.Drawing.Bitmap 被编码为 jpeg 并保存到选定的位置。
  5. Dispose()UnlockBits()GC.Collect() 方法被调用。

问题是,使用上述方法,所有打开的图像都必须留在内存中,直到整个操作完成。
比如我打开50张分辨率为4160x3120的图片,占用4160*3120*3*50字节:大约1857兆内存。

是否有任何可能的解决方案不需要所有图像都在内存中,或任何其他解决方案来减少内存使用?

【问题讨论】:

  • 最近看了一篇文章,可以在wpf中设置控件的fps刷新率,可以提高性能。也许朝这个方向研究可能会有所帮助。这是链接:wpftutorial.net/FrameRate.html
  • 如果您真的需要一次所有这些信息,您必须存储它,别无选择。根据您的算法,您可以做的是在内存和磁盘之间共享一些数据,但所有数据必须在某个时间点都在内存中。
  • “是否有任何可能的解决方案不需要所有图像都在内存中”。当然,如果图像处理可以按顺序进行。然而,这很难从您的问题中看出,因为您没有告诉我们具体的处理方式。
  • 您是在启动线程之前还是在线程内创建Bitmap 对象?这有很大的不同。例如,如果您在启动线程之前创建并锁定它们并且将 50 个单独的任务排队,那么您将在内存中一次有 50 个 Bitmaps 的数据,等待一次处理几个取决于您的处理器数量。相反,如果您只是将路径传递给每个任务并让每个任务实例化并锁定其自己的Bitmap,那么您可能会同时在内存中存储 1-8 个图像的数据(同样,取决于您的处理器数量)。
  • @rwank 跟我的问题无关。

标签: c# wpf memory bitmap


【解决方案1】:

我正在开发一个 C# WPF 应用程序,它使用来自许多图像的像素数据来处理一个图像。

如果您需要来自许多图像的像素数据,那么您需要将它们存储在内存中。您不能直接从磁盘或从磁盘处理像素。您的方法应该是最小化到只需要那些图像。

如果像素处理来自相同的相对位置,则可能会将图像分成几部分(例如四分之一)。

【讨论】:

    【解决方案2】:

    抱歉,我认为您的问题的直接答案是否定的。

    如果您需要在运行时处理所有图像数据,则需要将它们全部保存在内存中。这种情况在某些使用医学图像或图像处理算法进行 3D 渲染、模式识别等的应用程序中非常常见,这就是为什么这种系统通常需要强大的硬件来运行。

    您在不安全的环境中做正确的事情,您应该尽可能多地使用 TPL(任务并行库)。

    更高的性能取决于您的算法允许您做什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-27
      • 2020-01-27
      • 2018-07-12
      • 2021-12-12
      • 1970-01-01
      • 2011-12-02
      相关资源
      最近更新 更多