【问题标题】:Out of memory exception in reading a 1.5 GB tile-base Tiff file using LibTiff.Net使用 LibTiff.Net 读取 1.5 GB tile-base Tiff 文件时出现内存不足异常
【发布时间】:2017-04-18 13:55:44
【问题描述】:

我尝试使用 LibTiff.Net 库读取和写入 1.5 GB 平铺 Tiff 文件,因为它已声明支持 BigTiff (>4 GB) 图像文件。我写了下面的代码,但在“buffer [tiles] ...”行中出现错误,抛出内存异常。我很感激能帮助我解决这个问题的开发人员。

using (Tiff input = Tiff.Open(@"E:\active folder\Sample_04.tif", "r"))
        {
            int width = input.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
            int height = input.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
            int tileWidth = input.GetField(TiffTag.TILEWIDTH)[0].ToInt();
            int tileLentgh = input.GetField(TiffTag.TILELENGTH)[0].ToInt();

            int samplesPerPixel = input.GetField(TiffTag.SAMPLESPERPIXEL)[0].ToInt();
            int bitsPerSample = input.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt();
            int photo = input.GetField(TiffTag.PHOTOMETRIC)[0].ToInt();

            int tiles = 0;
            int tileSize = input.TileSize();
            byte[][] buffer = new byte[tileSize][];


            for (int y = 0; y < height; y += tileLentgh)
            {
                for (int x = 0; x < width; x += tileWidth)
                {
                    buffer[tiles] = new byte[tileSize];
                    input.ReadTile(buffer[tiles], 0, x, y, 0, 0);
                    tiles++;
                }
            }

            // writing
            using (Tiff output = Tiff.Open("output.tif", "w"))
            {

                output.SetField(TiffTag.SAMPLESPERPIXEL, samplesPerPixel);
                output.SetField(TiffTag.IMAGEWIDTH, width );
                output.SetField(TiffTag.IMAGELENGTH, height);
                output.SetField(TiffTag.BITSPERSAMPLE, bitsPerSample);
                output.SetField(TiffTag.ROWSPERSTRIP, output.DefaultStripSize(0));
                output.SetField(TiffTag.PHOTOMETRIC, photo);
                output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);

                int c = 0;

                for (int y = 0; y < height; y += tileLentgh)
                {
                    for (int x = 0; x < width; x += tileWidth)
                    {
                        output.WriteTile(buffer[c], x, y, 0, 0);
                        c++;
                    }
                }
            }
        }
        System.Diagnostics.Process.Start("output.tif");
    }

【问题讨论】:

  • 32 位还是 64 位进程?
  • 它是一个 32 位处理器。
  • 机器有多少内存?配置/可用多少交换/页面文件空间?抛出异常时你的进程消耗了多少内存?
  • 本机支持 6 Gb RAM,当内存达到 84% 时抛出异常。我认为它使用了 20% 的内存来执行。

标签: c# visual-studio tiff libtiff.net


【解决方案1】:

问题不在于库不支持 BigTiff 文件,当您尝试分配一个巨大的数组时会引发错误。您编写的代码试图在您的计算机内存中分配数组,期望那里有足够的空间来执行此操作,但似乎没有。

处理大小与目标系统上可用内存相当的数据总是需要额外注意(这就是为什么您可以在库的描述中看到 BigTiff 支持强调的原因)。

幸运的是,这不是一个新问题,并且有解决方案:请参阅herehere 的一些答案。

基本上,这些解决方案背后的想法是使用您的硬盘驱动器(或其他存储设备)来存储数据并为您提供一个接口,以便您在需要时将必要的部分交换到内存中(就像virtual memory)。

【讨论】:

  • 谢谢,但我对读取平铺 Tiff 的代码有疑问,因为没有使用 readTile() 方法读取的示例代码。我会听取你的建议来处理巨大的缓冲区数组。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-06
  • 2013-10-05
  • 2012-11-05
  • 1970-01-01
相关资源
最近更新 更多