用c编译的bmp位图大小为0 bmp字节补齐为什么无法旋转

BMP文件格式详解 - CSDN博客
BMP文件格式详解
BMP文件格式详解(BMP file format)
文件格式,又称为(位图)或是,设备无关位图,是系统中广泛使用的图像文件格式。由于它可以不作任何变换地保存图像像素域的数据,因此成为我们取得数据的重要来源。的图形用户界面()也在它的内建图像子系统中对格式提供了支持。
下面以为分析工具,结合的位图数据结构对文件格式进行一个深度的剖析。
文件的数据按照从文件头开始的先后顺序分为四个部分:
?&&&&&&&&&文件头:提供文件的格式、大小等信息
?&&&&&&&&&位图信息头:提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息
?&&&&&&&&&调色板:可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表
?&&&&&&&&&位图数据:就是图像数据啦
下面结合结构体的定义,通过一个表来分析这四个部分。
我们一般见到的图像以位图像为主,即、、三种颜色各用个来表示,这样的图像我们称为真彩色,这种情况下是不需要调色板的,也就是所位图信息头后面紧跟的就是位图数据了。因此,我们常常见到有这样一种说法:位图文件从文件头开始偏移个字节就是位图数据了,这其实说的是或位图的情况。这也就解释了我们按照这种程序写出来的程序为什么对某些位图文件没用了。
下面针对一幅特定的图像进行分析,来看看在位图文件中这四个数据段的排布以及组成。
我们使用的图像显示如下:
&&&&&&&&&&&&&&&&&
这是一幅位的位图文件,因此它是含有调色板的。
在拉出图像数据进行分析之前,我们首先进行几个约定:
在文件中,如果一个数据需要用几个字节来表示的话,那么该数据的存放字节顺序为“低地址村存放低位数据,高地址存放高位数据”。如数据在内存中的存储顺序为:
这种存储方式称为小端方式与之相反的是大端方式()。对两者的使用情况有兴趣的可以深究一下,其中还是有学问的。
以下所有分析均以字节为序号单位进行。
下面我们对从文件中拉出来的数据进行剖析:
为文件头定义了如下结构体:
typedef&struct&tagBITMAPFILEHEADER&
UINT16&bfT&&&&
DWORD&bfS&
UINT16&bfReserved1;&
UINT16&bfReserved2;&
DWORD&bfOffB
}&BITMAPFILEHEADER;&
对照文件数据我们看到:
:表示这是支持的位图格式。有很多声称开头两个字节必须为才是位图文件,从上表来看应为开头两个字节必须为才是位图文件。
:,通过查询文件属性发现一致。
:这是两个保留段,为。
:。即从文件头到位图数据需偏移字节。我们稍后将验证这个数据。
共有个字节。
位图信息头
同样地,为位图信息头定义了如下结构体:
:这就是说我这个位图信息头的大小为个字节。前面我们已经说过位图信息头一般有个字节,既然是这样,为什么这里还要给一个字段来说明呢?这里涉及到一些历史其实位图信息头原本有很多大小的版本的。我们看一下下表:
于兼容性的考虑,大多数应用使用了旧版的位图信息头来保存文件。而已经过时了因此现在最常用的格式就仅有了。因此,我们在前面说位图信息头的大小为字节。
:,图像宽为像素,与文件属性一致。
:,图像高为像素,与文件属性一致。这是一个正数,说明图像数据是从图像左下角到右上角排列的。
:该值总为。
:表示每个像素占个比特,即该图像共有种颜色。
:,,说明本图像不压缩。
:,图像的大小,因为使用,所以设置为。
:,水平分辨率,缺省。
:,垂直分辨率,缺省。
:说明本位图实际使用的颜色索引数为,与得到的结论一致。
:说明本位图重要的颜色索引数为,与前面得到的结论一致。
下面的数据就是调色板了。前面也已经提过,调色板其实是一张映射表,标识颜色索引号与其代表的颜色的对应关系。它在文件中的布局就像一个二维数组其中表示总的颜色索引数,每行的四个元素分别表示该索引对应的、、和的值,每个分量占一个字节。如不设透明通道时,为。因为前面知道,本图有个颜色索引,因此。索引号就是所在行的行号,对应的颜色就是所在行的四个元素。这里截取一些数据来说明:
&&&&&&&&&&&&&&&&&&&&&&&&&&&
索引:蓝,绿,红,
号:,,,
号:,,,
号:,,,
号:,,,
号:,,,
号:,,,等等。
一共有种颜色,每个颜色占用个字节,就是一共个字节,再加上前面的文件信息头和位图信息头的个字节加起来一共是个字节。也就是说在位图数据出现之前一共有个字节,与我们在文件信息头得到的信息:文件头到文图数据区的偏移为个字节一致!
下面就是位图数据了,每个像素占一个字节,取得这个字节后,以该字节为索引查询相应的颜色,并显示到相应的显示设备上就可以了。
注意:由于位图信息头中的图像高度是正数,所以位图数据在文件中的排列顺序是从左下角到右上角,以行为主序排列的。
也即我们见到的第一个像素是图像最左下角的数据,第二个人像素为图像最后一行第二列的数据,…一直到最后一行的最后一列数据,后面紧接的是倒数第二行的第一列的数据,依此类推。
如果图像是位或是位数据的位图的话,位图数据区就不是索引而是实际的像素值了。下面说明一下,此时位图数据区的每个像素的颜色阵列排布:
位按照的顺序来存储每个像素的各颜色通道的值,一个像素的所有颜色分量值都存完后才存下一个下一个像素,不进行交织存储。
位数据按照的顺序存储,其余与位位图的方式一样。
像素的排布规则与前述一致。
讲完了像素的排列规则以及各像素的颜色分量的排列规则,最后我们谈谈数据的对齐规则。我们知道默认的扫描的最小单位是字节,如果数据对齐满足这个值的话对于数据的获取速度等都是有很大的增益的。因此,图像顺应了这个要求,要求每行的数据的长度必须是的倍数,如果不够需要进行比特填充(以填充),这样可以达到按行的快速存取。这时,位图数据区的大小就未必是图片宽×每像素字节数×图片高能表示的了,因为每行可能还需要进行比特填充。
填充后的每行的字节数为:
&&,其中()为每像素的比特数。
在程序中,我们可以表示为:
这样,位图数据区的大小为:
我们在扫描完一行数据后,也可能接下来的数据并不是下一行的数据,可能需要跳过一段填充数据:
至此,我们通过分析一个具体的位图文件例子详细地剖析了位图文件的组成。需要注意的是:我们讲的主要是机上的位图文件的构成,对于嵌入式平台,可能在调色板数据段与机的不同。如在嵌入式平台上常见的位位图实际上采用的掩模的方式而不是索引的方式来表示图像。此时,在调色板数据段共有四个部分,每个部分为四个字节,实际表示的是彩色版规范。即:
第一个部分是红色分量的掩模
第二个部分是绿色分量的掩模
&第三个部分是蓝色分量的掩模
&第四个部分是分量的掩模(缺省为)
典型的调色板规范在文件中的顺序为为:
00F8&0000为FB00h=0000(二进制),是蓝红分量的掩码。&
  E007&0000为&07E0h=0000(二进制),是绿色分量的掩码。&
 &&1F00&Fh=1111(二进制),是蓝色分量的掩码。&
 &&&设置为0。
