欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

bmp文件详解

程序员文章站 2022-07-15 23:50:20
...

                  bmp文件------位图文件

一、位图文件结构

位图文件包括:位图文件头BITMAPFILEHEADER;

                         位图信息BITMAPINFO(位图信息头BITMAPINFOHEADER、颜色表RGBQUAD);

                         位图数据。

1.位图文件头

 位图文件头主要用于识别位图文件,位图文件头结构的定义为:

bmp文件详解其大小为:2+4+2+2+4 = 14byte

其中的bfType值是“BM”0x4d42)转化为十进制为19778,标志该文件是位图文件。

bfSize的值是位图文件的大小,等于 bfOffBits + DibWidth(四字节对齐后的宽度) * Height

bfOffBits表示像素数据距离文件起始位置的偏移量。

 

我们拿一个灰度图片举个例子,其每行像素个数为511,高度是512。

bmp文件详解

bfSize = 1078 + 512(511四字节对齐后就是512)*512 = 263222(byte)。

bfOffBits = 14 + 40(sizeof(BITMAPINFOHEADER)) + 256*4(颜色表大小) = 1078 。

 

那么彩色图片的信息我们也看下,其每行像素个数为511,高度是512:

bmp文件详解

bfSize  = 54 + 512(对齐后的啊)*512 * 3 = 786486(byte)

bfOffBits = 14 + 40 = 54(彩色图片一个像素用24位表示,故没有颜色表)

 

问题1:有关四字节问题:

就是为了让每一行的像素的个数都保证是4的个数,当然对齐后肯定是有优点的,优点是对于计算机存储来说的。

四字节对齐目的是让原本不是4的倍数的每行像素变成4的倍数,如上面的511->512

那么是怎么变得?我们首先要知道原本图片中一行像素个数m_nWidth,然后还有知道一个像素占了几位(1byte = 8bit),然后对齐后的宽度m_nDibWidth 为:(注意这里的数据全是整数运算,也就是说小数后面全舍掉后再参与运算)

m_nDibWidth = (m_nWidth*m_nBitCount + 31) / 32 * 4;

512                = (511 * 8 + 31)/32*4 = 4119/32*4 = 128*4=512

问题2:颜色表

说道颜色表,就必须知道RGB是怎么映射出来的?

bmp文件详解

          也就是说,由于我们灰度图片是8bit的,也就是有256个灰度级,如果要表示一个灰度级的像素,我需要让R分量,G分量,B分量都是一样的数,像素少是可以这么做,众所周知,现在手机图片都做到1亿了,那一张图片这样表示显然浪费?于是有了颜色表的存在。

颜色表就是将256个灰度级用256*4的数组先定义好,然后图片的像素进行映射。那么那个数组长啥样?

bmp文件详解

bmp文件详解

从这个图中我们能知道:像素点1的灰度级为2,像素点2的灰度级为n(0=<n<=255)

实际中用数组定义的样子是什么样的:

bmp文件详解

bmiColors是一个4*256 = 1024大小的数组,上面显示的是bmiColors[0] ,显然bmiColors[1]肯定是:

bmp文件详解

2.位图信息BITMAPINFO

包含两部分:位图信息头BITMAPINFOHEADER、颜色表RGBQUAD,其中颜色表不一定都有。

位图信息头的结构体定义如下:

typedef struct tagBITMAPINFOHEADER{ // bmih
DWORD  biSize;
LONG   biWidth;
LONG   biHeight;
WORD   biPlanes;
WORD   biBitCount
DWORD  biCompression;
DWORD  biSizeImage;
LONG   biXPelsPerMeter;
LONG   biYPelsPerMeter;
DWORD  biClrUsed;
DWORD  biClrImportant;
} BITMAPINFOHEADER;

每个参数的详细介绍:

bmp文件详解

biBitCount:对于每个像素的字节数,可能有以下取值:

1,单色图,调色板中含有两种颜色,也就是我们通常说的黑白图片

416色图

8256色图,通常说的灰度图,但也可以有颜色,取决于使用何种颜色表

1664K图,一般没有调色板,图像数据中每两个字节表示一个像素,5个或6个位表示一个RGB分量

2416M真彩色图,一般没有调色板,图像数据中每3个字节表示一个像素,每个字节表示一个RGB分量

324G真彩色,一般没有调色板,每4个字节表示一个像素,相对24位真彩图而言,加入了一个透明度,即RGBA模式

 

3.位图数据

位图数据是像素的信息,其大小为:nDL = m_nDibWidth * m_nHeight,单位:字节

而m_nDibWidth又和biBitCount以及图片宽度有关。