【发布时间】:2015-09-12 04:24:58
【问题描述】:
我正在开发一个 C# WPF 应用程序,它使用来自许多图像的像素数据来处理一个图像。
- 需要用户打开多张任意格式的图片。
- 这些图像使用 System.Drawing.Bitmap 类使用 LockBits() 方法存储在内存中,它们的第一个像素数据的内存地址存储在 >字节*。
- 新的 System.Drawing.Bitmap 是使用 LockBits() 方法创建和处理的,并在 unsafe 上下文中使用 直接访问内存System.Threading.Tasks.Parallel 类,其像素值是使用所有打开的图像的每个像素的像素值计算的,并保存到内存中。
- 已处理的 System.Drawing.Bitmap 被编码为 jpeg 并保存到选定的位置。
- 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 跟我的问题无关。