Tga图片格式分析以及程序实现
继位图之后,我们来看看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仅包含一个像素的颜色值,即为重复的那个颜色值。
关于RLE代码的实现,可以参考本文后面的“程序实现”部分的代码。
二、 程序实现
好了,弄清楚了文件格式后,编写程序就不是个难事清了。为了读取方便,我定义了结构体来表示Tga文件头:
//------------------------------------------------
// Name:TgaHeader
// Introduce:The tga header information in file
//------------------------------------------------
typedef struct tagTgaHeader
{
BYTE ubImageInfoByteCnt; //The image information length, in byte
BYTE ubColorTableExist; //0-have not color table,1-have
BYTE ubImageType; //Image type,2-uncompare RGB image,10-compare RGB image
BYTE ubColorTableInfo[5]; //Color table information
BYTE ubImageInfo[10]; //Image information
}TgaHeader, *LPTGAHEADER;
//------------------------------------------------
1、文件头信息
//Load the file header
TgaHeader header;
memset(&header, 0, sizeof(header));
is.read((char*)&header, sizeof(header));
if(header.ubImageType != 2 && header.ubImageType != 10)
return false;
2、获取图像规格信息
//Get image size
m_iImageWidth = (header.ubImageInfo[5]<<8) + header.ubImageInfo[4];
m_iImageHeight = (header.ubImageInfo[7]<<8) + header.ubImageInfo[6];
m_iBitsPerPixel = header.ubImageInfo[8];
if( m_iImageWidth <=0 || m_iImageHeight <= 0 ||
(m_iBitsPerPixel != 24 && m_iBitsPerPixel != 32))
return false;
m_iImageDataSize = m_iImageWidth * m_iImageHeight * m_iBitsPerPixel/8;
3、读取图片信息字段
//Load the image information
char info[255] = {'/0'};
is.read(info, header.ubImageInfoByteCnt);
4、读取图片数据
对于非压缩格式(header.ubImageType = 2),我们可以直接读取:
//Load image data
if(m_pImageData) delete []m_pImageData;
m_pImageData = new unsigned char[m_iImageDataSize];
is.read((char*)m_pImageData, m_iImageDataSize);
对于压缩格式(header.ubImageType = 10),我们要按照RLE算法解码:
if(m_pImageData) delete []m_pImageData;
m_pImageData = new unsigned char[m_iImageDataSize];
int iBytePerPixel = m_iBitsPerPixel/8;
int iPixelCnt = m_iImageWidth * m_iImageHeight;
int iCurPixel = 0;
unsigned char ucColorBuffer[4] = {'/0'};
do{
BYTE chunkheader = 0;
is.read((char*)&chunkheader, sizeof(BYTE));
//run length data
if(chunkheader & 0x80)
{
int iCnt = (chunkheader & 0x7f) + 1;
is.read((char*)ucColorBuffer, iBytePerPixel);
for(int i = 0; i < iCnt; i++)
{
m_pImageData[iCurPixel*iBytePerPixel + 0] = ucColorBuffer[0];
m_pImageData[iCurPixel*iBytePerPixel + 1] = ucColorBuffer[1];
m_pImageData[iCurPixel*iBytePerPixel + 2] = ucColorBuffer[2];
if(m_iBitsPerPixel == 32)
{
m_pImageData[iCurPixel*iBytePerPixel + 3] = ucColorBuffer[3];
}
iCurPixel++;
if(iCurPixel > iPixelCnt)
return false;
}
}
//no processed data
else
{
int iCnt = chunkheader + 1;
for(int i = 0; i < iCnt; i++)
{
is.read((char*)ucColorBuffer, iBytePerPixel);
m_pImageData[iCurPixel*iBytePerPixel + 0] = ucColorBuffer[0];
m_pImageData[iCurPixel*iBytePerPixel + 1] = ucColorBuffer[1];
m_pImageData[iCurPixel*iBytePerPixel + 2] = ucColorBuffer[2];
if(m_iBitsPerPixel == 32)
{
m_pImageData[iCurPixel*iBytePerPixel + 3] = ucColorBuffer[3];
}
iCurPixel++;
if(iCurPixel > iPixelCnt)
return false;
}
}
}while(iCurPixel < iPixelCnt);
5、注意事项
行对齐:
同位图一样,如果想把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转换。
Tga图片格式分析以及程序实现相关推荐
- 如何将Tga图片格式变成jpg格式?
如何将Tga图片格式变成jpg格式?Tga格式是电脑中使用比较成熟的图片格式之一,它的存在既保证图片质量的同时又能保持较小的体积优势,格式支持压缩,使用不失真的压缩算法,已被国际上的图形.图像工业所接 ...
- NOKIA、MOTOROLA、SIMENS及ERICCSON铃声和图片格式分析(转)
NOKIA.MOTOROLA.SIMENS及ERICCSON铃声和图片格式分析 最近一直有些朋友们要求总结一下主流手机铃声和图片的问题,由于本人在这方面基本没有什么尝试,只能将有些朋友们发表过的东西总 ...
- BMP图片格式分析(超详细)
文章目录 前言 一.BMP格式概览 二.实战分析bmp图片数据 前言 对学习C++感兴趣的可以看看这篇文章哦:C/C++教程 BMP图片大家见的应该也比较多,它是一种非常基本的图片格式 因为最近对C+ ...
- 位图文件(BMP)格式分析以及程序实现
最近正在着手开发一个图片库,也就是实现对常见图片格式的度写操作.作为总结与积累,我会把这些图片格式以及加载的实现写在我的Blog上. 说到图片,位图(Bitmap)当然是最简单的,它Windows显示 ...
- PNG图片格式分析格式
PNG文件格式 PNG总体格式 一个PNG文件是由8字节的文件标志和按照特定结构组织的3个以上的数据块(chunk)构成的,结构如所示.具体结构如图1.图2所示 PNG文件结构 图1 包含调色板数据 ...
- Canon CR2图片格式分析
首先是8个字节的文件头. CR2的前2个字节是"II",代表INTEL格式的存储顺序,即低字节在前,高字节在后. 接下来是固定的2个字节:0x2a00. 最后的4个字节的整数是指向 ...
- 【小程序】小程序图像处理:图片配色分析
背景 小程序的canvas是微信基于原生组件自行封装的,因此接口跟web的canvas有不少区别,早期更是没有支持像素级的处理能力. 在18年初的小程序基础库1.9.0版本更新中,出现了wx.canv ...
- 全面掌握移动端主流图片格式的特点、性能、调优等
1.引言 图片通常是移动端应用流量耗费最多的部分,并且占据着重要的视觉空间.以大家最常用的即时通讯IM应用为例,应用中存在大量的图片数据往来(比如图片消息.用户相册.用户头像等等).合理的图片格式选用 ...
- 【数据压缩2】TGA格式图片文件分析
一.TGA文件概述 1.什么是TGA格式图像? tga是由美国Truevision公司为其显示卡开发的一种图像文件格式,已被国际上的图形.图像工业所接受.现已成为数字化图像,以及运用光 ...
最新文章
- oracle exp/imp命令详解
- 由event target引发的关于事件流的一连串思考(二)
- Academic English Reading Notes
- WCF技术剖析之十一:异步操作在WCF中的应用(上篇)
- Android Studio运行报错:无法访问XXX......请删除该文件或确保该文件位于正确的类路径子目录中
- 对于公司,也是我对软件行业,软件项目的五想法
- ajax代码原理,关于Ajax的原理以及代码封装详解
- java布尔类型比较器_浅谈Java中几种常见的比较器的实现方法
- [导入]关于中文文本的截取
- 公交车刮擦 两名驾驶员丢下乘客下车“开战”
- 推荐 System Repair Engineer(SREng)2.4.12.806 版本
- chorme唤起Java开发的本地程序全采坑记
- 新手入门刷题(专题二)排序 (第一部分)
- isdigit()函数如何判断负数
- 关于商业智能BI,你需要知道的相关知识都在这里了
- WiFi的单频和双频
- 计算机内存不足黑屏怎么办,win10内存不足会黑屏吗_win10电脑内存不足黑屏了怎么办...
- Python str(float) 科学计数法
- STM32-外部中断详解
- 教你用Ossim平台检测网络的Shellcode攻击
热门文章
- 如何提升广告ROI?转化跟踪了解一下
- 段码式显示屏和背光电路怎么设计?
- Matlab图片预处理——截取图片中有效部分保存在其余文件夹下
- 我的上司叫“专横”,驾驭他小case,情商修炼术
- oracle 纵列 转 横列,oracle sql小结(主要讲横列转换的例子)decode 以及case
- 用户的虚拟地址 linux 0 4gb,Linux驱动虚拟地址和物理地址的映射
- android横屏分辨率,android适配不同分辨率hdpi、mdpi、ldpi横屏竖屏
- 兔子繁衍问题—c语言
- 首次使用阿帕奇下的ab测压工具测试程序
- 计算机组成原理 浮点运算和浮点运算器 练习题