使用 libtiff.net 编写大量 TIFF 页面的有效方法
Efficient way to write very large number of TIFF pages using libtiff.net
我正在使用以下代码将一系列 16 位灰度图像(对于此问题而言为空数组)写入多页 TIFF:
int numberOfPages = 1000;
int width = 256;
int height = 256;
string fileName = "test.tif";
ushort[] image = new ushort[width * height];
byte[] buffer = new byte[width * height * sizeof(ushort)];
Stopwatch stopWatch = new Stopwatch();
using (Tiff output = Tiff.Open(fileName, "w"))
{
if (output == null)
{
return;
}
stopWatch.Start();
for (int i = 0; i < numberOfPages; i++)
{
Buffer.BlockCopy(image, 0, buffer, 0, buffer.Length);
output.SetField(TiffTag.IMAGEWIDTH, width);
output.SetField(TiffTag.IMAGELENGTH, height);
output.SetField(TiffTag.SAMPLESPERPIXEL, 1);
output.SetField(TiffTag.BITSPERSAMPLE, 16);
output.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT);
output.SetField(TiffTag.XRESOLUTION, 96);
output.SetField(TiffTag.YRESOLUTION, 96);
output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
output.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);
output.SetField(TiffTag.COMPRESSION, Compression.NONE);
output.SetField(TiffTag.FILLORDER, FillOrder.MSB2LSB);
output.SetField(TiffTag.SUBFILETYPE, FileType.PAGE);
output.SetField(TiffTag.PAGENUMBER, i + 1, numberOfPages);
output.WriteEncodedStrip(0, buffer, buffer.Length);
output.WriteDirectory();
}
stopWatch.Stop();
}
Debug.WriteLine(stopWatch.ElapsedMilliseconds);
它在几百页上工作正常,但执行时间似乎不会随着页数的增加而线性增加。例如:
1000 pages --- 3130 ms
2000 pages --- 11778 ms
3000 pages --- 25830 ms
我也试过在循环中使用追加模式,但得到了类似的结果。
我做错了吗?或者我应该期待这种开销吗?
我使用 CPU 使用工具在 Visual Studio(分析 -> 性能分析器)中分析了您的代码,这是我的发现:
对于 5000 页,大约 91% 的时间用于编写 TIFF 目录。不是数据而是描述目录的结构。这看起来很可疑,所以我查看了 WriteDirectory
做了那么长时间的事情。
WriteDirectory
尝试 link 以前和新创建的目录。为此,它总是从第一个目录开始搜索以前的目录。 TIFF 中的目录越多,添加每个新目录所需的时间就越长。
恐怕不更改库代码就无法更改此行为。
我正在使用以下代码将一系列 16 位灰度图像(对于此问题而言为空数组)写入多页 TIFF:
int numberOfPages = 1000;
int width = 256;
int height = 256;
string fileName = "test.tif";
ushort[] image = new ushort[width * height];
byte[] buffer = new byte[width * height * sizeof(ushort)];
Stopwatch stopWatch = new Stopwatch();
using (Tiff output = Tiff.Open(fileName, "w"))
{
if (output == null)
{
return;
}
stopWatch.Start();
for (int i = 0; i < numberOfPages; i++)
{
Buffer.BlockCopy(image, 0, buffer, 0, buffer.Length);
output.SetField(TiffTag.IMAGEWIDTH, width);
output.SetField(TiffTag.IMAGELENGTH, height);
output.SetField(TiffTag.SAMPLESPERPIXEL, 1);
output.SetField(TiffTag.BITSPERSAMPLE, 16);
output.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT);
output.SetField(TiffTag.XRESOLUTION, 96);
output.SetField(TiffTag.YRESOLUTION, 96);
output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
output.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);
output.SetField(TiffTag.COMPRESSION, Compression.NONE);
output.SetField(TiffTag.FILLORDER, FillOrder.MSB2LSB);
output.SetField(TiffTag.SUBFILETYPE, FileType.PAGE);
output.SetField(TiffTag.PAGENUMBER, i + 1, numberOfPages);
output.WriteEncodedStrip(0, buffer, buffer.Length);
output.WriteDirectory();
}
stopWatch.Stop();
}
Debug.WriteLine(stopWatch.ElapsedMilliseconds);
它在几百页上工作正常,但执行时间似乎不会随着页数的增加而线性增加。例如:
1000 pages --- 3130 ms
2000 pages --- 11778 ms
3000 pages --- 25830 ms
我也试过在循环中使用追加模式,但得到了类似的结果。
我做错了吗?或者我应该期待这种开销吗?
我使用 CPU 使用工具在 Visual Studio(分析 -> 性能分析器)中分析了您的代码,这是我的发现:
对于 5000 页,大约 91% 的时间用于编写 TIFF 目录。不是数据而是描述目录的结构。这看起来很可疑,所以我查看了 WriteDirectory
做了那么长时间的事情。
WriteDirectory
尝试 link 以前和新创建的目录。为此,它总是从第一个目录开始搜索以前的目录。 TIFF 中的目录越多,添加每个新目录所需的时间就越长。
恐怕不更改库代码就无法更改此行为。