跳转至

使用 IDL 代码创建分块 TIFF 文件

原文链接: https://www.nv5geospatialsoftware.com/Learn/Blogs/Blog-Details/creating-tiled-tiff-files-with-idl-code

12121 评价此文章:

暂无评分

使用 IDL 代码创建分块 TIFF 文件

匿名作者 2014年6月5日,星期四

下方显示的代码示例,使用了分块图像格式而非标准的TIFF图像格式来写入TIFF图像。标准的TIFF图像使用条带,这些条带横跨整个X维度,并且仅在Y维度上进行分割。根据TIFF规范文档第15节所述:

对于低分辨率到中等分辨率的图像,将图像分解为条带的标准TIFF方法是足够的。然而,对于高分辨率图像,如果图像被分解为大致正方形的图块,而不是水平方向很宽但垂直方向很窄的条带,则访问效率更高,并且压缩效果往往更好。

这是一个快速测试来检查支持的数据类型:

IDL> data = double(dist(800,600))

IDL> tiff6_write, 'test.tif', data & help, read_tiff('test.tif')

<表达式>    DOUBLE   = 数组[800, 600]

IDL> tiff6_write, 'test.tif', float(data) & help, read_tiff('test.tif')

<表达式>    FLOAT    = 数组[800, 600]

IDL> tiff6_write, 'test.tif', ulong(data) & help, read_tiff('test.tif')

<表达式>    ULONG    = 数组[800, 600]

IDL> tiff6_write, 'test.tif', long(data) & help, read_tiff('test.tif')

<表达式>    LONG     = 数组[800, 600]

IDL> tiff6_write, 'test.tif', uint(data) & help, read_tiff('test.tif')

<表达式>    UINT     = 数组[800, 600]

IDL> tiff6_write, 'test.tif', fix(data) & help, read_tiff('test.tif')

<表达式>    INT      = 数组[800, 600]

IDL> tiff6_write, 'test.tif', byte(data) & help, read_tiff('test.tif')

<表达式>   BYTE      = 数组[800, 600]

以下是用于生成分块 TIFF 文件的代码:

**function** **tiff6\_Ifd**, tag, type, count,valueOffset

 **compile\_opt** idl2,logical\_predicate

 typelen = [**1**,**1**,**1**,**2**,**4**,**8**,**1**,**1**,**2**,**4**,**8**,**4**,**8**]

 ifd = { tiff6ifd, tag: **0us**, type: **0us**, count: **0ul**, valueOffset: **0ul** }

 ifd.*tag* = tag

 ifd.*type* = type

 ifd.*count* = count

 len = typelen[type]\*count

 **if** len **le** **4** **then** **begin**

   **case** type **of**

     **3**: ifd.*valueOffset*= **ulong**([**uint**(valueOffset), **0us**],**0**)

     **4**: ifd.*valueOffset*= **ulong**(valueOffset)

     **8**: ifd.*valueOffset*= **ulong**([**fix**(valueOffset), **0s**],**0**)

     **9**: ifd.*valueOffset*= **ulong**(**long**(valueOffset),**0**)

     **11**: ifd.*valueOffset*= **ulong**(**float**(valueOffset),**0**)

     **else**: **if** **max**(type **eq** [**1**,**2**,**6**,**7**]) **then** **begin**

          ifd.*valueOffset* = **ulong**([**byte**(valueOffset), **0b**,**0b**,**0b**],**0**)

       **endif** **else** **message**, 'Unsupported type: '+**strtrim**(type,**2**)

   **endcase**

 **endif** **else** **begin**

   ifd.*valueOffset* = **ulong**(valueOffset)

   **if** **arg\_present**(valueOffset) **then** **begin**

     valueOffset += len

   **endif**

 **endelse**

 **return**, ifd

**end**

 

