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


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