2010-01-11 85 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