**pro** **tiff6\_write**, filename, data

 **compile\_opt** idl2,logical\_predicate

 ;header

 byteord = **byte**(**1us**,**0**) ? 'II' : 'MM'

 header = { byteord: byteord, magic: **42us**, ifdOffset: **8ul** }

 numIfd = **18us**

 

 ;determine length and type

 sz = **size**(data, /struct)

 sz.*dimensions* >= **1**

 h = **hash**('BYTE',[**1**,**1**,**1**],'INT',[**8**,**2**,**2**],'UINT',[**3**,**2**,**1**],'LONG',[**9**,**4**,**2**], $

   'ULONG',[**4**,**4**,**1**],'FLOAT',[**11**,**4**,**3**],'DOUBLE',[**12**,**8**,**3**])

 **if** h.**HasKey**(sz.*type\_name*)**then** **begin**

   info = (**orderedhash**(**list**('type','len','frmt'), $

     **list**(h[sz.*type\_name*],/extract))).**ToStruct**()

 **endif** **else** **message**, 'Unsupported type: '+sz.*type\_name*

 

 ;strings need to be 0 terminated and even length

 software = [**byte**('IDL 8.3'),**0b**]

 datetime = [**byte**(**string**(**systime**(/julian), format= $

   '(c(cyi4.4,":",cmoi2.2,":",cdi2.2,"",cHi2.2,":",cmi2.2,":",csi2.2))')),**0b**]

 

 ;compute tile info

 tileSize = **128**

 tileByteSize = info.*len*\*tileSize^**2**

 n = sz.*dimensions*/tileSize + (sz.*dimensions* **mod** tileSize **ne** **0**)

 ntiles = n[**0**]\*n[**1**]

 

 ptr = **8** + **2** + numIfd\***12** + **4**

 

 ;fill in fields

 ifds = **list**()

 ifds.**Add**, **tiff6\_ifd**(**256**, **4**, **1**, sz.*dimensions*[**0**]) ; width

 ifds.**Add**, **tiff6\_ifd**(**257**, **4**, **1**, sz.*dimensions*[**1**]) ; length

 ifds.**Add**, **tiff6\_ifd**(**258**, **3**, **1**, info.*len*\***8**) ; bits

 ifds.**Add**, **tiff6\_ifd**(**259**, **3**, **1**, **1**) ; compression

 ifds.**Add**, **tiff6\_ifd**(**262**, **3**, **1**, **1**) ; photometric interpretation

 ifds.**Add**, **tiff6\_ifd**(**274**, **3**, **1**, **1**) ; orientation

 ifds.**Add**, **tiff6\_ifd**(**277**, **3**, **1**, **1**) ; samples per pixel

 ifds.**Add**, **tiff6\_ifd**(**282**, **5**, **1**, ptr) ; xresolution

 ifds.**Add**, **tiff6\_ifd**(**283**, **5**, **1**, ptr) ; yresolution

 ifds.**Add**, **tiff6\_ifd**(**284**, **3**, **1**, **1**) ; planar configuration

 ifds.**Add**, **tiff6\_ifd**(**296**, **3**, **1**, **2**) ; resolution unit

 ifds.**Add**, **tiff6\_ifd**(**305**, **2**, **n\_elements**(software), ptr) ; software

 ifds.**Add**, **tiff6\_ifd**(**306**, **2**, **n\_elements**(datetime), ptr) ; datetime

 ifds.**Add**, **tiff6\_ifd**(**322**, **4**, **1**, tileSize) ; tile width

 ifds.**Add**, **tiff6\_ifd**(**323**, **4**, **1**, tileSize) ; tile length

 ifds.**Add**, **tiff6\_ifd**(**324**, **4**, ntiles, ptr) ; tile offsets

 ifds.**Add**, **tiff6\_ifd**(**325**, **4**, ntiles, ptr) ; tile byte counts

 ifds.**Add**, **tiff6\_ifd**(**339**, **3**, **1**, info.*frmt*) ; sample format

 

 ;fields that require more data

 aux = **list**()

 aux.**Add**, **ulong**([**100**,**1**])

 aux.**Add**, **ulong**([**100**,**1**])

 aux.**Add**, software

 aux.**Add**, datetime

 aux.**Add**, **ulindgen**(ntiles, start=ptr, increment=tileByteSize)

 tmp = **replicate**(tileByteSize, ntiles)

 aux.**Add**, tmp

 

 **if** numifd **ne** **n\_elements**(ifds) **then** **message**, 'IFD size mismatch'

 ;write to file

 **openw**, lun, filename,/get\_lun

 **writeu**, lun, header

 **writeu**, lun, numIfd

 **writeu**, lun, ifds.**ToArray**()

 **writeu**, lun, **0ul** ; next IFD, formulti image

 **foreach** x, aux **do** **writeu**, lun, x

 tmp = **make\_array**([tileSize,tileSize], type=**size**(data,/type))

 **for** j=**0**, n[**1**]-**1** **do** **begin**

   ys = j\*tileSize

   ye = (j\*tileSize + tileSize-**1**) < (sz.*dimensions*[**1**]-**1**)

   **for** i=**0**, n[**0**]-**1** **do** **begin**

     xs = i\*tileSize

     xe = (i\*tileSize +tileSize-**1**) < (sz.*dimensions*[**0**]-**1**)

     tmp[**0**,**0**] = data[xs:xe,ys:ye]

     **writeu**, lun, tmp

   **endfor**

 **endfor**

 **free\_lun**, lun

**end**

LiDAR 数据的自定义处理:一个 ENVI LiDAR API 示例 一词之谈:变化