使用 LibTiff.Net 读取 1.5 GB 基于图块的 Tiff 文件时出现内存不足异常
Out of memory exception in reading a 1.5 GB tile-base Tiff file using LibTiff.Net
我尝试使用 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");
}
问题不是库不支持 BigTiff 文件,当您尝试分配一个巨大的数组时会抛出错误。您编写的代码试图在您的计算机内存中分配数组,期望那里有足够的 space 来这样做,但似乎没有。
处理大小与目标系统上的可用内存相当的数据总是 需要额外注意(这就是为什么您可以在库的描述中看到强调 BigTiff 支持)。
幸运的是,这不是一个新问题,并且有解决方案:查看一些答案 here or here。
基本上,这些解决方案背后的想法是使用您的硬盘驱动器(或其他存储设备)来存储数据,并提供一个接口供您在需要时将必要的部分交换到内存(就像 virtual memory).
我尝试使用 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");
}
问题不是库不支持 BigTiff 文件,当您尝试分配一个巨大的数组时会抛出错误。您编写的代码试图在您的计算机内存中分配数组,期望那里有足够的 space 来这样做,但似乎没有。
处理大小与目标系统上的可用内存相当的数据总是 需要额外注意(这就是为什么您可以在库的描述中看到强调 BigTiff 支持)。
幸运的是,这不是一个新问题,并且有解决方案:查看一些答案 here or here。
基本上,这些解决方案背后的想法是使用您的硬盘驱动器(或其他存储设备)来存储数据,并提供一个接口供您在需要时将必要的部分交换到内存(就像 virtual memory).