原文地址:http://blog.youkuaiyun.com/hxmcnu/article/details/12359731
参数定义
private:
BYTE * BmpBuffer;//24BMP位图数据
long bmpWidth ;
long bmpHeight;
BYTE *p32BitBuf;//32位BMP数据
int totalSize;//数据大小
int bytes_per_line;//每行的字节数
int m_nAlpha1;//32位BMP中alpha值,用于调节通明度
public:
bool Open24BMP();
bool Show24BMP();
bool Show32BMP();
bool Conver24To32(int m_nAlpha1);
int Set32BitBmpAlpha(int nAlpha);
相关功能实现:
//读取一张24bit的BMP保存到个BYTE buffer里面:
bool CConverBMPDlg::Open24BMP()
{
//
BYTE *pBmpBuf;
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 false;
}
BITMAPFILEHEADER fileheader={0};
fread(&fileheader,sizeof(fileheader),1,fp);
if(fileheader.bfType!=0x4D42)
{
fclose(fp);
return false ;
}
BITMAPINFOHEADER head;
fread(&head,sizeof(BITMAPINFOHEADER),1,fp);
bmpWidth = head.biWidth;
bmpHeight = head.biHeight;
WORD biBitCount = head.biBitCount;
if(biBitCount != 24)
{
::AfxMessageBox(_T("choose a 24 bit bmp"));
fclose(fp);
return false ;
}
bytes_per_line = (bmpWidth * biBitCount/8+3)/4*4;
totalSize = bytes_per_line*bmpHeight;
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;
BmpBuffer = new BYTE[totalSize];//24位BMP Buffer
buffer = new BYTE[totalSize];//temp buf to flip 24bit bmp map
memcpy(buffer,pBmpBuf,totalSize);
for (index=0; index < bmpHeight; index++)
memcpy(&BmpBuffer[((bmpHeight-1) - index)*bytes_per_line],
&buffer[index*bytes_per_line], bytes_per_line);
delete[] buffer;
buffer = NULL;
return true;
}
bool CConverBMPDlg::Show24BMP()
{
//显示一下:
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(
BmpBuffer[(i*bmpWidth+j)*3+2+realPitch],
BmpBuffer[(i*bmpWidth+j)*3+1+realPitch],
BmpBuffer[(i*bmpWidth+j)*3+realPitch]));
}
}
return true;
}
bool CConverBMPDlg::Conver24To32(int m_nAlpha1)
{
//将24bit转成32bit,添加Alpha通道:
//convert to 32bit
int _32bitBytes_per_line = (bmpWidth * 32 / 8 + 4)/4*4;
p32BitBuf = new BYTE[_32bitBytes_per_line * bmpHeight];//32 bit buf
int nAlpha = m_nAlpha1;//60%:153
BYTE *pSrc = BmpBuffer;
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;
}
}
return true;
}
bool CConverBMPDlg::Show32BMP()
{
//显示32bit的BMP
Invalidate(TRUE);
UpdateWindow();
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++)
{
int a = p32BitBuf[(i*bmpWidth+j)*4+realPitch];
dc.SetPixel(j,i,RGB(
p32BitBuf[(i*bmpWidth+j)*4+3+realPitch]*(a / 255.0) + 255*(255-a)/255.0,
p32BitBuf[(i*bmpWidth+j)*4+2+realPitch]*(a / 255.0) + 255*(255-a)/255.0,
p32BitBuf[(i*bmpWidth+j)*4+1+realPitch]*(a / 255.0) + 255*(255-a)/255.0));
}
}
return true;
}
//设置32bit的bmp的alpha通道:
int CConverBMPDlg::Set32BitBmpAlpha(int nAlpha)
{
int i,j;
int pitch = bmpWidth % 4;
for(i=0;i<bmpHeight;i++)
{
int realPitch = i * pitch;
for(j=0;j<bmpWidth;j++) 0
{
p32BitBuf[(i*bmpWidth+j)*4+realPitch] = nAlpha;
}
}
return 0;
}
void RGB32Rotate180(BYTE *des,BYTE *src,int width,int height)
{
if ((!des)||(!src))
{
return;
}
int n = 0;
int linesize = width*4;
for (int index=0; index < height; index++)
memcpy(&des[((height-1) - index)*linesize],&src[index*linesize], linesize);
}