继位图之后,我们来看看Tga图片的格式,以及程序实现。
一、 文件格式
Tga常见的格式有非压缩RGB和压缩RGB两种格式,其他格式的我们在这里不做讲述。文件的第三个Byte位作为标记:2为非压缩RGB格式,10为压缩RGB格式。它们的具体格式如下:
1、非压缩格式
图片类型:2-非压缩RGB格式
名称 | 偏移 | 长度 | 说明 | ||
图像信息字段长度 | 0 | 1 | 本字段是 1字节无符号整型,指出图像信息字段(见本子表的后面)长度,其取值范围是 0到 255 ,当它为 0时表示没有图像的信息字段。 | ||
颜色表类型 | 1 | 1 | 0 表示没有颜色表,1 表示颜色表存在。由于本格式是无颜色表的,因此此项通常被忽略。 | ||
图像类型码 | 2 | 1 | 该字段总为 2,这也是此类型为格式 2 的原因。 | ||
颜色表规格字段 | 颜色表首址 | 3 | 2 | 颜色表首的入口索引,整型(低位-高位) | 如果颜色表字段为0,则忽略该字段 |
颜色表的长度 | 5 | 2 | 颜色表的表项总数,整型(低位-高位) | ||
颜色表项位数 | 7 | 1 | 位数(bit),16代表 16 位 TGA,24 代表 24位 TGA ,32代表 32 位 TGA | ||
图像规格字段 | 图像 X坐标起始位置 | 8 | 2 | 图像左下角 X坐标的整型(低位-高位)值 | |
图像 Y坐标起始位置 | 10 | 2 | 图像左下角 Y坐标的整型(低位-高位)值 | ||
图像宽度 | 12 | 2 | 以像素为单位,图像宽度的整型(低位-高位) | ||
图像高度 | 14 | 2 | 以像素为单位,图像宽度的整型(低位-高位) | ||
图像每像素存储占用位数 | 16 | 2 | 它的值为16,24或 32 等等。决定了该图像是 TGA 16,TGA24,TGA 32等等。 | ||
图像描述符字节 | 17 | 1 | bits 3-0 - 每像素对应的属性位的位数; 对于TGA 16,该值为 0或 1,对于 TGA 24,该值为 0,对于 TGA 32,该值为 8。
bit 4 - 保留,必须为 0
bit 5 - 屏幕起始位置标志 0 = 原点在左下角 1 = 原点在左上角 对于 truevision图像必须为 0
bits 7-6 - 交叉数据存储标志 00 = 无交叉 01 = 两路奇/偶交叉 10 = 四路交叉 11 = 保留 | ||
图像信息字段 | 18 | 可变 | 包含一个自由格式的,长度是图像由“图像信息字段”指定。它常常被忽略(即偏移 0处值为 0 ),注意其最大可以含有 255个字符。如果需要存储更多信息,可以放在图像数据之后。 | ||
颜色表数据 | 可变 | 可变 | 如果颜色表类型为 0,则该域不存在,否则越过该域直接读取图像颜色表规格中描述了每项的字节数,为 2,3,4之一。 | ||
图像数据 | 可变 | 可变 | RGB颜色数据,存放顺序为:BBB GGG RRR (AAA) |
2、压缩格式
图片类型:10-压缩RGB格式
名称 | 偏移 | 长度 | 说明 | ||
图像信息字段长度 | 0 | 1 | 本字段是 1字节无符号整型,指出图像信息字段(见本子表的后面)长度,其取值范围是 0到 255 ,当它为 0时表示没有图像的信息字段。 | ||
颜色表类型 | 1 | 1 | 0 表示没有颜色表,1 表示颜色表存在。由于本格式是无颜色表的,因此此项通常被忽略。 | ||
图像类型码 | 2 | 1 | 该字段总为 10,这也是此类型为格式 10 的原因。 | ||
颜色表规格字段 | 颜色表首址 | 3 | 2 | 颜色表首的入口索引,整型(低位-高位) | 如果颜色表字段为0,则忽略该字段 |
颜色表的长度 | 5 | 2 | 颜色表的表项总数,整型(低位-高位) | ||
颜色表项位数 | 7 | 1 | 位数(bit),16代表 16 位 TGA,24 代表 24位 TGA ,32代表 32 位 TGA | ||
图像规格字段 | 图像 X坐标起始位置 | 8 | 2 | 图像左下角 X坐标的整型(低位-高位)值 | |
图像 Y坐标起始位置 | 10 | 2 | 图像左下角 Y坐标的整型(低位-高位)值 | ||
图像宽度 | 12 | 2 | 以像素为单位,图像宽度的整型(低位-高位) | ||
图像高度 | 14 | 2 | 以像素为单位,图像宽度的整型(低位-高位) | ||
图像每像素存储占用位数 | 16 | 2 | 它的值为16,24或 32 等等。决定了该图像是 TGA 16,TGA24,TGA 32等等。 | ||
图像描述符字节 | 17 | 1 | bits 3-0 - 每像素对应的属性位的位数; 对于TGA 16,该值为 0或 1,对于 TGA 24,该值为 0,对于 TGA 32,该值为 8。
bit 4 - 保留,必须为 0
bit 5 - 屏幕起始位置标志 0 = 原点在左下角 1 = 原点在左上角 对于 truevision图像必须为 0
bits 7-6 - 交叉数据存储标志 00 = 无交叉 01 = 两路奇/偶交叉 10 = 四路交叉 11 = 保留 | ||
图像信息字段 | 18 | 可变 | 包含一个自由格式的,长度是图像由“图像信息字段”指定。它常常被忽略(即偏移 0处值为 0 ),注意其最大可以含有 255个字符。如果需要存储更多信息,可以放在图像数据之后。 | ||
颜色表数据 | 可变 | 可变 | 如果颜色表类型为 0,则该域不存在,否则越过该域直接读取图像颜色表规格中描述了每项的字节数,为 2,3,4之一。 | ||
图像数据 | 可变 | 可变 | 采用RLE压缩后的RGB颜色数据。 |
Tga的压缩算法采用了RLE算法,RLE算法的基本思想是将数据分为两大类:
A:连续的不重复字节
B:连续的重复字节
RLE算法应用于RGB格式的图片压缩中,则把数据分为:
A:连续的不重复像素颜色值
B:连续的重复像素颜色值
然后将数据按这两类数据分成若干长度不相等数据块,每个数据块的开始都是一个1个字节长度的header(RLE在纯数据压缩中header位2个字节16位),后面紧跟着data数据块,如下。
Header(1个字节) | Data(变长) |
每个header的第一位作为标记:0表示A类颜色数据,1表示B类颜色数据。剩下的7位意义如下:
对于A类数据:表示data有多少个像素的RGB颜色值。取值0-127,0表示1个像素,所以最多为128个像素,data块则为这些不重复的像素RGB颜色值。
对于B类数据:表示有多少个像素具有相同的RGB颜色值。取值0-127,0表示1个像素,所以最多为128个像素,data仅包含一个像素的颜色值,即为重复的那个颜色值。
注意事项
行对齐:
同位图一样,如果想把tga用于GDI,需要做行对齐处理,而却Tga文件里的数据是没有行对齐的,所以加载必须程序进行行对齐。行对齐的方法如下:
A:计算图片行对齐前每行的字节数:
iRowDataLenOld = m_iImageWidth * m_iImageHeight * m_iBitsPerPixel/8;
B:计算行对齐后的字节数:
iRowDataLenNew= (((m_iImageWidth*m_iBitsPerPixel) + 31) >> 5) << 2;
C:如果iRowDataLenOld=iRowDataLenNew则不需要对齐
D:否则在每行的后面添加iRowDataLenNew-iRowDataLenOld个字节,并以0填充。
BGR->RGB转换:
Tga文件存储颜色数据的格式为BGR(A),如果需要得到RGB(A)格式的数据(如OpenGL中)需要做BGR->RGB转换。
原文的图像每像素存储占用位数有错(16字节处),应该为1个字节