TGA文件格式整理
2016-07-15 14:22
741 查看
整理自:
http://dev.gameres.com/Program/Visual/Other/TGAFormat.htm
http://blog.csdn.net/yyfzy/article/details/785948
http://tech.watchstor.com/management-115327.htm
http://baike.baidu.com/subview/18794/7334271.htm?fromtitle=tga%E6%96%87%E4%BB%B6&fromid=10437960&type=syn
感谢以上各位博主。
TGA(Targa)格式是计算机上应用最广泛的图象格式。在兼顾了BMP的图象质量的同时又兼顾了JPEG的体积优势。并且还有自身的特点:通道效果、方向性。在CG领域常作为影视动画的序列输出格式,因为兼具体积小和效果清晰的特点。
TGA的结构比较简单,属于一种图形、图像数据的通用格式,在多媒体领域有很大影响,是计算机生成图像向电视转换的一种首选格式。TGA图像格式最大的特点是可以做出不规则形状的图形、图像文件,一般图形、图像文件都为四方形,若需要有圆形、菱形甚至是缕空的图像文件时,TGA就可以派上用场了。
TGA格式支持压缩,使用不失真的压缩算法。
PC游戏中很多采用TGA格式的图片。
转换为tga格式用ps就可以了。
需要tga查看通道信息,参见:http://blog.codingnow.com/cloud/TgaViewer?show_comments=1
TGA文件存储格式要点:
1)是以小端模式存储的,包括规格定义和RGB数据,也就是BGR形式存放(读取时候直接读入一个unsigned int中就可以了)。
2)看到的图片的左上角一行像素可能放在文件内存中的最后一行(图片y轴可能是世界坐标系的和屏幕坐标系相反),或者文件内存中的第一行就是左上角一行像素。
3) tga头文件记录了调色板偏移大小和规格,和图像像素数据的偏移大小和规格。
4) tga分为压缩编码的和非压缩编码的,压缩算法是采用了RLE算法(数据分为两类3B1G1R1B2G2R2B3G3R3 3B4G4R4的形式,原码为3B1G1R1B2G2R2B3G3R3 B4G4R4B4G4R4B4G4R4)。
(2012-02-24 19:16:45)
转载▼
继位图之后,我们来看看Tga图片的格式,以及程序实现。
一、 文件格式
Tga常见的格式有非压缩RGB和压缩RGB两种格式,其他格式的我们在这里不做讲述。文件的第三个Byte位作为标记:2为非压缩RGB格式,10为压缩RGB格式。它们的具体格式如下:
1、非压缩格式
图片类型:2-非压缩RGB格式
2、压缩格式
图片类型:10-压缩RGB格式
Tga的压缩算法采用了RLE算法,RLE算法的基本思想是将数据分为两大类:
A:连续的不重复字节
B:连续的重复字节
RLE算法应用于RGB格式的图片压缩中,则把数据分为:
A:连续的不重复像素颜色值(3B1G1R1B2G2R2B3G3R3)
B:连续的重复像素颜色值(3B4G4R4)
然后将数据按这两类数据分成若干长度不相等数据块,每个数据块的开始都是一个1个字节长度的header(RLE在纯数据压缩中header位2个字节16位),后面紧跟着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仅包含一个像素的颜色值,即为重复的那个颜色值。
“程序实现”的代码
bool LoadTGA(TextureImage
*texture, char *filename) //
Loads A TGA File Into Memory
{
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; //
Uncompressed TGA Header
GLubyte TGAcompare[12]; //
Used To Compare TGA Header
GLubyte header[6]; //
First 6 Useful Bytes From The Header
GLuint bytesPerPixel; //
Holds Number Of Bytes Per Pixel Used In The TGA File
GLuint imageSize; //
Used To Store The Image Size When Setting Aside Ram
GLuint temp; //
Temporary Variable
GLuint type=GL_RGBA; //
Set The Default GL Mode To RBGA (32 BPP)
FILE *file = fopen(filename, "rb"); //
Open The TGA File
// 1.读取头部
if( file==NULL
|| //
Does File Even Exist?
fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare)
|| // Are There 12 Bytes To Read?且跳过了
memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0 || //
Does The Header Match What We Want?是非压缩的类型2tga
fread(header,1,sizeof(header),file)!=sizeof(header)) //
If So Read Next 6 Header Bytes,读取6字节宽高和位数
{
if
(file == NULL) //
Did The File Even Exist? *Added Jim Strong*
return
FALSE; //
Return False
else //
Otherwise
{
fclose(file); //
If Anything Failed, Close The File
return
FALSE; //
Return False
}
}
// 2.将低位高位存放的数据还原(小端模式,其实用左移8位或上低位刚合适)
texture->width =
header[1] * 256 + header[0]; //
Determine The TGA Width (highbyte*256+lowbyte)高低位组合形式
texture->height = header[3] * 256 + header[2]; //
Determine The TGA Height (highbyte*256+lowbyte)高低位组合形式
if( texture->width <=0 || //
Is The Width Less Than Or Equal To Zero
texture->height <=0 || //
Is The Height Less Than Or Equal To Zero
(header[4]!=24
&& header[4]!=32)) //
Is The TGA 24 or 32 Bit? // bpp需要是24位或者32位的
{
fclose(file); //
If Anything Failed, Close The File
return
FALSE; //
Return False
}
texture->bpp = header[4]; //
Grab The TGA's Bits Per Pixel (24 or 32)
bytesPerPixel = texture->bpp/8; //
Divide By 8 To Get The Bytes Per Pixel
imageSize = texture->width * texture->height * bytesPerPixel; // Calculate The Memory Required For The
TGA Data
// 3.分配内存且读取图像信息
texture->imageData=(GLubyte *)malloc(imageSize); //
Reserve Memory To Hold The TGA Data
// 图像信息字段和颜色表数据是空的, 直接读取未压缩的图像数据
if( texture->imageData==NULL
|| //
Does The Storage Memory Exist?
fread(texture->imageData, 1, imageSize, file)!=imageSize) //
Does The Image Size Match The Memory Reserved?
{
if(texture->imageData!=NULL) //
Was Image Data Loaded
free(texture->imageData); //
If So, Release The Image Data
fclose(file); //
Close The File
return FALSE; //
Return False
}
// 4.将小端模式的BGR(A)转换为RGB(A);除非texture->imageData转换为COLOR时候时再翻转且只用RGB,否则这个转换是没有必要的。
for(GLuint
i=0; i<int(imageSize); i+=bytesPerPixel) //
Loop Through The Image Data
{ //
Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
temp=texture->imageData[i]; //
Temporarily Store The Value At Image Data 'i'
texture->imageData[i]
= texture->imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte
texture->imageData[i + 2] = temp; //
Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
}
fclose (file); //
Close The File
// Build A Texture From The Data
glGenTextures(1, &texture[0].texID); //
Generate OpenGL texture IDs
glBindTexture(GL_TEXTURE_2D, texture[0].texID); //
Bind Our Texture
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtered
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtered
if (texture[0].bpp==24) //
Was The TGA 24 Bits
{
type=GL_RGB; //
If So Set The 'type' To GL_RGB
}
glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);
return true; //
Texture Building Went Ok, Return True
}
http://dev.gameres.com/Program/Visual/Other/TGAFormat.htm
http://blog.csdn.net/yyfzy/article/details/785948
http://tech.watchstor.com/management-115327.htm
http://baike.baidu.com/subview/18794/7334271.htm?fromtitle=tga%E6%96%87%E4%BB%B6&fromid=10437960&type=syn
感谢以上各位博主。
TGA(Targa)格式是计算机上应用最广泛的图象格式。在兼顾了BMP的图象质量的同时又兼顾了JPEG的体积优势。并且还有自身的特点:通道效果、方向性。在CG领域常作为影视动画的序列输出格式,因为兼具体积小和效果清晰的特点。
TGA的结构比较简单,属于一种图形、图像数据的通用格式,在多媒体领域有很大影响,是计算机生成图像向电视转换的一种首选格式。TGA图像格式最大的特点是可以做出不规则形状的图形、图像文件,一般图形、图像文件都为四方形,若需要有圆形、菱形甚至是缕空的图像文件时,TGA就可以派上用场了。
TGA格式支持压缩,使用不失真的压缩算法。
PC游戏中很多采用TGA格式的图片。
转换为tga格式用ps就可以了。
需要tga查看通道信息,参见:http://blog.codingnow.com/cloud/TgaViewer?show_comments=1
TGA文件存储格式要点:
1)是以小端模式存储的,包括规格定义和RGB数据,也就是BGR形式存放(读取时候直接读入一个unsigned int中就可以了)。
2)看到的图片的左上角一行像素可能放在文件内存中的最后一行(图片y轴可能是世界坐标系的和屏幕坐标系相反),或者文件内存中的第一行就是左上角一行像素。
3) tga头文件记录了调色板偏移大小和规格,和图像像素数据的偏移大小和规格。
4) tga分为压缩编码的和非压缩编码的,压缩算法是采用了RLE算法(数据分为两类3B1G1R1B2G2R2B3G3R3 3B4G4R4的形式,原码为3B1G1R1B2G2R2B3G3R3 B4G4R4B4G4R4B4G4R4)。
TGA文件内部格式及程序实现
(2012-02-24 19:16:45)转载▼
标签:
| 分类: 图形内部格式 |
一、 文件格式
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颜色数据。 |
A:连续的不重复字节
B:连续的重复字节
RLE算法应用于RGB格式的图片压缩中,则把数据分为:
A:连续的不重复像素颜色值(3B1G1R1B2G2R2B3G3R3)
B:连续的重复像素颜色值(3B4G4R4)
然后将数据按这两类数据分成若干长度不相等数据块,每个数据块的开始都是一个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仅包含一个像素的颜色值,即为重复的那个颜色值。
“程序实现”的代码
bool LoadTGA(TextureImage
*texture, char *filename) //
Loads A TGA File Into Memory
{
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; //
Uncompressed TGA Header
GLubyte TGAcompare[12]; //
Used To Compare TGA Header
GLubyte header[6]; //
First 6 Useful Bytes From The Header
GLuint bytesPerPixel; //
Holds Number Of Bytes Per Pixel Used In The TGA File
GLuint imageSize; //
Used To Store The Image Size When Setting Aside Ram
GLuint temp; //
Temporary Variable
GLuint type=GL_RGBA; //
Set The Default GL Mode To RBGA (32 BPP)
FILE *file = fopen(filename, "rb"); //
Open The TGA File
// 1.读取头部
if( file==NULL
|| //
Does File Even Exist?
fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare)
|| // Are There 12 Bytes To Read?且跳过了
memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0 || //
Does The Header Match What We Want?是非压缩的类型2tga
fread(header,1,sizeof(header),file)!=sizeof(header)) //
If So Read Next 6 Header Bytes,读取6字节宽高和位数
{
if
(file == NULL) //
Did The File Even Exist? *Added Jim Strong*
return
FALSE; //
Return False
else //
Otherwise
{
fclose(file); //
If Anything Failed, Close The File
return
FALSE; //
Return False
}
}
// 2.将低位高位存放的数据还原(小端模式,其实用左移8位或上低位刚合适)
texture->width =
header[1] * 256 + header[0]; //
Determine The TGA Width (highbyte*256+lowbyte)高低位组合形式
texture->height = header[3] * 256 + header[2]; //
Determine The TGA Height (highbyte*256+lowbyte)高低位组合形式
if( texture->width <=0 || //
Is The Width Less Than Or Equal To Zero
texture->height <=0 || //
Is The Height Less Than Or Equal To Zero
(header[4]!=24
&& header[4]!=32)) //
Is The TGA 24 or 32 Bit? // bpp需要是24位或者32位的
{
fclose(file); //
If Anything Failed, Close The File
return
FALSE; //
Return False
}
texture->bpp = header[4]; //
Grab The TGA's Bits Per Pixel (24 or 32)
bytesPerPixel = texture->bpp/8; //
Divide By 8 To Get The Bytes Per Pixel
imageSize = texture->width * texture->height * bytesPerPixel; // Calculate The Memory Required For The
TGA Data
// 3.分配内存且读取图像信息
texture->imageData=(GLubyte *)malloc(imageSize); //
Reserve Memory To Hold The TGA Data
// 图像信息字段和颜色表数据是空的, 直接读取未压缩的图像数据
if( texture->imageData==NULL
|| //
Does The Storage Memory Exist?
fread(texture->imageData, 1, imageSize, file)!=imageSize) //
Does The Image Size Match The Memory Reserved?
{
if(texture->imageData!=NULL) //
Was Image Data Loaded
free(texture->imageData); //
If So, Release The Image Data
fclose(file); //
Close The File
return FALSE; //
Return False
}
// 4.将小端模式的BGR(A)转换为RGB(A);除非texture->imageData转换为COLOR时候时再翻转且只用RGB,否则这个转换是没有必要的。
for(GLuint
i=0; i<int(imageSize); i+=bytesPerPixel) //
Loop Through The Image Data
{ //
Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
temp=texture->imageData[i]; //
Temporarily Store The Value At Image Data 'i'
texture->imageData[i]
= texture->imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte
texture->imageData[i + 2] = temp; //
Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
}
fclose (file); //
Close The File
// Build A Texture From The Data
glGenTextures(1, &texture[0].texID); //
Generate OpenGL texture IDs
glBindTexture(GL_TEXTURE_2D, texture[0].texID); //
Bind Our Texture
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtered
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtered
if (texture[0].bpp==24) //
Was The TGA 24 Bits
{
type=GL_RGB; //
If So Set The 'type' To GL_RGB
}
glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);
return true; //
Texture Building Went Ok, Return True
}
相关文章推荐
- Skia深入分析5——skia文字绘制的实现
- Skia深入分析5——skia文字绘制的实现
- Skia深入分析3——skia图片绘制的实现(1)
- Skia深入分析3——skia图片绘制的实现(1)
- PNG
- 搭建VTK+ITK+Python系统
- 例程:如何使用PX2硬编码H.264 [CODE_PX2]Encode_H264
- 例程:如何使用PX2硬编码H.264 [CODE_PX2]Encode_H264
- 快速像素混合插值
- java学习脚印:深入java绘图机制
- 高斯滤波器-这个我觉得讲的最好
- 一种基于轮廓的自由图像变形算法
- Skia深入分析3——skia图片绘制的实现(1)
- Skia深入分析3——skia图片绘制的实现(2)
- Skia深入分析5——skia文字绘制的实现
- Skia深入分析6——skia中图像编解码代码概述
- 什么是Bayer格式图像?
- 关于中值滤波算法,以及C语言实现
- DDA算法和Bresenham算法生成直线
- 使用 WIC 对 Windows Vista 图标进行解码