WIDTHBYTES

一、定义

#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4);

计算图像每行象素所占的字节数目,设置成4的整数倍

//=(((bits) + 31) / 8)

//=((( biWidth* biBitCount) + 31) / 8)

二、参数说明:

bits:一个btmap中一行像素的位数总和。

 

bits:=biWidth* biBitCount;

biWidth:像素个数

biBitCount:一个像素所占的位数

当biBitCount=1时,8个像素占1个字节;

当biBitCount=4时,2个像素占1个字节;

当biBitCount=8时,1个像素占1个字节;

当biBitCount=24时,1个像素占3个字节

也就是一个像素占biBitCount/8个字节

三、实例:

对于2色图,如果图象宽是31,则每一行需要31位存储,合3个字节加7位,因为字节数必须是4的整倍数,所以应该是4,而此时的 biWidth=31, biBitCount=1, WIDTHBYTES(31*1)=4,和我们设想的一样。

举一个256色的例子,如果图象宽是31,则每一行需要31个字节存储,因为字节数必须是4的整倍数,所以应该是32,而此时的biWidth=31, biBitCount=8, WIDTHBYTES(31*8)=32。

四、相关知识说明

1.将图像文件宽度设置成4的整数倍,只有bmp格式要求采用,其他格式的图像并不要求是4的倍数。

2.bmp格式采用这一做法,我想是为了考虑访问的速度。从文件读出图像数据时,一次读4个字节比一次读1个字节快。但如果图像文件不是4的倍数时,每行最后的像素就不可能[注]采用一次读4个字节(否则就会把下一行的像素也读出)。当然,你仍然可以读出的4字节来,但必须处理:将其中几个字节放在本行,而其余的显示到下一行. 但显然这很不方便,要影响速度。

3. 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是左到右,扫描行之间是从下到上。Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充

vs2017编译程序出现报错 warning C4800: “PBYTE”: 将值强制为布尔值 "true" 或 "false"(性能警告) 下面是程序代码片段 给出修改过的代码 #ifdef _DEBUG //!断言支持,debug版本直接使用系统的assert # define _FC_Assert_ assert #else //!断言支持,Release版本将断言记录在/Foundation/Assert中 # define _FC_Assert_(expr) do {LOG_ASSERT(expr,"%s",#expr);} while(0) #endif int TgaCodec::_from_8_PAL_read(void** lineAddr, PBYTE lpSrc, const TgaHeader& tgaHeader, const LPBYTE pPal)//Passed { _FC_Assert_(lpSrc); _FC_Assert_(tgaHeader.bBits==8);//前提 _FC_Assert_(pPal); LPBITMAPINFOHEADER pBmpInfo=&(_imageInfo.bmi); WORD wSrcBytesPerLine=DIBSCANLINE_WIDTHBYTES(tgaHeader.wWidth*8); DWORD*(*pDestLineAddr)=(DWORD**)lineAddr; LPBYTE pSrcBuf,pDest24; LPWORD pDest16; int fmt=GetImageFormat(); int iRow,iCol; switch(fmt) { case DF_32: for(iRow=0;iRow<pBmpInfo->biHeight;iRow++) { if(tgaHeader.bDescriptor&TGA_VERTMIRROR) //上下倒置 pSrcBuf=lpSrc+wSrcBytesPerLine*iRow; else pSrcBuf=lpSrc+wSrcBytesPerLine*(pBmpInfo->biHeight-1-iRow); for(iCol=0;iCol<pBmpInfo->biWidth;iCol++) { if(tgaHeader.bDescriptor&TGA_HORZMIRROR)//左右反置 memcpy(pDestLineAddr[iRow]+iCol,pPal+pSrcBuf[pBmpInfo->biWidth-1-iCol]*3,3); else memcpy(pDestLineAddr[iRow]+iCol,pPal+pSrcBuf[iCol]*3,3); } } break; case DF_24: for(iRow=0;iRow<pBmpInfo->biHeight;iRow++) { if(tgaHeader.bDescriptor&TGA_VERTMIRROR) //上下倒置 pSrcBuf=lpSrc+wSrcBytesPerLine*iRow; else pSrcBuf=lpSrc+wSrcBytesPerLine*(pBmpInfo->biHeight-1-iRow); pDest24=(LPBYTE)pDestLineAddr[iRow]; for(iCol=0;iCol<pBmpInfo->biWidth;iCol++) { if(tgaHeader.bDescriptor&TGA_HORZMIRROR)//左右反置 memcpy(pDest24+iCol*3,pPal+pSrcBuf[pBmpInfo->biWidth-1-iCol]*3,3); else memcpy(pDest24+iCol*3,pPal+pSrcBuf[iCol]*3,3); } } break; case DF_16_555: for(iRow=0;iRow<pBmpInfo->biHeight;iRow++) { if(tgaHeader.bDescriptor&TGA_VERTMIRROR) //上下倒置 pSrcBuf=lpSrc+wSrcBytesPerLine*iRow; else pSrcBuf=lpSrc+wSrcBytesPerLine*(pBmpInfo->biHeight-1-iRow); pDest16=(LPWORD)pDestLineAddr[iRow]; for(iCol=0;iCol<pBmpInfo->biWidth;iCol++) { if(tgaHeader.bDescriptor&TGA_HORZMIRROR)//左右反置 pDest16[iCol]=_cnv_rgb_to_555(pPal[pSrcBuf[pBmpInfo->biWidth-1-iCol]*3+2],pPal[pSrcBuf[pBmpInfo->biWidth-1-iCol]*3+1],pPal[pSrcBuf[pBmpInfo->biWidth-1-iCol]*3]); else pDest16[iCol]=_cnv_rgb_to_555(pPal[pSrcBuf[iCol]*3+2],pPal[pSrcBuf[iCol]*3+1],pPal[pSrcBuf[iCol]*3]); } } break; case DF_16_565: for(iRow=0;iRow<pBmpInfo->biHeight;iRow++) { if(tgaHeader.bDescriptor&TGA_VERTMIRROR) //上下倒置 pSrcBuf=lpSrc+wSrcBytesPerLine*iRow; else pSrcBuf=lpSrc+wSrcBytesPerLine*(pBmpInfo->biHeight-1-iRow); pDest16=(LPWORD)pDestLineAddr[iRow]; for(iCol=0;iCol<pBmpInfo->biWidth;iCol++) { if(tgaHeader.bDescriptor&TGA_HORZMIRROR)//左右反置 pDest16[iCol]=_cnv_rgb_to_565(pPal[pSrcBuf[pBmpInfo->biWidth-1-iCol]*3+2],pPal[pSrcBuf[pBmpInfo->biWidth-1-iCol]*3+1],pPal[pSrcBuf[pBmpInfo->biWidth-1-iCol]*3]); else pDest16[iCol]=_cnv_rgb_to_565(pPal[pSrcBuf[iCol]*3+2],pPal[pSrcBuf[iCol]*3+1],pPal[pSrcBuf[iCol]*3]); } } break; case DF_NULL: default: break; } return 0; }
09-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值