2010-01-11 43 views
9

我想使用LibTiff来访问非常大的TIFF文件。我需要多个页面和图块等功能,因此LibTiff似乎是正确的选择。任何人都可以帮助我如何从C#中使用LibTiff?我发现了一些链接(例如blog.bee-ee,其中包含部分代码,但我没有超越获得版本,我看过FreeImage,但发现它不适合(图片大约800万像素8或16位灰度 - > 800-1600兆字节)大小,我不能在一个32位的环境加载在存储器中)使用C#中的LibTiff(访问平铺的TIFF图像)

我非常在C/C++经历过,但尚未在C#。任何人都可以帮我一个包装或一些提示?

注:我需要的页面在TIFF访问金字塔型飞机(多分辨率),以及256×256的瓷砖具有对图像的不同部分的快速访问,而在一次加载它。

[编辑] LibTIFF.NET解决方案对我来说似乎最实用。我现在将它集成到一个产品开发中,它将有助于节省进入/退出托管内存的麻烦。我还没有尝试'回调'功能,这似乎很好地以.net方式解决。 感谢您的帮助stackoverflow

回答

6

你可以试试我们的LibTiff.Net。它是使用托管C#编写的LibTiff的免费和开源版本。我们实施的API与原来的API非常相似。

http://bitmiracle.com/libtiff/

我们刚刚发布,所以有可能是错误。但完整的源代码带有一些测试,所以最明显的错误应该得到修复。

+0

谢谢。我的第一个测试看起来不错。尽管我找到了一个包装类,但它没有一个已知的作者,我迟早会遇到有关访问托管/非托管内存资源的一些问题。基准测试显示,在阅读非压缩文件时,我的表现相当,Adobe压缩金字塔平铺tiffs的性能提高了50%。这对我来说是可以接受的。我可能决定不使用压缩,而且我会比解决内存问题更好地使我的软件多核心友好。 – Adriaan 2010-01-14 08:12:21

+0

谢谢,Adriaan 我们的实现肯定比原来的选择语言慢:-) – Bobrovsky 2010-01-14 12:24:07

+0

我不介意。对于我的项目绩效意味着功能/欧元。开发时间占成本的95%。我可以轻松地投入一个quadcore来弥补这一点。此外,当我远离压缩时,差异很小。而我的文件只能压缩大约10%,所以每个文件只有100MBytes ;-) – Adriaan 2010-01-17 21:27:14

4

WIC提供支持非常大的图像文件。在.NET框架中有一个很好的包装:TiffBitmapDecoder。

+1

你能添加一些链接吗?从我所看到的,TiffBitmapDecoder试图立刻在内存中加载图像。我不能那样做。图片>由于碎片,1 GByte在32位计算机上始终会失败。你指的是windows7的细节(http://msdn.microsoft.com/en-us/library/ee720061%28VS.85%29.aspx)? – Adriaan 2010-01-11 13:09:48

+0

不,TBD不存储图像。从这里开始:http://msdn.microsoft.com/en-us/library/ms748873.aspx – 2010-01-11 13:41:03

+0

感谢您的帮助。不幸的是,我的经历不同。 http://msdn.microsoft.com/en-us/library/ms748873.aspx中列出的步骤确实尝试使用位图1帧的大小分配一块内存。我需要访问位于位图(所以没有适合屏幕的内存保存选项),只是不一定在一块内存中。当我尝试运行示例中给出的tiff解码器时,它通常在位图大于10k * 10k时失败。这些只是我的'小测试文​​件'。我的目标是800万像素×16位。这就是我寻找平铺TIFF文件的原因。 – Adriaan 2010-01-13 08:04:48

1

我最初的解决方案是为LibTIFF DLL使用C#.NET包装器。我在libtiff ftp上找到了它。它似乎包含LIBTiff库的所有重要方法。它将内存保存在非受管理的LibTIFF内存中;这意味着C#代码需要知道这一点,并在需要使用安全代码进行处理时复制数据。

我的“瓦读码”,以测试它读起来就像

if (LibTIFF.IsTiled(tiff)) 
{ 
    if (LibTIFF.GetField(tiff, (int)TIFFTags.TIFFTAG_TILEWIDTH, out tileWidth) && 
     LibTIFF.GetField(tiff, (int)TIFFTags.TIFFTAG_TILELENGTH, out tileLength)) 
    { 
     uint tiles = 0; 
     IntPtr pTile = LibTIFF._malloc((int)(tileLength*tileWidth*bitsPerSample/2)); 
     for (uint y = 0; y < imageLength; y += tileLength) 
     { 
      for (uint x = 0; x < imageWidth; x += tileWidth) 
      { 
       LibTIFF.ReadTile(tiff, pTile, x, y, 0, 0); 
       tiles++; 
      } 
     }       
     LibTIFF._free(pTile); 
    } 
} 

我会去,虽然的libtiff的.NET端口,但是这种解决方案可能是其他人是正确的,所以我离开它在StackOverflow上。

+0

'LibTiff'是处理Tiled TIFF的唯一方法吗?或者我们可以使用.Net Framework中的TiffBitmapDecoder类来做同样的事情吗? – 2014-02-27 22:16:30

+0

从我所看到的,TiffBitMapDecoder没有提供选择性加载文件部分的功能(仅用于渲染完整帧)。 http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.tiffbitmapdecoder(v=vs.110).aspx – Adriaan 2014-05-05 12:41:07