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; 可以去试试内存对齐啦~嘻嘻
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
- photoshop去除图片上的水印
- 图片引发的溢出危机(图)
- 纯CSS实现的当鼠标移上图片添加阴影效果代码
- 随鼠标移动的图片或文字特效代码
- CSS 图片横向排列实现代码
- 获取图片宽度和高度的类,支持JPG,GIF,PNG,BMP
- 超级经典一套鼠标控制左右滚动图片带自动翻滚
- 用css实现图片垂直居中的使用技巧
- 图片与文字半透明效果 鼠标移上不透明
- javascript实现网站顶部出现几秒后图片缓慢消失的效果
- asp下轻松实现将上传图片到数据库的代码
- asp汉字中文图片验证码
- CSS图片翻转菜单
- 一个收集图片的bookmarlet(js 刷新页面中的图片)
- JavaScript判断图片是否能够加载,失败则替换默认图片
- 图片友情链接滚动 横向,带控制按钮
- JavaScript 控制图片改变重叠顺序的代码(鼠标移动切换)
- 图片翻转菜单技术研究
- js怎样实现下拉框改变,它旁边的图像也改变