将掩码跟像素值进行“与”运算再进行移位操作就可以得到各色分量值。看看掩码,就可以明白事实上在每个像素值的两个字节16位中,按从高到低取5、6、5位分别就是r、g、b分量值。取出分量值后把r、g、b值分别乘以8、4、8就可以补齐每个分量为一个字节,再把这三个字节按BGR组合,放入存储器,就可以转换为24位标准BMP格式了。
这样我们假设在位图数据区有一个像素的数据在文件中表示为02 F1。这个数据实际上应为F102:
&r = (F102 AND F800) && 8 = F0h = 240
&g= (F102&AND&07E0)&& 3 = 20h = 32&
 &b=(F102&AND&001F) && 3 =&10h =16
至此我们就可以显示了。(本文结束)
参考资源:
1.&&&&&&wiki百科&bmp file format&&
2.&&&&&&gwwgle的专栏&BMP格式详解&
3.&&&&&&匿名&BMP格式图像文件详析
4.&&&&&&Singler的专栏位图文件(BMP)格式分析以及程序实现
& & & & & & & & & & & & & & & & & & & & & 转自:/Matrix_Yao/archive//1615295.html
【FILE HEADER 实例图解】14 bytes
typedef struct {&
/* type : Magic identifier,一般为BM(0x42,0x4d) */&
/* File size in bytes,全部的档案大小 */&
unsigned short int reserved1, reserved2; /* 保留位 */&
/* Offset to image data, bytes */&
} FILEHEADER;
type:2 bytes,一般都是'B' (0x42)、'M' (0x4D)size:4 bytes,记录该BMP档的大小,0x436 = 1078 bytesreserved1:保留位,2 bytesreserved2:保留位,2 bytesoffset:4 bytes,0x36 = 54 bytes
【INFO HEADER&实例图解】40 bytes
typedef struct {&
/* Info Header size in bytes */&
int width,/* Width and height of image */&
unsig/* Number of colour planes */&
uns /* Bits per pixel */&
unsi /* Compression type */&
un /* Image size in bytes */&
int xresolution, /* Pixels per meter */&
u /* Number of colours */&
/* Important colours */&
} INFOHEADER;
size:4 bytes,0x28 = 40 bytes,表示Info Header的大长度总共 40 byteswidth:4 bytes,0x10 = 16,图像宽度为16 pixelheight:4 bytes,0x10 = 16,图像高度为16 pixelplanes:2 bytes,0x01 = 1,位元面数为1bits:2 bytes,0x20 = 32,每個pixel需要32bitscompression:4 bytes,0代表不压缩imagesize:4 bytes,0x400 = 1024 bytes,点阵图资料大小为1024 bytesxresolution:4 bytes,水平解析度yresolution:4 bytes,垂直解析度ncolours:4 bytes,点阵图使用的调色板颜色数importantcolours:4 bytes,重要的颜色数
【RAW DATA&实例图解】
刚刚的File Header共14bytes,Info Header为40bytes,「imagesize」 = 1024 bytes,所以「14 + 40 + 1024 = 1078」, 即等于File Header中「size」的大小。下面我只提取部分的资料,反正全部的档案,減去Header档54位元组,剩下的就是点阵图的资料。
在Info Header中的「bits」为32 bits,故四个位元组一组,若24 bits,则三个位元组一组,例子中的长宽各为16,以「Z」字型来看,一列则为16组,即16 X 4 = 64 bytes。注意的是,图中是以A、B、C ~ …的读取顺序来解说,但实际上程序所读取到的通常回是反过来的,即… ~ C、B、A。另外,下图是以「BGRA」排列。
本文已收录于以下专栏:
相关文章推荐
1.说明:如果操作系统是32位,则指针是按32位寻址的,一个字节8位,所以得出其长度为32/8=42.代码void TestPointSize(char cArray[]){ cout int iAr...
最近在做yuv存储为Jpg,这个涉及到jpg的编码压缩,是非常耗性能的,我们目前多用于手机上,在IOS上是通过将yuv 420转为rgb565-&rgb8888然后通过oc提供的函数存储为jpg,整个...
在阅读代码时,遇到了很早之前用过的fseek(),很久没有用了,有点陌生,写出来以便下次查阅。
函数功能是把文件指针指向文件的开头,需要包含头文件stdio.h
  函数名:...
C语言lseek()函数:移动文件的读写位置
#include   #include
定义函数:
网上已经有不少关于c语言函数fread() 和fwrite() 用法分析的文章,在此将这两个函数的用法写下来,是为了巩固所学,加深印象,也为了日后方便查询复习比较,如果能帮助到某些朋友,则是意外的惊喜...
本文继续上一篇文章的内容,介绍一个音频码流处理程序。音频码流在视频播放器中的位置如下所示。本文中的程序是一个AAC码流解析程序。该程序可以从AAC码流中分析得到它的基本单元ADTS frame,并且可...
fseek函数用来设置文件指针stream的位置,原型为:
int fseek(FILE *stream, long offset, int fromwhere);
      下面先对fseek...
fseek函数是 用来设定文件的当前读写位置.函数原型:   int fseek(FILE *fp,long offset,int origin);函数功能:把fp的文件读写位置指针移到指定的位置.f...
前几天在做彩屏显示的时候,我遇到一个把变量输入到彩屏的问题,其中有的变量是int或者double的,但是彩屏厂商提供的库函数只有显示字符的发送函数,所以我就在想能不能把int或者double的强制转换...
因为公司的主要业务是图像识别相关的,因此对图像处理、识别是我学习的重点。虽然写程序也不少年了,但是对于图像处理领域,我还是一个新兵。对很多基础的概念也还是存在盲区,所以想在边学边做的过程中,对一些概念...
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)C语言读取BMP格式图片_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
C语言读取BMP格式图片
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩7页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢bmp - CSDN博客
通过我这些天用C++读写bmp图像的经历,摸索再摸索,终于对bmp文件的结构、操作有了一定的了解,下面就大概介绍bmp图片纯C++的读取、旋转和保存的实现过程。
要用C++读取bmp图片文件,首先要弄清楚bmp格式图片文件的结构。可以参考这篇文章:
有几点需要注意的是:
在读取bmp图片的时候,一定要注意内存对齐的问题,譬如文件头,否则无法读取出正确结果。
关于图片的像素数据,每一行的像素的字节数必须是4的整数倍。如果不是,则需要补齐。一般来说,bmp图像文件的数据是从下到上,从左到右的。即从文件中最先读到的是图像最下面一行的左边第一个像素,然后是坐标第二个.....接下来是倒数第二行的第一个像素。
采用的编译环境是VS2008。
关于图像旋转,并不难。只需要搞清楚像素坐标变换公式就行。我以图像的中心点为坐标原点。先把像素在目标图像中的位置变化为坐标系中的位置,做旋转变换求出变换之前的在坐标系中的坐标,再变换为子啊图片中的位置。
公式:(x1,y1)是变换之前的坐标系中的坐标,(x2,y2)是变换之后的坐标系中的坐标。angle为逆时针旋转的角度数。
x1 = cos(angle)*x2-sin(angle)*y2;
y1 = sin(angle)*x2-cos(angle)*y2;
我的代码分为两个版本:灰度图的和彩色图的。
灰度图是只含亮度信息,不含彩色信息的图像。bmp格式文件中并没有灰度图这个概念,但是我们很容易地用bmp文件来表示灰度图。方法是用256色的调色板,只不过这个调色板有点特殊,每一项的RGB值都是相同的,从(0,0,0),(1,1,1),...,一直到(255,255,255)。这样,灰度图就可以用256色图来表示了。其图像数据就是调色板索引值,也就是实际的RGB的亮度值。另外因为是256色的调色板,所以图像数据中的一个字节代表一个像素。如果是彩色的256色图,图像处理后可能会产生不属于这256色的颜色,所以,图像处理一般采用灰度图。这也可以更好地将重点放在算法上。
下面是灰度图旋转代码,能处理任意尺寸的bmp灰度图,以及旋转任意角度(逆时针)。
代码包括两个文件:BmpRot.h和BmpRot.cpp
BmpRot.h:
BmpRot.cpp:
数据测试:
旋转前和旋转后的对比(45度):
彩色图的处理和灰度图略有不一样。主要是像素数据不同。由于每行数据的字节数必须是4的整数倍,这个地方处理起来要比灰度图麻烦很多,多以暂时还 没做好。本程序的局限性就是只能处理尺寸是4的整数倍的图片,可以旋转任意角度(逆时针)。
参考代码:分两个文件:BmpRot.h和BmpRot.cpp
BmpRot.h:
BmpRot.cpp:
本文已收录于以下专栏:
相关文章推荐
代码来自网络,在此分享:
//GrabScreenToBitmap.h
#ifndef GRABSCREENTOBITMAP_H
#define GRABSCREENTOBITMAP_H
在这里主要用到一个函数:StretchBlt,
以下摘自 Win32 API
函数功能:函数从源矩形中复制一个位图到目标矩形,必要时按目前目标设备设置的模式进行图像的拉伸或压缩。
    函...
