【转】最经典格式之BMP图片格式,转来的~
- 博客分类:
- 技术杂绘
【转】最经典格式之BMP图片格式,转来的~
2010年08月14日
以C:\WINDOWS\Blue Lace 16.bmp为例,简要说明一下bmp图片的结构。这张图片是一张典型的4位、16色的bmp图片,每台电脑上都应该有这张图片。在说明之前请安装好UltraEdit软件以便察看bmp图片的16进制值。
一个bmp图片由3大部分组成:BITMAPFILEHEADER结构体,BITMAPINFO结构体,DIB数据区。其中DIB意思就是 Device-Independent Bitmap(设备无关位图)。两个结构体的定义如下:(注意Integer类型占2个字节,Long类型占4个字节)
Private Type BITMAPFILEHEADER // 14 bytes
bfType As Integer
bfSize As Long
bfReserved1 As Integer
bfReserved2 As Integer
bfOffBits As Long
End Type
Private Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors As RGBQUAD
End Type
其中BITMAPINFO结构体中还有两个子结构体,分别定义如下:
Private Type BITMAPINFOHEADER '40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Private Type RGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
rgbReserved As Byte
End Type
下面用UltraEdit打开C:\WINDOWS\Blue Lace 16.bmp察看其16进制数据。
一个bmp文件以BITMAPFILEHEADER结构体开始,BITMAPFILEHEADER的第1个属性是bfType(2字节),这里恒定等于&H4D42。由于内存中的数据排列高位在左,低位在右,所以内存中从左往右看就显示成(42 4D),所以在UltraEdit中头两个字节显示为(42 4D)就是这样形成的,以后的数据都是这个特点,不再作重复说明。
BITMAPFILEHEADER的第2个属性是bfSize(4字节),表示整个bmp文件的大小,这里等于&H000004F8=1272字节。
BITMAPFILEHEADER的第3个、第4个属性分别是bfReserved1、bfReserved2(各2字节),这里是2个保留属性,都为0,这里等于&H0000、&H0000。
BITMAPFILEHEADER的第5个属性是bfOffBits(4字节),表示DIB数据区在bmp文件中的位置偏移量,这里等于&H00000076=118,表示数据区从文件开始往后数的118字节开始。
BITMAPFILEHEADER结构体这里就讲完了,大家会发现BITMAPFILEHEADER只占了bmp文件开始的14字节长度,但需要特别说明的是在vb中定义一个BITMAPFILEHEADER结构体变量,其长度占了16个字节,原因就是第1个属性本来应该只分配2个字节,但实际被分配了4个字节,多出来2个字节,所以如果想保存一张bmp图片,写入BITMAPFILEHEADER结构体时一定要注意这一点。
接下来是BITMAPINFO结构体部分。BITMAPINFO段由两部分组成:BITMAPINFOHEADER结构体和RGBQUAD结构体。其中RGBQUAD结构体表示图片的颜色信息,有些时候可以省略,一般的24位图片和32位图片都不带RGBQUAD结构体,因为DIB数据区直接表示的RGB值,一般4位图片和8位图片才带有RGBQUAD结构体。(多少位的图片就是用多少位来表示一个颜色信息,例如4位图片表示用4个bit来表示一个颜色信息。)一个bmp文件中有没有RGBQUAD结构体,可以根据前面BITMAPFILEHEADER结构体的第5个属性bfOffBits来判断,因为BITMAPINFOHEADER结构体长度为40bit,如果BITMAPINFOHEADER结构体结束后还未到DIB数据区的偏移量,就说明接下来的数据是RGBQUAD结构体部分。这里讲的C:\WINDOWS\Blue Lace 16.bmp是一个4bit图片,所以它带有 RGBQUAD结构体。
下面进入正题BITMAPINFOHEADER部分。
BITMAPINFOHEADER的第1个属性是biSize(4字节),表示BITMAPINFOHEADER结构体的长度,最常见的长度是40字节,UltraEdit中可以看到紧接着的4个字节等于&H00000028=40字节。
BITMAPINFOHEADER的第2个属性是biWidth(4字节),表示bmp图片的宽度,这里等于&H00000030=48像素。
BITMAPINFOHEADER的第3个属性是biHeight(4字节),表示bmp图片的高度,这里等于&H00000030=48像素。
BITMAPINFOHEADER的第4个属性是biPlanes(2字节),表示bmp图片的平面属,显然显示器只有一个平面,所以恒等于1,这里等于&H0001。
BITMAPINFOHEADER的第5个属性是biBitCount(2字节),表示bmp图片的颜色位数,即24位图、32位图等等。这里等于&H0004,表示该图片为4位图。
BITMAPINFOHEADER的第6个属性是biCompression(4字节),表示图片的压缩属性,bmp图片是不压缩的,等于0,所以这里为&H00000000。
BITMAPINFOHEADER的第7个属性是biSizeImage(4字节),表示bmp图片数据区的大小,当上一个熟悉biCompression等于0时,这里的值可以省略不填,所以这里等于&H00000000。
BITMAPINFOHEADER的第8个属性是biXPelsPerMeter(4字节),表示图片X轴每米多少像素,可省略,这里等于&H00000EC3=3779像素/米。
BITMAPINFOHEADER的第9个属性是biYPelsPerMeter(4字节),表示图片Y轴每米多少像素,可省略,这里等于&H00000EC3=3779像素/米。
BITMAPINFOHEADER的第10个属性是biClrUsed(4字节),表示使用了多少个颜色索引表,一般biBitCount属性小于16才会用到,等于0时表示有2^biBitCount个颜色索引表,所以这里仍等于&H00000000。
BITMAPINFOHEADER的第11个属性是biClrImportant(4字节),表示有多少个重要的颜色,等于0时表示所有颜色都很重要,所以这里等于&H00000000。
至此BITMAPINFOHEADER结构体结束。
由于这个图片到这里还未到达DIB数据区的偏移量,所以接下来的部分是RGBQUAD结构体。RGBQUAD结构体由4个字节型数据 组成,所以一个RGBQUAD结构体只占用4字节空间,从左到右每个字节依次表示(蓝色,绿色,红色,未使用)。举例的这个图片我数了数总共有16个RGBQUAD结构体,由于该图片是4位图,2^4正好等于16,所以它把16种颜色全部都枚举出来了,这些颜色就是一个颜色索引表。颜色索引表编号从0开始,总共16个颜色 ,所以编号为0-15。从UltraEdit中可以看到按照顺序,这16个RGBQUAD结构体依次为:
编号:(蓝,绿,红,空)
0号:(00,00,00,00)
1号:(00,00,80,00)
2号:(00,80,00,00)
3号:(00,80,80,00)
4号:(80,00,00,00)
5号:(80,00,80,00)
6号:(80,80,00,00)
7号:(80,80,80,00)
8号:(C0 ,C0,C0,00)
9号:(00,00,FF,00)
10号:(00,FF,00,00)
11号:(00,FF,FF,00)
12号:(FF,00,00,00)
13号:(FF,00,FF,00)
14号:(FF,FF,00,00)
15号:(FF,FF,FF,00)
为了更直观的表示这些颜色,可以见后面的图片。
到这里,正好满足DIB数据区的偏移量,所以后面的字节就是图片内容了。这里需要提醒的是所有的DIB数据扫描行是上下颠倒的,也就是说一幅图片先绘制底部的像素,再绘制顶部的像素,所以这些DIB数据所表示的像素点就是从图片的左下角开始,一直表示到图片的右上角。
由于这里的图片是4位图片,也就是说4bit就表示一个像素,一个字节有8个bit,所以一个字节能表示2个像素。
从UltraEdit中可以看到,DIB数据区第一个字节是&H44,16进制正好是将2进制数每4个一组书写的,跟4bit图片正好吻合,所以&H44表示两个像素,高位的4表示第一个像素,低位的4表示第二个像素。这里的4不是表示RGB颜色,而是表示颜色索引号为4,由于索引号从0开始编号的,所以4表示索引表中第5个颜色,从附图中可以看到索引号为4的是蓝色。这是第一字节,表示的是图片左下角开始2个像素,如果有 PhotoShop打开这个图片可以看到,左下角2个像素取出来的颜色RGB值正好等于索引表中第5个颜色的RGB值。后面的DIB数据以此类推。
至此一个bmp图片就全部解析完了,根据这些信息就可以完整的绘制一张bmp图片来。
所以要显示一个bmp位图特别方便,特别是24位、32位图片,后面的DIB数据区就是按照(B,G,R)或(B,G,R,A)顺序排列的,只要根据 DIB偏移量找到DIB数据区,装入一个buffer中保存,前面BITMAPINFO结构体也有了,直接用CopyMemory复制过来,然后就可以调用CreateDIBSection函数创建一个hBitMap出来,把这个hBitMap选入DC中,就可以用BitBlt或StretchBlt向目标DC中复制数据,把bmp图片就在绘图区显示出来了。
如果你还不明白,还有:
1. BMP文件组成
BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。
2. BMP文件头
BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。
其结构定义如下:
typedef struct tagBITMAPFILEHEADER
{
WORDbfType; // 位图文件的类型,必须为BM
DWORD bfSize; // 位图文件的大小,以字节为单位
WORDbfReserved1; // 位图文件保留字,必须为0
WORDbfReserved2; // 位图文件保留字,必须为0
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图
// 文件头的偏移量表示,以字节为单位
} BITMAPFILEHEADER;
3. 位图信息头
BMP位图信息头数据用于说明位图的尺寸等信息。
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; // 本结构所占用字节数
LONGbiWidth; // 位图的宽度,以像素为单位
LONGbiHeight; // 位图的高度,以像素为单位
WORD biPlanes; // 目标设备的级别,必须为1
WORD biBitCount// 每个像素所需的位数,必须是1(双色),
// 4(16色),8(256色)或24(真彩色)之一
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),
// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
DWORD biSizeImage; // 位图的大小,以字节为单位
LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数
LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数
DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
DWORD biClrImportant;// 位图显示过程中重要的颜色数
} BITMAPINFOHEADER;
4. 颜色表
颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
typedef struct tagRGBQUAD {
BYTErgbBlue;// 蓝色的亮度(值范围为0-255)
BYTErgbGreen; // 绿色的亮度(值范围为0-255)
BYTErgbRed; // 红色的亮度(值范围为0-255)
BYTErgbReserved;// 保留,必须为0
} RGBQUAD;
颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
当biBitCount=1,4,8时,分别有2,16,256个表项;
当biBitCount=24时,没有颜色表项。
位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // 位图信息头
RGBQUAD bmiColors[1]; // 颜色表
} BITMAPINFO;
5. 位图数据
位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:
当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=24时,1个像素占3个字节;
Windows规定一个扫描行所占的字节数必须是
4的倍数(即以long为单位),不足的以0填充,
一个扫描行所占的字节数计算方法:
DataSizePerLine= (biWidth* biBitCount+31)/8;
// 一个扫描行所占的字节数
DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
位图数据的大小(不压缩情况下):
DataSize= DataSizePerLine* biHeight;
发表评论
-
整理下OSS方面的资料,免得到处找,linux音频编程,open sound system
2012-01-20 00:12 789整理下OSS方面的资料,免 ... -
文件操作小结
2012-01-20 00:12 762文件操作小结 2010年08 ... -
C++流和文件流
2012-01-20 00:12 620C++流和文件流 2010年08 ... -
从DOS命令到制作IMG的详细教程
2012-01-20 00:12 505从DOS命令到制作IMG的详细教程 2010年06月20日 ... -
从头开始编写操作系统(8) 第7章:系统结构
2012-01-20 00:12 695从头开始编写操作系统( ... -
东方文花帖
2012-01-19 01:04 484东方文花帖 2010年10月07日 中文名:东 ... -
Java
2012-01-19 01:04 498Java 2010年06月22日 运行结果 ... -
JDK1.5 JDK1.6 各自的新特性
2012-01-19 01:04 671JDK1.5 JDK1.6 各自的新特 ... -
Photoshop常见问答集
2012-01-19 01:04 477Photoshop常见问答集 ... -
一个PS高手的话,对初学者很实用
2012-01-19 01:04 659一个PS高手的话,对初学 ... -
(转)BMP文件格式详解(BMP file format)
2012-01-17 00:27 675(转)BMP文件格式详解(BMP ... -
C语言 BMP图片处理
2012-01-17 00:27 721C语言 BMP图片处理 2011年11月12日 C语言 ... -
bmp另类加密解密方法
2012-01-17 00:27 734bmp另类加密解密方法 2011年03月19日 ... -
BMP文件格式、
2012-01-17 00:27 333BMP文件格式、 2011年09 ... -
成人笑话大全第019篇
2012-01-16 13:52 504成人笑话大全第019篇 20 ... -
高中生自我评语 高中毕业生自我鉴定
2012-01-16 13:52 746高中生自我评语 高 ... -
演讲稿大全
2012-01-16 13:52 515演讲稿大全 2010年11月17日 演讲稿大全 ?? ... -
三年级如何写作文
2012-01-16 13:52 497三年级如何写作文 2011年10月27日 三年级如何写 ...
相关推荐
命令行图片格式转换bmp转jpg 支持直接将BMP拖拽到程序图标上。
用C语言完成的,将png格式和jpeg格式的图片显示出来,以及转化为bmp格式的功能,其中还附加了一些图片放大缩小和图片旋转的小功能
在linux环境下进行bmp图像转换yuv格式
Yuv转Bmp bmp转yuv420 支持各种图片格式转yuv bmp转yuv420 y分量无像素点差异 色度分量有0-1个像素点差异
240*320BMP格式图片的翻转,实现图片的倒置,所操作的图片仅为240*320BMP格式
BMP图片储存格式说明及C代码 BMP(全称Bitmap)是Window操作系统中的标准图像文件格式,可以分成两类:设备相关位图(DDB)和设备无关位图(DIB),使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用...
利用 C 语言只需两步实现 RAW 格式图片转换成 BMP 格式图片,简单实用容易理解,附代码注释。
可转换图片格式可转换图片格式可转换图片格式可转换图片格式可转换图片格式可转换图片格式
图片格式 NV21 转 RGB24 和 BMP图片源码(C语言)。 NV21 转 RGB24 格式。 NV21 转 BMP 格式图片源码。 直接可以用。
图片格式转换(如bmp转jpg)的matlab实现。
argb1555转bmp图片
使用OPENCV库,将YUYV格式的视频转换为BMP格式的图片并保存,在VS2017环境下,亲测可用
VC下实现BMP图片提取RGB数据,存储到数组文件
源码通过ffmpeg库实现了将bmp格式图像转换为jpeg格式图像
多张24位bmp格式图片转换成16位bin文件,适合单片机flash烧录,有偏移地址,要重新定制的私信我
android jni 将wlt图片转成bmp格式图片,支持32位armeabi架构手机
一个能把各种bmp格式的图片转换为0x开头的十六进制数组的txt文件,使用方便,简单,非常适合于用单片机控制TFT显示BMP位图的转换软件
该资源提供了BMP格式图像转JPEG格式图像的函数,在数字图像处理后,进行图像输出时会用得到,非常方便。不依赖于其他框架,纯C语言实现。
批量快速将多张bmp图片转换为bin文件,bmp图片位深度为24bit,bin文件可选择8bit(RGB323)、16bit(RGB565)、24bit(RGB888) 输出,用于烧录到 外部flash,单片机去读取数据显示图像。因为输出每张bmp图片所在flash里的...