Tag Image File Format(TIFF)圖像文件是圖形圖像處理中常用的格式之一, 它的圖像格式很復雜, 但由于它對圖像信息的存放靈活多變,它可以支持很多色彩系統,而且獨立于操作系統, 因此TIFF得到了廣泛的應用。
在各種地理信息系統、攝影測量與遙感等應用中, 都要求圖像具有地理編碼信息, 例如圖像所在的坐標系、比例尺、圖像上點的坐標、經緯度、長度單位及角度單位等等。對于存儲和讀取這些信息,純TIFF 格式的圖像文件是很難做到的,而是GeoTIFF 作為TIFF 的一種擴展, 在TIFF 的基礎上定義了 一些GeoTag (地理標簽),從而對各種坐標系統、橢球基準、投影信息等進行定義和存儲,使圖像數據和地理數據存儲在同一圖像文件中, 這樣就為廣大用戶制作和使用帶有地理信息的圖像提供了方便的途徑。
GeoTiff只是Tiff的一種特例,但要遵循規范來用好它卻不是那么簡單。
1 GeoTiff利用Tiff表達Geo(地理)信息的思想
添加微信好友, 獲取更多信息
復制微信號
Tiff對GeoTiff的支持已寫入了Tiff6.0,也就是說,GeoTiff是一種Tiff6.0文件,它繼承了在Tiff6.0規范中的相應部分,所有的GeoTiff特有的信息都編碼在Tiff的一些預留Tag(標簽)中,它沒有自己的IFD(圖像文件目錄)、二進制結構以及其它一些對Tiff來說不可見的信息。
用來描述GeoTiff流行的眾多影射參數及類型信息,如果每一個信息都采用一個標簽那將至少需要幾十甚至幾百個標簽,這會耗盡Tiff定義的有限的標簽資源,另一方面,雖然私有的IFD提供了數千個自由的標簽,但也是有限的,因為標簽值對不理解的讀者來說是不可見的 (因為他們不知道IFD_OFFSET標簽值指向一個私有的IFD)。
為了避免這些問題,GeoTiff采用一系列的Keys(鍵)來存取這些信息,這些鍵在功能上相當于標簽,但它處在TIFF上抽象更上一層。準確的說它是一種媒介標簽(Meta-Tag)。鍵與格式化的標簽值一起共存,TIFF文件處理其它圖像數據。和標簽一樣,鍵也有的ID號,范圍從0到65535,但不像標簽那樣,所有鍵的ID號都可以用于GeoTiff的參數定義上。
2 結構與定義
鍵也稱為GeoKeys,所有鍵都是由Geo Key Directory Tag標簽來索引,這個標簽就相當于表示Geo信息的鍵的一個目錄。它的結構如下:
GeoKeyDirectoryTag:
Tag = 34735 (87AF.H)
Type = SHORT (2-byte unsigned short)
N = variable, >= 4
Alias: ProjectionInfoTag, CoordSystemInfoTag
Owner: SPOT Image, Inc.
它由頭和鍵實體構成,如下:
Header={KeyDirectoryVersion, KeyRevision, MinorRevision, NumberOfKeys}
KeyEntry = { KeyID, TIFFTagLocation, Count, Value_Offset }
其中,TIFF Tag Location表示哪個tag存放值,如果值為0,則表示值為SHORT類型且包含在Value_Offset元素中;否則,其值類型由tag含有值的TIFF-Type暗指。
所有Key值不是short類型的都存放在下面兩種Tag下,基于下面的結構:
GeoDoubleParamsTag:
Tag = 34736 (87BO.H)
Type = DOUBLE (IEEE Double precision)
N = variable
Owner: SPOT Image, Inc.
注:該tag用來存放DOUBLE型的GeoKeys,被GeoKeyDirectoryTag引用,這個double數組中任何值的意義由指向它的GeoKeyDirectoryTag引用決定。FLOAT值必須先轉換為DOUBLE才能存儲。
GeoAsciiParamsTag:
Tag = 34737 (87B1.H)
Type = ASCII
Owner: SPOT Image, Inc.
N = variable
例:
GeoKeyDirectoryTag=( 1, 1, 2, 6,
1024, 0, 1, 2,
1026, 34737,12, 0,
2048, 0, 1, 32767,
2049, 34737,14, 12,
2050, 0, 1, 6,
2051, 34736, 1, 0 )
GeoDoubleParamsTag(34736)=(1.5)
GeoAsciiParamsTag(34737)=("Custom File|My Geographic|")
之一行表明這是一個版本號為1的GeoTIFF GeoKey目錄,鍵的版本為Rev. 1.2,在這個標簽中定義了6個鍵。
下一行定義之一個鍵(ID=1024 = GTModelTypeGeoKey),值為2(Geographic),直接放在元素列表中(因為TIFFTagLocation=0);
下一行鍵1026(the GTCitationGeoKey),列在GeoAsciiParamsTag(34737)數組中開始于偏移0,數到第12個字節,所以其值為"Custom File"("|"被轉換為結束符了)
再下面一行,鍵2051(GeogLinearUnitSizeGeoKey) 位于GeoDoubleParamsTag
(34736), 偏移為0所以值為1.5
key2049的值為(GeogCitationGeoKey) is "My Geographic"。
3 GeoTIFF中坐標系
Geotiff設計使得標準的地圖坐標系定義可以以一個單一的注冊的標簽的形式隨意存儲。也支持非標準坐標系的描述,為了在不同的坐標系間轉換,可以通過使用三四個另設的TIFF標簽來實現。
然而,為了在各種不同的客戶端和GeoTIFF提供者間正確交換,更好要建立一個通能的系統來描述地圖投影。
在TIFF/GeoTIFF框架下,主要有3種不同的空間可供坐標系定義,這3種空間是:
1.光柵空間(圖像空間)R,用于在一幅圖像中表示象素值;
a)在標準TIFF6.0中定義了與光柵空間R與設備空間相關的標簽: 如顯示器、掃描儀、或打印機
2.設備空間D;
3.模型空間M,用于表示地球上的點。
a)地理坐標系
b)地心坐標系
c)投影坐標系
d)垂直坐標系
下面是從GeoTIFF的觀點上來看,這3種空間的使用以及它們相應的坐標系。
4 讀寫程序
講到這兒,我們來了解一下我們如何來讀寫這類GeoTiff文件,我們的目標只有一個,我們將規范中要求的鍵值寫入到文件并能讀出,所幸的事,這些工作別人已經做了,這就是著名的LibGeoTiff,它是在LibTiff基礎上實現的。
它的主要讀寫函數原型如下:
GTIFFree(): Free GeoTIFF access handle. GTIFGetDefn(): Read and Normalize GeoTIFF Definition. GTIFKeyGet(): Read GeoTIFF GeoKey. GTIFKeySet(): Write GeoTIFF GeoKey. GTIFNew(): Create GeoTIFF access handle. GTIFWriteKeys(): Flush GeoTIFF Keys. SetCSVFilenameHook(): Override CSV File Searching. XTIFFClose(): Close GeoTIFF file. XTIFFOpen(): Open GeoTIFF file. 下面是一個例程makegeo.c:
#include "geotiffio.h" #include "xtiffio.h" #include void SetUpTIFFDirectory(TIFF *tif); void SetUpGeoKeys(GTIF *gtif); void WriteImage(TIFF *tif); #define WIDTH 20L #define HEIGHT 20L void main() { char *fname = "newgeo.tif"; TIFF *tif=(TIFF*)0; GTIF *gtif=(GTIF*)0; tif=XTIFFOpen(fname,"w"); if (!tif) goto failure; gtif = GTIFNew(tif); if (!gtif) { printf("failed in GTIFNewn"); goto failure; } SetUpTIFFDirectory(tif); SetUpGeoKeys(gtif); WriteImage(tif); GTIFWriteKeys(gtif); GTIFFree(gtif); XTIFFClose(tif); exit (0); failure: printf("failure in makegeon"); if (tif) TIFFClose(tif); if (gtif) GTIFFree(gtif); exit (-1); } void SetUpTIFFDirectory(TIFF *tif) { double tiepoints[6]={0,0,0,130.0,32.0,0.0}; double pixscale[3]={1,1,0}; TIFFSetField(tif,TIFFTAG_IMAGEWIDTH, WIDTH); TIFFSetField(tif,TIFFTAG_IMAGELENGTH, HEIGHT); TIFFSetField(tif,TIFFTAG_COMPRESSION, COMPRESSION_NONE); TIFFSetField(tif,TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); TIFFSetField(tif,TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE, 8); TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP, 20L); TIFFSetField(tif,TIFFTAG_GEOTIEPOINTS, 6,tiepoints); TIFFSetField(tif,TIFFTAG_GEOPIXELSCALE, 3,pixscale); } void SetUpGeoKeys(GTIF *gtif) { GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic); GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea); GTIFKeySet(gtif, GTCitationGeoKey, TYPE_ASCII, 0, "Just An Example"); GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, KvUserDefined); GTIFKeySet(gtif, GeogCitationGeoKey, TYPE_ASCII, 0, "Everest Ellipsoid Used."); GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, Angular_Degree); GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, Linear_Meter); GTIFKeySet(gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT, 1, KvUserDefined); GTIFKeySet(gtif, GeogEllipsoidGeoKey, TYPE_SHORT, 1, Ellipse_Everest_1830_1967_Definition); GTIFKeySet(gtif, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1, (double)6377298.556); GTIFKeySet(gtif, GeogInvFlatteningGeoKey, TYPE_DOUBLE, 1, (double)300.8017); } void WriteImage(TIFF *tif) { int i; char buffer[WIDTH]; memset(buffer,0,(size_t)WIDTH); for (i=0;i
來源:開源地理空間基金會中文分會
來源鏈接:https://www.osgeo.cn/post/134b7
本站聲明:網站內容來源于 *** ,如有侵權,請聯系我們,我們將及時處理。