最近在實習,前陣子用到TIF(GeoTiff)影像處理,在VC2005上用了一下GDAL,在此記錄下相關東西。
GDAL當前的最新版本已經到了1.7.2,由於除了Win32,還要與Windows Mobile的Pocket PC打交道,所以也看了一下WinCE的支援情況,發現雖然其中一直都有wince目錄,不過最終發現只有1.4版的wince版本才真正可以編譯使用,後續版本的WinCE分支都只是擺設了
不過這裡的內容基本與版本無關
基本的東西自然不用多說,官網上的入門教程和樣本還是很容易理解的,資料模型的解釋也很容易,下面的地址有基本內容的中文翻譯:
http://www.osgeo.org.cn/l18n/gdal/index.html
這裡總結一下碰到的GDAL技巧
檔案讀寫:
GDAL中映像的讀寫主要有三種:
GDALDataset::RasterIO(…)
GDALRasterBand::RasterIO(…)
GDALRasterBand:ReadBlock(...)和WriteBlock(…)
經過我自己的測試,效率都相差不算很大,不過還是有一些區別的。
前兩者本質上差不多,只不過第一項可以一次讀取指定映像範圍的所有波段資訊,而第二種唯讀取所在波段的資訊。這兩個函數的參數都有原圖要讀取的地區,以及目標大小兩部分參數,根據這兩部分參數,RasterIO可以自動完成映像的縮放(我只用到縮小)。第一種讀取,由於可以讀取所有波段,還有一些特殊的地方,後面說明。
ReadBlock和WriteBlock是按照影像檔的分塊組織讀取,分塊大小是影像檔本身已經客觀存在的,由於適合檔案分塊的讀取,所以速度是最快的,但是只能按分好的某塊讀取,靈活性差。
GDALDataset::RasterIO的最後三個參數->讀取結果資料排列
這個函數讀取指定地區的所有波段,既然讀取所有波段,就有一個資料群組織格式的問題。對於一般映像,一個波段(實際顏色的一個分量)是8bit,那麼我們通過RasterIO取出來的資料就是byte* pData;(這裡的byte,可以是typedef unsigned char byte)。那麼對於24bit的真彩圖,pData裡要儲存紅綠藍(RGB)三個波段,RasterIO的最後三個參數就是指定這種組織方式的,具體概念大家到其API Document裡面摳說明去,這裡給出:nPixelSpace, nLineSpace, nBandSpace 三者,如果都為0,則pData中資料的組織是:RRR...RGGG….GBBB...B(三個參數均使用了預設設定),如果設定為(3,0,1),則可以排列成RGBRGBRGB…..(每像素3個資料位元,每行可用資料位元自動,每個波段1個資料位元),後者更便於顯示。當然,Windows位元影像資料顏色排列是BGR,那麼可以設定nBandCount=3,panBandMap=new int[]{3,2,1},這樣讀取波段的順序就是BGR了~
二值Tif圖(1bit TIF 圖)處理
二值圖一般只有一個波段,並且這個波段只有1bit,但是即使如此,GDAL在讀取的時候,GetDataType也返回GDT_Byte,即認為是8bit波段,中間會自動把每個1bit讀出為8bit(值不變,仍只有0和1)。這也許是因為C++中沒有一種合適的資料類型能表示非8bit倍數的資料大小(即使bool是1bit,還有四值圖(2bit),八值圖(3bit)呢)。
統一成8bit對讀和運算處理沒什麼影響,但如果直接以此再Create一個GDALDataset並寫入,映像就會突然變大8倍,因為被寫入為8bit單波段映像了。這時候要使用Tiff的建立選項,Create函數有一個字串數組傳入的建立選項(NBITS=1即建立1bit圖),這方面可以參考:
http://www.gdal.org/frmt_gtiff.html
金字塔(縮圖)
即調用BuildOverView可以建立不同比例的縮圖,GDAL預設會存成.ovr檔案,只能是整數縮小比例。這樣,之後當調用RasterIO以相適應的縮小比例讀取映像時,GDAL會自動使用金字塔中相應比例的縮圖資料,可以極大的提高這個比例映像的顯示處理速度。