【问题标题】:Processing on large bitmaps (up to 3GB)处理大型位图(最大 3GB)
【发布时间】:2012-06-19 09:50:22
【问题描述】:

我正在从事一些大学项目,但遇到了内存问题。 我使用以下代码在 HDD 上加载了大约 1.5GB 的位图:

Bitmap bmp = new Bitmap(pathToFile); 

问题是新创建的 Bitmap 对象使用了大约 3.5GB 的 RAM,这是我无法理解的(这真的是 BIG 包装器:E)。我需要进入像素数组,使用 Bitmap 类真的很有帮助(我稍后使用 LockBits() 方法,并按字节处理数组字节),但在这种情况下,它是完全阻塞的。所以这是我的问题:

有没有简单的方法来提取像素阵列而不借出额外的 2GB 空间?

我使用 c# 只是为了提取所需的数组,然后在 c++ 中处理该数组 - 也许我可以在 c++ 中提取所有需要的数据(但此处出现转换问题 - 我专注于 24bgr 格式)?

PS:我需要将整个位图保存在内存中,因此将其分成几部分是没有办法的。

PS2:只是为了澄清一些问题:我知道文件扩展名和文件格式之间的区别。加载的文件是未压缩的位图,每像素 3 个字节,大小约为 1.42GB(16k x 32k 像素),那么为什么 Bitmap 对象要大两倍以上呢?不会发生任何解压缩问题和转换为其他格式的问题。

【问题讨论】:

  • @Jason:是的,但这个问题没有实际答案。不知道他们为什么要监督内存映射文件。
  • 位图使用什么编码?有 RLE 压缩吗?
  • 位图的编码是 24 位的,没有 RLE 压缩,所以我唯一想要的就是反序列化像素数组 :( 它的大小是 16k X 32k 像素,所以每个像素 3 个字节需要 1.42GB所以我真的不明白为什么用该文件创建的 Bitmap 对象需要额外的 2GB 数据
  • 忽略磁盘大小,图像的尺寸和位深度是多少。这将告诉您将图像数据保存在内存中的最低要求(将它们全部相乘 - 假设它不是索引图像 - 并且位深度为每个像素的字节数)。然后,这将告诉您是压缩等还是 Bitmap 类的内存开销是您的问题。

标签: c# file memory bitmap


【解决方案1】:

考虑使用内存映射文件来访问您的大量数据:)。 可以在这里找到一个专注于您需要的示例:http://visualstudiomagazine.com/articles/2010/06/23/memory-mapped-files.aspx 它在托管代码中,但您也可以从等效的本机代码中使用它。

如果您需要更多详细信息,请告诉我。

【讨论】:

  • 您能否更具体一些并说明如何在这种特殊情况下使用它?
  • 好吧,您只需使用内存映射视图遍历位图,分块读取数据并将其推送到 C++ 部分。我认为在 C++ 中完成这一切并在遍历 mem 映射文件时处理位图数据甚至可能更有效。
  • 整件事是,使用 MMF 您不会将整个数据加载到内存中。只是其中的一小部分。而且您可以浏览它,而无需真正关心它并非全部在内存中。
  • Why use the .NET Bitmap class when you can do a little extra processing and get much more efficiency out of it 这就是 OP 的要求。解释那部分。(虽然它仍然不需要 MMF)
  • 我并不想变得粗鲁。对不起!但我不知道你为什么说 MMF 行不通,不仅如此,为什么你认为有更好的解决方案。就我而言,我认为这是唯一的解决方案。研究如何使用 Bitmap 完成这是浪费时间。例如,ImageMagick 还使用 MMF 处理大文件来处理和处理大图像 (www2.fz-juelich.de/vislab/software/www/FAQ.html#C9)。
【解决方案2】:

您可以使用此解决方案,在 C# 中更快地使用位图 http://www.codeproject.com/Tips/240428/Work-with-bitmap-faster-with-Csharp

或者你可以使用内存映射文件

http://visualstudiomagazine.com/articles/2010/06/23/memory-mapped-files.aspx

【讨论】:

    【解决方案3】:

    您可以停止内存缓存。

    代替

    Bitmap bmp = new Bitmap(pathToFile);

    使用

    var bmp = (Bitmap)Image.FromStream(sourceFileStream, false, false);

    https://stackoverflow.com/a/47424918/887092

    【讨论】:

      猜你喜欢
      • 2011-01-14
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-23
      相关资源
      最近更新 更多