Bmp又叫dib文件
任何一个bmp文件都包含这四个信息
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)博客访问: 829797
博文数量: 256
博客积分: 1760
博客等级: 上尉
技术积分: 1612
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: WINDOWS
位图文件(Bitmap-File,BMP)格式是Windows采用的图像文件存储格式,在Windows环境下运行的所有图像处理软件都支持这种格
式。Windows 3.0以前的BMP位图文件格式与显示设备有关,因此把它称为设备相关位图(device-dependent
bitmap,DDB)文件格式。Windows
3.0以后的BMP位图文件格式与显示设备无关,因此把这种BMP位图文件格式称为设备无关位图(device-independent
bitmap,DIB)格式,目的是为了让Windows能够在任何类型的显示设备上显示BMP位图文件。
&&&&& 位图文件可看成由4个部分组成:位图文件头(bitmap-file header)、位图信息头(bitmap-information header)、彩色表(color table)和定义位图的字节阵列。可以文本打开方式打开BMP文件。
(1)文件头信息块
:文件标识,为字母ASCII码“BM”,42 4D。亦或者与19778相比较。:整个文件大小,单位字节。:保留,每字节以“00”填写。000A-000D:记录图像数据区的起始位置。从文件开始到位图数据(bitmap data)之间的偏移量。 (2)图像描述信息块
000E-0011:图像描述信息块的大小,常为28H。:图像宽度。以像素为单位。:图像高度。以像素为单位。001A-001B:图像的plane总数(恒为1)。001C-
001D:记录像素的位数,很重要的数值,图像的颜色数由该值决定。1 - Monochrome bitmap,4 - 16 color
bitmap,8 - 256 color bitmap,F - 16位位图,18 - 24bit (true color) bitmap,20 -
32位位图。
001E-0021:数据压缩方式(数值位0:不压缩;1:8位压缩;2:4位压缩;3:Bitfields压缩)。:图像区数据的大小。单位字节,该数必须是4的倍数。:水平每米有多少像素,在设备无关位图(.DIB)中,每字节以00H填写。002A-002D:垂直每米有多少像素,在设备无关位图(.DIB)中,每字节以00H填写。002E-0031:此图像所用的颜色数。
:指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要。
(3)颜色表(调色板)
&&&&&&颜色表的大小根据所使用的颜色模式而定,其中每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha(32位位图
的透明度值,一般不需要)。对于24-位真彩色图象就不使用彩色表(同样也包括16位、和32位位图),因为位图中的RGB值就代表了每个象素的颜色;而
对于使用索引颜色的,则需要较大的调色板。
(4)图像数据区
颜色表接下来为位图文件的图像数据区,在此部分记录着每点像素对应的颜色索引号,其记录方式也随颜色模式而定,既2色图像每点占1位(8位为1字
节);16色图像每点占4位(半字节);256色图像每点占8位(1字节);真彩色图像每点占24位(3字节)。所以,整个数据区的大小也会随之变化。究
其规律而言,可的出如下计算公式:图像数据信息大小=(图像宽度*图像高度*记录像素的位数)/8。扫描行是由底向上存储的,这就是说,阵列中的第一个字
节表示位图左下角的像素,而最后一个字节表示位图右上角的像素。
&&&&&& 然而,未压缩的图像信息区的大小。除了真彩色模式外,其余的均大于或等于数据信息的大小。这是为什么呢?原因有两个:BMP
文件记录一行图像是以字节为单位的。因此,就不存在一个字节中的数据位信息表示的点在不同的两行中。也就是说,设显示模式位16色,在每个字节分配两个点
信息时,如果图像的宽度为奇数,那么最后一个像素点的信息将独占一个字节,这个字节的后4位将没有意义。接下来的一个字节将开始记录下一行的信息。&
(5)实例分析
&&&& 如下的4x4像素的位图
,经过UE打开成16进制文件后,显示如下:
我们可以通过查找对应的数据位来验证上面所分析的各部分信息。这样就比较清楚了。
(6)位图操作常使用的结构体&
&&&&& 位图头文件结构:
typedef struct tagBITMAPFILEHEADER{&&&& short bfT&&&& int bfS&&&& short bfReserved1;&&&& short bfReserved2;&&&& int bfOffB}BITMAPFILEHEADER, *PBITMAPFILEHEADER;
&&&&& 位图信息结构:
typedef struct tagBITMAPINFOHEADER{&&&&& int biS&&&&& int biW&&&&& int biH&&&& &short biP&&&&& short biBitC&&&& &int biC&&&& &int biSizeI&&&&& int biXPelsPerM&&&& &int biYPelsPerM&&&&& int biClrU&&&&& int biClrI}BITMAPINFOHEADER,*PBITMAPINFOHEADER;
参考原文:
参考原文:
阅读(1600) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。

我要回帖

更多关于 c语言怎么读bmp的字节 的文章

 

随机推荐