读写TIFF图像函数原理.docx
《读写TIFF图像函数原理.docx》由会员分享,可在线阅读,更多相关《读写TIFF图像函数原理.docx(14页珍藏版)》请在冰豆网上搜索。
读写TIFF图像函数原理
二.读取tiff/tif文件
1.tiff/tif文件结构:
1.tiff/tif文件结构:
TIF图由四部分构成:
图像文件头(IFH),图像文件目录(IFD),目录入口(DE),图像数据;
IFH数据结构包含3个成员共计8个字节。
第一个成员Byteorder可能是“MM”(0x4d4d)或“II”(0x4949),0x4d4d表示该TIFF图是摩托罗拉整数格式0x4949表示该图是Intel整数格式;当Byteorder为”MM”时,则之后的由16或32位数组成的数据都是从高字节到低字节顺序存储的,如果为”II”,则字节存储顺序相反;
第二个成员Version总是包含十进制42(0x2a),它用于进一步校验该文件是否为TIF格式,实际上,42这个数大概永远不会变化;
第三个成员是第一个IFD相对文件开始处的偏移量(最小为8,因为IFH结构已经占据8bytes)。
IFD是TIF图中最重要的数据结构,它包含了一个TIF文件中最重要的信息,一个TIF图可能有一个或多个IFD,这说明文件中有一个或多个图像,每个IFD标识1个图像的基本属性。
IFD结构中包含了三类成员。
第一类(个)成员DirectoryEntryCount(2bytes)指出该结构里面有多少个目录入口;
第二类成员就是N个线性排列的DE(12bytes)序列,数量不定(这就是为什么称TIF格式文件为可扩充标记的文件,甚至用户可以添加自定义的标记属性),每个DE标识了图像的某一个属性;
最后就是一类(个)偏移量(4bytes),标识下一个文件目录相对于文件开始处的位置,当然,如果该TIF文件只包含了一幅图像,那么就只有一个IFD,显然,这个偏移量就等于0;
DE共12字节,一个DE就是一幅图像的某一个属性。
例如图像的大小、相对位置(条带偏移量)、分辨率、是否压缩、像素的行列数、一个像素由几位表示(1位代表黑白两色,8位代表256色等等)等。
其中前两个字节是标记码tag(2bytes)。
公用标记码是大于254(十六进制FE)的标记码,最大是321(141H)。
大于32768(8000H)的是私有码。
tag成员是该属性的编号,在图像文件目录中,它是按照升序排列的。
我们可以通过读这些编号,然后到TIF格式官方白皮书中查找相应的含义。
属性是用数据来表示的,那么type(2bytes)就是代表着该数据的类型,TIF官方指定的有5种数据类型。
1=BYTE8比特无符号整型。
2=ASXII8比特的字节,存储7比特的ASCII码;最后
一个字节必须是NUL(二进制0)。
3=SHORT16比特(2字节)无符号整型。
4=LONG32比特(4字节)无符号整型。
5=RATIONAL两个LONG型:
第一个代表一个分数的分子,第二个是分母。
ASCII部分的长度的值包含NUL。
如果有必要填充,长度将不会包含
填充部分。
需要说明的是没有像Pascal风格的字符串那样的出始长度字节。
任何ASCII域可能包含多个字符串,每个以一个NUL结束。
一个单独的字符串在从我任何可能的时候都是最好的。
多重字符串域的长度是域中所有字符串加上它们结尾的NUL的字节数。
在两个字符串中只能有一个NUL,所以跟在第一个字符串后的字符串经常在奇数个字节处开始。
读取程序必须检查类型来证实它包含了期望的值。
TIFF格式在某些域中目前允许不只一种的有效类型。
例如,图像宽度和图像高度通常指明是SHORT类型。
但是行数多于64000的图像必须用LONG类型在域类型中。
TIFF读取程序对于无符号整型来说应该接受BYTE,SHORT和LONG类型的值。
这允许一个单独的程序来读取任何整型值,使阅读更强大,在某些情况下还节省磁盘。
在TIFF6.0中,一些新的字段类型已经定义:
6=SBYTE一个8比特的有符号整数;
7=UNDEFINED一个8比特的字节,有可能存储任何类型,取决于该字段的定义。
8=SSHORT一个16比特(2字节)的有符号整数。
9=SLONG一个32比特(四字节)的有符号整数。
10=SRATIONAL两个SLONG型:
第一个是分数的分子,第二个是分母。
11=FLOAT单精度(四字节)IEEE类型。
12=DOUBLE双精度(八字节)IEEE类型。
这些新字段类型也受TIFF文件头中字节顺序(II或MM)的制约。
Length(4bytes)成员是数据的数量而不是数据类型的长度(长度为sizeof(type)*length)。
第4个成员valueOffset(4bytes)很重要,它是tag标识的属性代表的变量值相对文件开始处的偏移量。
如果变量值占用的空间(长度)小于4个字节,那么该值就存放在valueOffset中即可,没必要再另外指向一个地方了。
图像数据:
以条带为单位存储;一个图像分为一个条带或多个((width+RawsPerStripz-1)/RawsPerStripe),每个条带存储多行(RawsPerStripe或pRawsPerStrip[i]);一行不够整数个字节的补0,使成整数个字节,再连续存储于条带中;
Tiff/tif文件结构图示
双层图像(黑白图像)
一个双层图像(黑白图像)包含两种颜色-黑色和白色。
TIFF允许程序以白色为0或黑色为0的格式来写出图像。
记录这个信息的字段叫图像颜色方案()。
图像颜色方案
标号=262(106.H)
类型=SHORT
值:
0=白色是0。
对于双层图像和灰度图像来说:
0是描绘白色。
最大值描绘黑色。
这时Compression的正常值2。
1=黑色是0。
对于双层图像和灰度图像来说:
0是描绘黑色。
最大值描绘白色。
Compression的值是2,图像的显示和打印将会是反转的。
Compression
标号=259(103.H)
类型=SHORT
值:
1=没有压缩,但包装成字节的数据尽可能紧密,不会留下没用比特(除
了在一排的最后)。
值元素被存储在一个字节型的数组中。
每个扫描线(行)填充到下一个字节边界。
2=CCITT组31维改良霍夫曼运行长度编码。
见第十节的改良霍夫曼压
缩的描述。
32773=PACKBITS压缩,一个简单的面向字节的运行长度方案。
请参阅PACKBITS部分细节。
数据压缩只应用在光栅图像数据。
所有其它的TIFF字段不受影响。
图像高度
标号=257(101.H)
类型=SHORT或LONG
图像中行(有时被描述成扫描行)的数量。
图像宽度
标号=256(100.H)
类型=SHORT或LONG
图像中列的数量,换名话说,每个扫描行的像素的数量。
分辨率单位
标号=296(128.H)
类型=SHORT
值:
1=没有绝对的测量单位。
用于有非正方形的高宽比,但是没有有意义的绝对尺寸。
2=英寸。
3=厘米。
缺省值=2(英寸)。
水平分辨率
标号=282(11A.H)
类型=RATIONAL
在图像宽度方向上每个分辨率单位有多少个像素(通常指的是水平方向)。
垂直分辨率
标号=283(11B.H)
类型=RATIONAL
在图像高度方向上每个分辨率单位有多少个像素(通常指的是垂直方向)。
每个条带的行数
标号=278(116.H)
类型=SHORT或LONG
每一个条带的行数(除了可能的最后一行。
)
例如,如果图像高度是24,而且行数每个条带是10,就会形成3个条带,其中第一个条带有10行,第二个条带有10行,第三个条带有4行。
(在最后一个条带的数据不会填充额外六行空数据。
)
条带偏移量
标号=273(111.H)
类型=SHORT或LONG
针对每个条带,都有一个字节偏移量。
条带字节数
标号=279(117.H)
类型=SHORT或LONG
针对第一个条带,在任何压缩之后的条带的字节数。
双层图像必须具备的字段
标签名十进制十六进制类型值
图像宽度256100SHORT或LONG
图像高度257101SHORT或LONG
压缩方案259103SHORT1,2或32773
图片颜色方案262106SHORT0或1
条带偏移量273111SHORT或LONG
条带行数278116SHORT或LONG
条带字节娄279117LONG或SHORT
水平分辨率28211ARATIONAL
垂直分辨率28311BRATIONAL
分辨率单位296128SHORT1,2或3
基本TIFF双层图像在以前版本的TIFF说明文档中被叫作B级TIFF图像。
读取tiff/tif二层图像(黑白图像)原理
●将条带读入到内存中的unsignedchar型数组中
●以条带字节数为循环上限,每次从上数组中读取一个字节
●因为二层图像为1bit深度,一个字节循环8次,每次从其中读取一位,每当读出一行像素后,跳出本字节的循环,进行下一个字节的循环
●每读出一位,确定一个像素(R8bits,G8bits,B8bits)。
0->(0xff,0xff,0xff),1->(0x00,0x00,0x00)(图像颜色方案=0);0->(0x00,0x00,0x00),1->(0xff,0xff,0xff)(图像颜色方案=1)。
●将得到的每个像素的R,G,B值连续写入到文件中,得到RAW图像。
fread(ppixels,1,StripByteCounts(pStripByteCounts[i]),stream);//从文件中读出一个条带到内存中
for(inti=0,outpixels=0,r=0;ifor(intj=7;j>=0&&outpixels{
PIXELpixel,tpixel;//定义像素结构体变量
pixel.r=(((~)(ppixels[i]>>j))&1)*0xff;//得出R值
pixel.g=(((~)(ppixels[i]>>j))&1)*0xff;//得出g值
pixel.b=(((~)(ppixels[i]>>j))&1)*0xff;//得出b值
tpixel.b=(((~)(ppixels[i]>>j))&1)*0xff;
tpixel.g=(((~)(ppixels[i]>>j))&1)*0xff;
tpixel.r=(((~)(ppixels[i]>>j))&1)*0xff;
fwrite(&pixel,sizeof(PIXEL),1,ostream);//将像素写入输出文件中
fwrite(&tpixel,sizeof(PIXEL),1,tstream);
outpixels++;
if((outpixels%width)==0)//每读出一行像素,结束该字节循环
break;
}
灰度图像
灰度图像是一般化的二层图像。
二层图像只能存储黑色各白色图像数据,但是灰度图像还能存储灰色的深浅。
图像颜色方案
标号=262(106.H)
类型=SHORT
值:
0=白色是0。
对于双层图像和灰度图像来说:
0是描绘白色。
最大值描绘黑色。
这是Compression的正常值2。
1=黑色是0。
对于双层图像和灰度图像来说:
0是描绘黑色。
最大值描绘白色。
如果
时的Compression的值是2,图像的显示和打印将会是反转的。
和二层图像的差异
Compression=1或32773(PackBits算法)。
在基本TIFF图像文件中,灰度图像能以不压缩方式或PACKBITS算法压缩方式存储。
注意:
PackBits算法对于连续色调图像往往是无效的,包括许多灰度图像。
在这种情况下,不压缩图像是更好的。
样点位数
标号=258(102.H)
类型=SHORT
每个样点的比特数。
基本TIFF灰度图像的允许值为4或8,允许16或256个不同的灰度级别。
灰度图像必须具备的字段
标签名十进制十六进制类型值
图像宽度256100SHORT或LONG
图像高度257101SHORT或LONG
样点位数258102SHORT4或8
压缩方案259103SHORT1或32773
图片颜色方案262106SHORT0或1
条带偏移量273111SHORT或LONG
条带行数278116SHORT或LONG
条带字节数279117LONG或SHORT
水平分辨率28311ARATIONAL
垂直分辨率28311BRATIONAL
分辨率单位296128SHORT1或2或3
基本TIFF灰度图像在早期版本TIFF规范被称为G级的TIFF图像。
Tiff/tif灰度图像的位深度有1,2,4,6,8,10,12,14,16这九种,也就是每个像素分别以1,2,4,6,8,10,12,14,16bits存储。
其中1,2,4,6,8位深度的图像转成R,G,B=(8,8,8)格式存储;10,12,14,16可转换成R,G,B=(16,16,16)格式存储。
读取tiff/tif灰度图像的原理
●
调色板图像
调色板彩色图像和灰度图像相似。
他们仍然是每个像素有一个数据表示,但是这块数据的值是用作对一个完整的RGB的索引表的索引。
为了描述这种数据,你需要加入或是改变以下字段。
其他必备字段和灰度图像中的那些是一样的。
和灰度图像的差异
图像颜色方案=3(调色板彩色)。
颜色分配表
标号=320(140.H)
类型=SHORT
N=3*(
)
这个字段为调色板彩色图像定义了一个红色-绿色-蓝色的颜色分配表(经常叫作一个查找表)。
在一个调色板彩色图像中,一个像素值用来牵引的一个RGB查找表。
例如,一个调色板彩色图像像素有一个值为0,将会根据红,绿,蓝三个的0th个值来显示。
在一个TIFF颜色分配表中,所有的红色值在前面,紧跟着是绿色的值,接下来是蓝色的值。
在颜色分配表中,0,0,0代表黑色,65535,65535,65535代表白色。
颜色表图像必须具备的字段
标签名十进制十六进制类型值
图像宽度256100SHORT或LONG
图像高度257101SHORT或LONG
样点位数258102SHORT4或8
压缩方案259103SHROT1或32773
图片颜色方案262106SHORT3
条带偏移量273111SHORT或LONG
条带行数278116SHORT或LONG
条带字节数279117LONG或SHORT
水平偏移量28211ARATIONAL
垂直偏移是28311BRATIONAL
分辨率单位296128SHORT1或2或3
颜色分配表320140SHORT
在时期TIFF说明文档中基本TIFF调色板彩色图像被称为P级图像。
RGB全彩色图像
在RGB图像中,每个像素由三个部分组成:
红,绿,和蓝色。
没有颜色分配表。
为了描述一个RGB图像,你需要添加或更改以下字段值。
其他的必须具备的字段和调色板彩色图像相同。
和调色板彩色图像的差异
样点位数=8,8,8.在基本TIFFRGB图像中,每个样点部分是8比特深度。
图片颜色方案=2(RGB)。
没有颜色分配表。
像素样点数
标号=277(115.H)
类型=SHORT
每个像素分为几块数。
对于RGB图像来说,这个数量是3,除非还存在其他额外的样点。
有关详细信息,请参阅的额外样点字段。
RGB彩色图像必须具备的字段
标签名十进制十六进制类型值
图像宽度256100SHORT或LONG
图像高度257101SHORT或LONG
样点位数258102SHORT8,8,8
压缩方案259103SHORT1或32773
图片颜色方案262106SHORT2
条带偏移量273111SHORT或LONG
像素样点数277115SHORT3或更多
条带行数278116SHORT或LONG
条带字节数279117LONG或SHORT
水平分辨率28211ARATIONAL
垂直分辨率28311BRATIONAL
分辨率单位296128SHORT1,2或3
2.程序框图
读取tif/tiff图像
Main()函数启动: