您的位置:首页 > 其它

MFC 关于BMP 24bit 和 32bit的操作

2013-10-06 22:35 288 查看
定义结构:

.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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: