TGA文件
结构
TGA的结构比较简单,属于一种图形、图像数据的通用格式,在多媒体领域有很大影响,是计算机生成图像向电视转换的一种首选格式。特点
TGA图像格式最大的特点是可以做出不规则形状的图形、图像文件,一般图形、图像文件都为四方形,若需要有圆形、菱形甚至是缕空的图像文件时,TGA可就派上用场了!优点
TGA格式支持压缩,使用不失真的压缩算法。在工业设计领域,使用三维软件制作出来的图像可以利用TGA格式的优势,在图像内部生成一个Alpha(通道),这个功能方便了在平面软件中的工作。
Tga常见的格式有非压缩RGB和压缩RGB两种格式,文件的第三个Byte位作为标记:2为非压缩RGB格式,10为压缩RGB格式。这里的类只实现读取非压缩格式的tga文件。
先给出tga文件的文件格式:
名称 |
偏移 |
长度 |
说明 |
||
图像信息字段长度 |
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) |
代码如下:
- //========================================================
- /**
- * @file TGALoader.h
- *
- * 项目描述: TGA文件载入类
- * 文件描述: 纹理映射
- * 适用平台: Windows98/2000/NT/XP
- *
- *
- */
- //========================================================
- #ifndef __TGALOADER_H__
- #define __TGALOADER_H__
- #include "stdafx.h"
- /** TGA文件载入类 */
- class CTGALoader
- {
- public:
- CTGALoader(); /**< 构造函数 */
- ~CTGALoader();
- bool LoadTGA(const char *file); /**< 载入TGA文件 */
- void FreeImage(); /**< 释放内存 */
- bool Load(const char* fileName); /**< 载入TGA文件为纹理 */
- unsigned int ID; /**< 生成纹理的ID号 */
- int imageWidth; /**< 图像宽度 */
- int imageHeight; /**< 图像高度 */
- unsigned char *image; /**< 指向图像数据的指针 */
- unsigned int type; /**< 图象类型GL_RGB 或GL_RGBA */
- };
- #endif
- //========================================================
- /**
- * @file TGALoader.cpp
- *
- * 项目描述: 纹理映射
- * 文件描述: TGA文件载入
- * 适用平台: Windows98/2000/NT/XP
- *
- *
- */
- //========================================================
- #include "TGALoader.h"
- /** 构造函数 */
- CTGALoader::CTGALoader()
- {
- /** 设置为默认值 */
- image = 0;
- type = 0;
- ID = -1;
- imageWidth = 0;
- imageHeight = 0;
- }
- /** 析构函数 */
- CTGALoader::~CTGALoader()
- {
- FreeImage(); /**< 释放内存 */
- }
- /** 载入TGA文件 */
- bool CTGALoader::LoadTGA(const char* file)
- {
- FILE *pfile;
- unsigned char tempColor; /**< 用于交换颜色分量 */
- unsigned char bitCount; /**< 每象素的bit位数 */
- int colorMode; /**< 颜色模式 */
- long tgaSize; /**< TGA文件大小 */
- unsigned char unCompressHeader[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /**< 未压缩TGA文件头 */
- unsigned char tgaHeader[12]; /**< 文件头 */
- unsigned char header[6]; /**< 文件头前6个字节 */
- /** 检查文件名是否为空 */
- if(!file)
- return false;
- /** 打开文件 */
- pfile = fopen(file, "rb");
- if(!pfile)
- return false;
- /** 读取文件头前12个字节 */
- fread(tgaHeader, 1, sizeof(tgaHeader), pfile);
- /** 比较文件是否为未压缩文件 */
- if(memcmp(unCompressHeader, tgaHeader, sizeof(unCompressHeader)) != 0)
- {
- MessageBox(NULL,"文件类型错误!","错误",MB_OK);
- fclose(pfile);
- return false;
- }
- /** 读取6个字节(从上面读取的12个字节后再取6个字节) */
- fread(header, 1, sizeof(header), pfile);
- /** 计算图像的宽度和高度 */
- imageWidth = header[1] * 256 + header[0];
- imageHeight = header[3] * 256 + header[2];
- /** 获取每象素的bit位数 */
- bitCount = header[4];
- /** 计算颜色模式和图像大小 */
- colorMode = bitCount / 8;
- tgaSize = imageWidth * imageHeight * colorMode;
- /** 分配内存 */
- image = new unsigned char[sizeof(unsigned char) * tgaSize];
- /** 读取数据 */
- fread(image, sizeof(unsigned char), tgaSize, pfile);
- /** 将BGA格式转化为RGA格式 */
- for(long index = 0; index < tgaSize; index += colorMode)
- {
- tempColor = image[index];
- image[index] = image[index + 2];
- image[index + 2] = tempColor;
- }
- /** 关闭文件 */
- fclose(pfile);
- /** 设置图象类型 */
- if(colorMode == 3)
- type = GL_RGB;
- else
- type = GL_RGBA;
- return true;
- }
- /** 载入TGA文件并创建纹理 */
- bool CTGALoader::Load(const char* fileName)
- {
- if(!LoadTGA(fileName))
- {
- MessageBox(NULL,"载入TGA文件失败!","错误",MB_OK);
- exit(0);
- }
- /** 生成纹理对象名称 */
- glGenTextures(1, &ID);
- /** 创建纹理对象 */
- glBindTexture(GL_TEXTURE_2D, ID);
- /** 控制滤波 */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
- /** 创建纹理 */
- gluBuild2DMipmaps(GL_TEXTURE_2D, type, imageWidth,
- imageHeight, type, GL_UNSIGNED_BYTE,
- image);
- return true;
- }
- void CTGALoader::FreeImage()
- {
- /** 释放内存 */
- if(image)
- {
- delete[] image;
- image = 0;
- }
- }