BMP的8位位图转换24位位图

#define WIDTHBYTES(bits) (((bits)+31)/32*4)  //一行的位数
/******************************************************************************
*函数功能:获取位图信息
*函数声明:
   BOOL GetNormalBmpInfo(
   CString m_strFile,  -位图路径
   nWidth,  -位图宽度
   nHeight:位图高度
   biBitCount:位数
   pbi,获取位图地址
   lpBits:获取位图的实际数据
    )
******************************************************************************/
bool GetNormalBmpInfo(CString m_strFile,int &nWidth,int &nHeight, int &iBitCount,BITMAPINFO**pbi,void** lpBits)// 获取标准BMP文件的长度和高度
{
CFile file;
if( !file.Open( m_strFile, CFile::modeRead) )
return false;
BITMAPFILEHEADER bmfHeader;
//读位图文件头信息
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return false;
//判断是否是BMP
if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
return false;
//读位图头信息
BITMAPINFOHEADER bmiHeader;
if (file.Read((LPSTR)&bmiHeader, sizeof(bmiHeader)) !=sizeof(bmiHeader))
return false;
//获得大小信息,并显示
nWidth = bmiHeader.biWidth;
nHeight = bmiHeader.biHeight;
iBitCount = bmiHeader.biBitCount;
int numQuad = 0;
if(bmiHeader.biBitCount < 24)////小于24位有调色板
{
numQuad = 1 << bmiHeader.biBitCount;
//为图像信息pbi申请空间
//* pbi=(BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD));
* pbi=(BITMAPINFO*)new BYTE[sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD)];
memcpy(*pbi,&bmiHeader,sizeof(bmiHeader));
RGBQUAD* quad =(RGBQUAD*)((BYTE*)(*pbi)+sizeof(BITMAPINFOHEADER));
//读取调色板
if(numQuad!=0)
{
file.Read(quad,sizeof(RGBQUAD)*numQuad);
}
}
DWORD fileLength =  bmiHeader.biWidth* bmiHeader.biHeight;//总文件大小
DWORD  size = fileLength -sizeof(BITMAPFILEHEADER);//文件大小-文件头结构体的大小,此时你会发现,文件头的大小的确是14字节
bmiHeader.biSizeImage = file.GetLength() - bmfHeader.bfOffBits;
//int l_width = WIDTHBYTES( bmiHeader.biWidth* bmiHeader.biBitCount);//计算位图的实际宽度并确保它为32的倍数
//long nSize = l_width*bmiHeader.biHeight;
*lpBits = (BYTE*)new BYTE[bmiHeader.biSizeImage];
file.Read((void*)(*lpBits), bmiHeader.biSizeImage);//通过读取,把读出的数据存入刚才分配的内存之中
file.Close();//文件操作完成之后关闭文件
return true;
}

/******************************************************************************

*函数功能:将8位位图转换为24位位图
*函数声明:
   BOOL Bitmap8To24(
    BYTE* srcImage,  -指向源图像的像素数据的指针
    BYTE* dstImage,  -指向目的图像的像素数据的指针
BITMAPINFO* lpbi,=位图信息地址
    LONG imageWidth, -源图像的宽度(像素数)
    LONG imageHeight -源图像的高度(像素数)
    )
******************************************************************************/
BOOL CDIB::Bitmap8To24(BYTE* srcImage,BYTE* dstImage,BITMAPINFO* lpbi,LONG imageWidth,LONG imageHeight)
{
LONG lLineBytes24=((imageWidth*24+31)/32*4);
LONG lLineBytes8=((imageWidth*8+31)/32*4);
int n,j;
/*for(int i=0;i<imageHeight;i++)
{
for(j=0,n=0;j<lLineBytes8;j++,n++)//这部分为转换成灰度图像
{
BYTE gray=*(srcImage+lLineBytes8*i+j);
*(dstImage+lLineBytes24*i+n)=gray;
n++;
*(dstImage+lLineBytes24*i+n)=gray;
n++;
*(dstImage+lLineBytes24*i+n)=gray;
}
}*/


//因为24位是用三位表示一个颜色(顺序是BGR),没有调色板,而8位的是一位表示一个颜色信息在调色板中的偏移量
RGBQUAD *pRgb = (RGBQUAD *)((BYTE*)lpbi+sizeof(BITMAPINFOHEADER));
for( int i=0; i<imageHeight; i++)
{
for( j=0, n=0; j<lLineBytes8; j++)
{
int num = *(srcImage+lLineBytes8*i+j);//获取8位中调色板信息的偏移量
//将颜色信息写入24位指针指向的地址(为了保证dstBits始终指向首地址,故不写成dst=...)
*(dstImage+lLineBytes24*i+n)=pRgb[num].rgbBlue;
n++;
*(dstImage+lLineBytes24*i+n)=pRgb[num].rgbGreen;
n++;
*(dstImage+lLineBytes24*i+n)=pRgb[num].rgbRed;
n++;
}
}
return true;

}

注意:上面两个函数已经根据8位图信息转为24位实际数据,接下来可以自己加入24位头部信息生成图像。

参考地址:http://blog.csdn.net/poonjun/article/details/3701641

http://blog.csdn.net/yjn43422757/article/details/6493658

http://blog.csdn.net/yjn43422757/article/details/6493662


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章