bmp图像大小biSizeImage算法公式由来

LPBITMAPINFOHEADER lpbmiHeader;

// ...

计算BMP方法

法一:lpbmiHeader->biSizeImage = (cx * biBitCount + 31)/32*4*cy;

法二:lpbmiHeader->biSizeImage = ((cx * biBitCount + 31) & ~31) / 8 * cy;

法三:lpbmiHeader->biSizeImage = ((cx * biBitCount + 31) & ~31) >> 3 * cy;

前提: 在BMP的文件格式中规定每行的字节数必须是4的整数倍,不是4的整数倍要补齐。

上面公式红色部分都是一样的结果,都是计算BMP图像中每行的字节数。

其中cx * biBitCount是实际一行占用的位数。暂且用dwRowBit表示吧。

情况1:dwRowBit小于32位(假设dwRowBit为31),那么dwRowBit/8 就小于4,但是我们需要补齐4个字节。办法就是(31 + 31)/32 * 4

情况2: dwRowBit正好32位,不需要考虑多少。 32/8 ,和32/32 * 4都是一样的

情况3: dwRowBit为34位,按理说最少需要4个字节带1位,但是因为必须是4的整数倍,所以应该以8个字节保存。

如何将34位转化为8个字节呢?就是要将dwRowBit中除以32的余数部分添加到满足32位的情况。

所以(dwRowBit + 31)/32 * 4;

其实我们也可以换个思维考虑:

如下dwRowBit分成2个部分: dwRowBit1为正好能被32整除的部分,dwRowBit2为不能被32整除的部分(则dwRowBit2肯定小于32,为什么?你们想想?)

那么上述公式划分为

(dwRowBit1 + dwRowBit2 + 31) / 32 * 4;

再简化一下就是dwRowBit1 / 32 * 4 + (dwRowBit2 + 31) / 32 * 4

再简化一下dwRowBit1 / 8 + (dwRowBit2 + 31) / 32 * 4

dwRowBit2从31位中取一定的位数使自己补齐为32,31剩余的部分除以32的话自动为0.

另外还要补充一点: 对单位的考虑

(dwRowBit1 + dwRowBit2 + 31) bit / 32 bit  * 4 Byte

//===============================================================================================//

// 参考资料1 

计算biSizeImage的两种方法: 1.最简单的方法是由BITMAPFILEHEADER结构的bfSize减去bfOffBits。 2.由图像的高度和宽度来计算图像数据的字节数。要注意的是并不是图像的高度乘以图像宽度乘以表示每象 素的字节数就行了,因为在BMP的文件格式中规定每行的字节数必须是4的整数倍,不是4的整数倍的要补 零。因此,正确的算法是: biSizeImage=(biWidth*biBitCount+31)/32*4*biHeight 其中,biWidth*biBitCount是每一行图像占用的位数,除以8是每行图像占用的字节数,要为4的整数倍,所 以除以32再乘以4,整数除法自动取整。(不能直接除以8,想想为什么?加31有什么作用?) 不足的位数补充上如241存储为244.(..........如果可以位数舍去,241为240,这是不可能的,那不用加31)

// 参考资料2

csdn论坛搜索关键字:

biSizeImage

VC/MFC分区——图形处理/算法

主要链接:

http://topic.csdn.net/u/20070929/13/9ED13464-121E-401E-B827-91E3BF5F0036.html

http://topic.csdn.NET/u/20100114/21/0A67123E-1407-4FC0-B4E0-6D27FB8626C2.html

http://topic.csdn.net/u/20100116/17/4590fdf6-91c7-49a6-a76f-fa3effbae759.html

关键心得:

biSizeImage=(biWidth*biBitCount+31)/32*4*biHeight其中,biWidth*biBitCount是每一行图像占用的位数,除以8是每行图像占用的字节数,要为4的整数倍,所以除以32再乘以4 31是按整数除法自动取整的原则来的,其保证每行图像字节数必须是4的整倍数! 举一个例子,对于2色图,如果图象宽是31,则每一行需要31位存储,合3个字节加7位,因为字节数必须是4的整倍数,所以应该是4。所以补齐时需要加上4个字节数即32位

