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

定义结构:
.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 

你可能感兴趣的:(MFC 关于BMP 24bit 和 32bit的操作)