您的位置:首页 > 其它

BMP基本读取的相关问题

2013-10-18 16:46 211 查看
最近一直在写有关BMP文件读写的相关内容,期间遇到不少问题,现在终于算是告一段落。

1.关于BMP的格式,在百度百科上有很详细的介绍http://baike.baidu.com/view/189487.htm

  简略必须读取:

  位图文件头:BITMAPFILEHEADER bmfh

  位图信息头: BITMAPINFOHEADER bmih

  彩色表:RGBQUAD aColors[]

  图象数据阵列字节 BYTE aBitmapBits[]

  有效图像数据在最后的data里。在读取bmfh有一个bfOffBits说明从文件头开始到实际的图象数据之间的字节的偏移量,可以直接跳到数据阶段。

  还用到了: bmih中的biWidth,biHeight, biBitCount 说明比特数/象素, biSizeImage(注意以字节为单位)

 

2. 关于读取BMP格式中内存对齐问题:

为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。  缺省情况下,c/c++编译器默认将结构、栈中的成员数据进行内存对齐。

所以在读取BMP头格式是会出现读取数据错误,两种解决方案1.分别读取 2.使用#pragma pack(1) 和 #pragma pack()将定义的结构体包围。

3.关于BMP图像数据的读取和保存

同样因为对齐的原因,BMP格式文件会在图片文件宽度不是四的倍数时进行自动补齐,所以如果直接用图像宽度作为循环读取会出现读取的图像倾斜现象。

灰度图像的每行字节数:int iLineByteCnt = (m_bmpinfo.bmiHeader.biWidth+ 3) >> 2) << 2;  所以图像数据大小: int m_iImageDataSize = iLineByteCnt * m_bmpinfo.bmiHeader.biHeight;

图像int iLineByteCnt = (m_bmpinfo.bmiHeader.biWidth*m_iBitsPerPixel+ 3) >> 2) << 2;注意*m_iBitsPerPixel不是直接读取出来的8,24,32而是字节数即1,3,4

针对24位的彩色图像扫描  int nCol = (((m_bmpinfo.bmiHeader.biWidth*3) + 3) >> 2) << 2;//扫描宽度。。所以在彩色图像转为灰度图像时每行的也是对齐的。。。

 

4.关于彩色图像转灰度图像

有很多博文写了相关内容,24位的转8位主要公式m_graydata[i*m_WidthByte+j]=m_bmpData[k+2]*0.299+m_bmpData[k+1]*0.587+m_bmpData[k]*0.114;//转化公式

gray = R*0.299+G*0.587+B*0.114 .但是24位的BMP色彩格式是BGR不是RGB

 

5.关于显示

只想说一点你认为读取出的第一行实际上最后一行,BMP是倒着存储的,所以你想显示前半段图片是要使用后半段的图像数据。

 

6.其他:

关于常识 灰度图像 黑色:0   白色:255  

                  32位系统中sizeof(long) = sizeof(int) = 4; sizeof(short) = 2;  sizeof(char) = 1; 可以去试试内存对齐啦~嘻嘻

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  内存对齐 BMP 图片