===================================

1:biWidth = 241 是位图的宽度而不是字节数目 2:(bits)其实需要输入:(biWidth * biBitCount), 3:WIDTHBYTES()根据输入(biWidth*biBitCount)而得出行字节数,而扫描行字节数乘以扫描行总数(位图的高度biHeight),就得出位数据的实际字节数目,估计你是理解错误了. 4:那估计是乱写的,正确是不能把 (xx)/32*4写成(xx)/8的,在计算机那是不相等的,举例: width = 2,bpp = 8那么行字节数应该是 (2*8+31)/32*4 得4个字节. (2*8+31)/8 得5个字节. 有少少常识的都知道,上面那个是对的,下面那个是错的,原因那些家伙根本不理解"对齐"的意思,片面地把"/32*4"合成为"/8"来误人误已. hoho.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏量化投资与机器学习

从Encoder到Decoder实现Seq2Seq模型(算法+代码)

知乎专栏:机器不学习 作者:天雨栗 | 蚂蚁金服 | 数据算法 已授权刊登 前言 好久没有更新专栏,今天我们来看一个简单的Seq2Seq实现,我们将使用Tens...

6086
来自专栏专知

【Keras教程】用Encoder-Decoder模型自动撰写文本摘要

【导读】这篇博文介绍了如何在深度学习框架Keras上实现文本摘要问题,探讨了如何使用编码器-解码器递归神经网络体系结构来解决文本摘要问题,如何实现文本摘要问题的...

6125
来自专栏有趣的Python

3- OpenCV+TensorFlow 入门人工智能图像处理-TensorFlow入门

tensorflow基础入门 思考一个问题: 如何刚好学习TensorFlow 类比为一门开发语言,学会语法,api的调用, 原理性掌握。 语言的要素: 基础...

7308
来自专栏决胜机器学习

从机器学习学python(四) ——numpy矩阵基础

从机器学习学python(四)——numpy矩阵基础 (原创内容,转载请注明来源,谢谢) 一、numpy中matrix 和 array的区别 ...

4097
来自专栏小鹏的专栏

Tensorflow使用的预训练的resnet_v2_50,resnet_v2_101,resnet_v2_152等模型预测,训练

tensorflow 实现:Inception,ResNet , VGG , MobileNet, Inception-ResNet; 地址: https:/...

7838
来自专栏数据结构与算法

学大伟业Day解题报告

预计分数:30+30+0=60 实际分数:30+20+0=50 题解部分全部来自http://www.cnblogs.com/TheRoadToTheGold/...

3184
来自专栏来自地球男人的部落格

Seq2Seq模型

前言: 此文翻译自TensorFlow tutorial: Sequence-to-Sequence Models 本文的尽量在做到意思正确的情况下,做到不...

28210
来自专栏人工智能

十五:多层感知机与布尔函数

今天没有别的话,好好学习,多多转发! 本期内容是 【多层感知机与布尔函数】 场景描述 神经网络概念的诞生很大程度上受到了神经科学的启发。生物学研究表明,大脑皮层...

2488
来自专栏上善若水

002计算机图形学之直线画线算法

主要思想是,由于我们在缓存区上画点,全部是整数。那么在画线的时候,当斜率k小于1的时候,下一个点是取(x+1,y+1)还是(x+1,y)取决于点(x+1,y+0...

1192
来自专栏小樱的经验随笔

算法--枚举策略

枚举法的基本思想 枚举法的基本思想是根据提出的问题枚举所有可能状态,并用问题给定的条件检验哪些是需要的,哪些是不需要的。能使命题成立,即为其解。 枚举结构:循环...

4809

扫码关注云+社区