定义结构:
.H:
class CMBmp
{
public:
CMBmp(void);
~CMBmp(void);
int m_nBmpHeight;
int m_nBmpWidth;
BYTE* m_p32BitBmpBuf;
};
.cpp:
CMBmp::CMBmp(void)
: m_nBmpHeight(0)
, m_nBmpWidth(0)
, m_p32BitBmpBuf(NULL)
{
}
CMBmp::~CMBmp(void)
{
m_nBmpHeight = m_nBmpWidth = 0;
if(NULL != m_p32BitBmpBuf){
delete[] m_p32BitBmpBuf;
m_p32BitBmpBuf = NULL;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
读取一张24bit的BMP保存到个BYTE buffer里面:
CFileDialog GetFile(TRUE,NULL,NULL,OFN_FILEMUSTEXIST,_T("BMP(*.bmp)|*.bmp|All Files(*.*)|*.*"));
if(IDOK == GetFile.DoModal())
{
CString strFilePath = GetFile.GetPathName();
FILE *fp=NULL;
int ret = fopen_s(&fp,strFilePath,"rb");
if(fp==0)
{
return ;
}
BITMAPFILEHEADER fileheader={0};
fread(&fileheader,sizeof(fileheader),1,fp);
if(fileheader.bfType!=0x4D42)
{
fclose(fp);
return ;
}
BITMAPINFOHEADER head;
fread(&head,sizeof(BITMAPINFOHEADER),1,fp);
long bmpWidth = head.biWidth;
long bmpHeight = head.biHeight;
WORD biBitCount = head.biBitCount;
if(biBitCount != 24)
{
::AfxMessageBox(_T("choose a 24 bit bmp"));
fclose(fp);
return ;
}
int bytes_per_line = (bmpWidth * biBitCount/8+3)/4*4;
int totalSize = bytes_per_line*bmpHeight;
BYTE * pBmpBuf = new BYTE[totalSize]; // 24 bit buf
size_t size = 0;
while(true)
{
int iret = fread(&pBmpBuf[size],1,1,fp);
if(iret == 0)
break;
size = size + iret;
}
fclose(fp);
}
/////////////////////////////////////////////////////////////////
上面读出来的是翻转的,下面正过来:
//flip
BYTE *buffer;
int index;
buffer = new BYTE[totalSize];//temp buf to flip 24bit bmp map
memcpy(buffer,pBmpBuf,totalSize);
for (index=0; index < bmpHeight; index++)
memcpy(&pBmpBuf[((bmpHeight-1) - index)*bytes_per_line],
&buffer[index*bytes_per_line], bytes_per_line);
delete[] buffer;
buffer = NULL;
//////////////////////////////////////////////////////////////////
显示一下:
////show 24bit
//int i,j;
//CClientDC dc(this);
//int pitch = bmpWidth % 4;
//for(i=0;i<bmpHeight;i++)
//{
// int realPitch = i * pitch;
// for(j=0;j<bmpWidth;j++)
// {
// dc.SetPixel(j,i,RGB(
// m_pBmpBuf1[(i*bmpWidth+j)*3+2+realPitch],
// m_pBmpBuf1[(i*bmpWidth+j)*3+1+realPitch],
// m_pBmpBuf1[(i*bmpWidth+j)*3+realPitch]));
// }
//}
////////////////////////////////////////////////////////////////////
将24bit转成32bit,添加Alpha通道:
//convert to 32bit
int _32bitBytes_per_line = (bmpWidth * 32 / 8 + 4)/4*4;
BYTE *p32BitBuf = new BYTE[_32bitBytes_per_line * bmpHeight];//32 bit buf
int nAlpha = m_nAlpha1;//60%:153
BYTE *pSrc = pBmpBuf;
BYTE *pDst = p32BitBuf;
int pitch = bmpWidth % 4;
for(int i=0;i<bmpHeight;i++)
{
int realPitch = i * pitch;
for(int j=0;j<bmpWidth;j++)
{
pDst[(i*bmpWidth+j)*4+3+realPitch] = pSrc[(i*bmpWidth+j)*3+2+realPitch];
pDst[(i*bmpWidth+j)*4+2+realPitch] = pSrc[(i*bmpWidth+j)*3+1+realPitch];
pDst[(i*bmpWidth+j)*4+1+realPitch] = pSrc[(i*bmpWidth+j)*3+realPitch];
pDst[(i*bmpWidth+j)*4+realPitch] = nAlpha;
}
}
delete[] pBmpBuf;
pBmpBuf = NULL;
////////////////////////////////////////////////////////////////////////////////
显示32bit的BMP
void Ctest5View::Draw32BitBMP(CMBmp& bmp)
{
Invalidate(TRUE);
UpdateWindow();
int i,j;
CClientDC dc(this);
int pitch = bmp.m_nBmpWidth % 4;
for(i=0;i<bmp.m_nBmpHeight;i++)
{
int realPitch = i * pitch;
for(j=0;j<bmp.m_nBmpWidth;j++)
{
int a = bmp.m_p32BitBmpBuf[(i*bmp.m_nBmpWidth+j)*4+realPitch];
dc.SetPixel(j,i,RGB(
bmp.m_p32BitBmpBuf[(i*bmp.m_nBmpWidth+j)*4+3+realPitch]*(a / 255.0) + 255*(255-a)/255.0,
bmp.m_p32BitBmpBuf[(i*bmp.m_nBmpWidth+j)*4+2+realPitch]*(a / 255.0) + 255*(255-a)/255.0,
bmp.m_p32BitBmpBuf[(i*bmp.m_nBmpWidth+j)*4+1+realPitch]*(a / 255.0) + 255*(255-a)/255.0));
}
}
}
/////////////////////////////////////////////////////////////////////////////////
设置32bit的bmp的alpha通道:
int Ctest5View::Set32BitBmpAlpha(CMBmp& bmp, int nAlpha)
{
int i,j;
int pitch = bmp.m_nBmpWidth % 4;
for(i=0;i<bmp.m_nBmpHeight;i++)
{
int realPitch = i * pitch;
for(j=0;j<bmp.m_nBmpWidth;j++)
{
bmp.m_p32BitBmpBuf[(i*bmp.m_nBmpWidth+j)*4+realPitch] = nAlpha;
}
}
return 0;
}
////////////////////////////////////////////////////////////
2个32bit 的bmp 合成:
if(NULL != m_bmp1.m_p32BitBmpBuf && NULL != m_bmp2.m_p32BitBmpBuf)
{
int bmpHeight,bmpWidth;
bmpHeight = m_bmp1.m_nBmpHeight > m_bmp2.m_nBmpHeight ? m_bmp2.m_nBmpHeight : m_bmp1.m_nBmpHeight;
bmpWidth = m_bmp1.m_nBmpWidth > m_bmp2.m_nBmpWidth ? m_bmp2.m_nBmpWidth : m_bmp1.m_nBmpWidth;
if(NULL != m_bmp3.m_p32BitBmpBuf)
{
delete [] m_bmp3.m_p32BitBmpBuf;
m_bmp3.m_p32BitBmpBuf = NULL;
}
int _32bitBytes_per_line = (bmpWidth * 32 / 8 + 4)/4*4;
m_bmp3.m_p32BitBmpBuf = new BYTE[_32bitBytes_per_line * bmpHeight];
m_bmp3.m_nBmpHeight = bmpHeight;
m_bmp3.m_nBmpWidth = bmpWidth;
int pitch3 = bmpWidth % 4;
int pitch2 = m_bmp2.m_nBmpWidth % 4;
int pitch1 = m_bmp1.m_nBmpWidth % 4;
for(int i=0;i<bmpHeight;i++)
{
int realPitch3 = i * pitch3;
int realPitch2 = i * pitch2;
int realPitch1 = i * pitch1;
for(int j=0;j<bmpWidth;j++)
{
int nIndexA3,nIndexR3,nIndexG3,nIndexB3;
nIndexA3 = (i*bmpWidth+j)*4+realPitch3;
nIndexB3 = (i*bmpWidth+j)*4+1+realPitch3;
nIndexG3 = (i*bmpWidth+j)*4+2+realPitch3;
nIndexR3 = (i*bmpWidth+j)*4+3+realPitch3;
int nIndexA2,nIndexR2,nIndexG2,nIndexB2;
nIndexA2 = (i * m_bmp2.m_nBmpWidth + j)*4+realPitch2;
nIndexB2 = (i * m_bmp2.m_nBmpWidth + j)*4+1+realPitch2;
nIndexG2 = (i * m_bmp2.m_nBmpWidth + j)*4+2+realPitch2;
nIndexR2 = (i * m_bmp2.m_nBmpWidth + j)*4+3+realPitch2;
int nIndexA1,nIndexR1,nIndexG1,nIndexB1;
nIndexA1 = (i * m_bmp1.m_nBmpWidth + j)*4+realPitch1;
nIndexB1 = (i * m_bmp1.m_nBmpWidth + j)*4+1+realPitch1;
nIndexG1 = (i * m_bmp1.m_nBmpWidth + j)*4+2+realPitch1;
nIndexR1 = (i * m_bmp1.m_nBmpWidth + j)*4+3+realPitch1;
m_bmp3.m_p32BitBmpBuf[nIndexA3] = 255.0 * ((m_bmp1.m_p32BitBmpBuf[nIndexA1] / 255.0) + (m_bmp2.m_p32BitBmpBuf[nIndexA2] / 255.0) - (m_bmp1.m_p32BitBmpBuf[nIndexA1] / 255.0) * (m_bmp2.m_p32BitBmpBuf[nIndexA2] / 255.0));
m_bmp3.m_p32BitBmpBuf[nIndexR3] = (255 - m_bmp3.m_p32BitBmpBuf[nIndexA3])/255.0 * m_bmp1.m_p32BitBmpBuf[nIndexR1] + (m_bmp3.m_p32BitBmpBuf[nIndexA3]/255.0) * m_bmp2.m_p32BitBmpBuf[nIndexR2];
m_bmp3.m_p32BitBmpBuf[nIndexG3] = (255 - m_bmp3.m_p32BitBmpBuf[nIndexA3])/255.0 * m_bmp1.m_p32BitBmpBuf[nIndexG1] + (m_bmp3.m_p32BitBmpBuf[nIndexA3]/255.0) * m_bmp2.m_p32BitBmpBuf[nIndexG2];
m_bmp3.m_p32BitBmpBuf[nIndexB3] = (255 - m_bmp3.m_p32BitBmpBuf[nIndexA3])/255.0 * m_bmp1.m_p32BitBmpBuf[nIndexB1] + (m_bmp3.m_p32BitBmpBuf[nIndexA3]/255.0) * m_bmp2.m_p32BitBmpBuf[nIndexB2];
//int a = m_bmp3.m_p32BitBmpBuf[nIndexA3];
//int r = m_bmp3.m_p32BitBmpBuf[nIndexR3];
//int g = m_bmp3.m_p32BitBmpBuf[nIndexG3];
//int b = m_bmp3.m_p32BitBmpBuf[nIndexB3];
//CString msg;
//msg.Format(_T("A:%d R:%d G:%d B:%d"),a,r,g,b);
//AfxMessageBox(msg);
}
}//end for
//show 32bit
m_bComBmp3 = true;
Draw32BitBMP(m_bmp3);
}//end if