8位位圖轉換爲24位位圖
主要的轉換程序
*函數功能:將8位位圖轉換爲24位位圖
*函數聲明:
BOOL Bitmap8To24(
BYTE* srcImage, -指向源圖像的像素數據的指針
BYTE* dstImage, -指向目的圖像的像素數據的指針
LONG imageWidth, -源圖像的寬度(像素數)
LONG imageHeight -源圖像的高度(像素數)
)
******************************************************************************/
BOOL Bitmap8To24(BYTE* srcImage,BYTE* dstImage,LONG imageWidth,LONG imageHeight)
{
LONG lLineBytes24=((imageWidth*24+31)/32*4);
LONG lLineBytes8=((imageWidth*8+31)/32*4);
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;
}
}
return true;
}
完整的轉換程序
{
// TODO: Add your control notification handler code here
if(m_dib.GetBitCount()==0)
{
AfxMessageBox("請先打開位圖");
return;
}
{
AfxMessageBox("已經是24位位圖");
return;
}
{
CString filename;
char szFilter[]="位圖文件(*.bmp;*.dib)|*.bmp;*.dib|All Files(*.*)|*.*||";
CFileDialog dlg(false,"*.bmp",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter);
if(dlg.DoModal()==IDOK)
{
UpdateData(true);
filename=dlg.GetPathName();
}
else
{
return;
}
char* file=(char*)filename.GetBuffer(filename.GetLength());
filename.ReleaseBuffer();
if(fp==0)
{
AfxMessageBox("保存出錯");
return;
}
bf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
bf.bfReserved1=0;
bf.bfReserved2=0;
bf.bfSize=m_dib.GetHeight()*m_dib.GetWidthBytes(m_dib.GetWidth(),24)+bf.bfOffBits;
bf.bfType=((WORD)'M'<<8|'B');
fwrite(&bf,sizeof(BITMAPFILEHEADER),1,fp);
bi.biBitCount=24;
bi.biClrImportant=0;
bi.biClrUsed=0;
bi.biCompression=0L;
bi.biHeight=m_dib.GetHeight();
bi.biPlanes=1;
bi.biSize=sizeof(BITMAPINFOHEADER);
bi.biSizeImage=m_dib.GetHeight()*m_dib.GetWidthBytes(m_dib.GetWidth(),24);
bi.biWidth=m_dib.GetWidth();
bi.biXPelsPerMeter=0;
bi.biYPelsPerMeter=0;
fwrite(&bi,sizeof(BITMAPINFOHEADER),1,fp);
BYTE* image=new BYTE[m_dib.GetHeight()*lLineBytes24];
{
AfxMessageBox("轉換過程錯誤");
return;
}
fclose(fp);
//delete[] image;
}
}
24位位圖轉換爲8位位圖
主要的轉換程序
*函數功能:將24位位圖轉換爲8位位圖
*函數聲明:
BOOL Bitmap24To8(
BYTE* srcImage, -指向源圖像的像素數據的指針
BYTE* dstImage, -指向目的圖像的像素數據的指針
LONG imageWidth, -源圖像的寬度
LONG imageHeight -源圖像的高度
)
******************************************************************************/
BOOL Bitmap24To8(BYTE* srcImage,BYTE* dstImage,LONG imageWidth,LONG imageHeight)
{
LONG lLineBytes=((imageWidth*24+31)/32*4);
LONG lLineBytes8=((imageWidth*8+31)/32*4);
for(int i=0;i<imageHeight;i++)
{
for(j=0,n=0;j<lLineBytes&&n<lLineBytes8;j++,n++)
{
BYTE B=*(srcImage+lLineBytes*i+j);
j++;
BYTE G=*(srcImage+lLineBytes*i+j);
j++;
BYTE R=*(srcImage+lLineBytes*i+j);
}
}
}
完整的轉換程序
{
// TODO: Add your control notification handler code here
if(m_dib.GetBitCount()==0)
{
AfxMessageBox("請先打開圖片");
return;
}
else if(m_dib.GetBitCount()==8)
{
AfxMessageBox("已經是8位位圖");
return;
}
else
{
CString filename;
char szFilter[]="位圖文件(*.bmp;*.dib)|*.bmp;*.dib|All Files(*.*)|*.*||";
CFileDialog dlg(false,"*.bmp",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter);
if(dlg.DoModal()==IDOK)
{
UpdateData(true);
filename=dlg.GetPathName();
}
else
{
return;
}
char* file=(char*)filename.GetBuffer(filename.GetLength());
filename.ReleaseBuffer();
if(fp==0)
{
AfxMessageBox("保存出錯");
return;
}
bf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256;
bf.bfReserved1=0;
bf.bfReserved2=0;
bf.bfSize=m_dib.GetHeight()*m_dib.GetWidthBytes(m_dib.GetWidth(),8)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256;
bf.bfType=((WORD)'M'<<8|'B');
fwrite(&bf,sizeof(BITMAPFILEHEADER),1,fp);
BITMAPINFO* pInfo=m_dib.GetBitmapInfo();
bi.biBitCount=8;
bi.biClrImportant=0;
bi.biClrUsed=0;
bi.biCompression=0L;
bi.biHeight=m_dib.GetHeight();
bi.biPlanes=1;
bi.biSize=sizeof(BITMAPINFOHEADER);
bi.biSizeImage=m_dib.GetHeight()*m_dib.GetWidthBytes(m_dib.GetWidth(),8);
bi.biWidth=m_dib.GetWidth();
bi.biXPelsPerMeter=0;
bi.biYPelsPerMeter=0;
fwrite(&bi,sizeof(BITMAPINFOHEADER),1,fp);
fwrite(&(pInfo->bmiColors),sizeof(RGBQUAD),256,fp);
if(!Bitmap24To8(m_dib.GetDibData(),image,m_dib.GetWidth(),m_dib.GetHeight()))
{
AfxMessageBox("轉換像素過程中出錯");
return;
}
fwrite(image,m_dib.GetHeight()*m_dib.GetWidthBytes(m_dib.GetWidth(),8),1,fp);
fclose(fp);
delete[] image;
AfxMessageBox("保存完畢");
}
}
程序運行時截圖
打開位圖的程序
//用CFile對象實現打開位圖
BOOL CDib::OpenImage(CString filename)
{
CFile file;
file.Open(filename,CFile::modeRead);
//讀取位圖文件頭
BITMAPFILEHEADER bmfh;
int nbmfh=file.Read(&bmfh,sizeof(BITMAPFILEHEADER));
if(nbmfh!=sizeof(BITMAPFILEHEADER))
{
AfxMessageBox("讀取文件頭失敗");
return false;
}
if(bmfh.bfType==0x4d42)
{
//計算位圖信息頭的大小
BITMAPINFOHEADER bmih;
file.Seek(sizeof(BITMAPFILEHEADER),CFile::begin);
int nbmih=file.Read(&bmih,sizeof(BITMAPINFOHEADER));
if(nbmih!=sizeof(BITMAPINFOHEADER))
{
AfxMessageBox("讀取位圖信息頭失敗");
return false;
}
m_nWidth=bmih.biWidth;
m_nHeight=bmih.biHeight;
m_nBitCount=bmih.biBitCount;
m_lLineBytes=GetWidthBytes(m_nWidth,m_nBitCount);
file.Seek(bmfh.bfOffBits,CFile::begin);
//爲像素數據分配空間
m_lpDibData=new BYTE[m_nHeight*m_lLineBytes];
DWORD dwdib=file.Read(m_lpDibData,m_nHeight*m_lLineBytes);
if(dwdib!=static_cast<DWORD>(m_nHeight*m_lLineBytes))
{
AfxMessageBox("讀取像素數據失敗");
return false;
}
if(m_nBitCount==8)
{
BITMAPINFO* bitmapInfo=(BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256];
memcpy(&bitmapInfo->bmiHeader,&bmih,sizeof(BITMAPINFOHEADER));
if(bmih.biClrUsed!=0)
{
for(int i=0;i<(int)bmih.biClrUsed;i++)
{
bitmapInfo->bmiColors[i].rgbBlue=i;
bitmapInfo->bmiColors[i].rgbGreen=i;
bitmapInfo->bmiColors[i].rgbRed=i;
bitmapInfo->bmiColors[i].rgbReserved=0;
}
}
else
{
for(int i=0;i<256;i++)
{
bitmapInfo->bmiColors[i].rgbBlue=i;
bitmapInfo->bmiColors[i].rgbGreen=i;
bitmapInfo->bmiColors[i].rgbRed=i;
bitmapInfo->bmiColors[i].rgbReserved=0;
}
}
m_pBitmapInfo=bitmapInfo;
}
else if(m_nBitCount==24)
{
BITMAPINFO* bitmapInfo=(BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER)];
memcpy(bitmapInfo,&bmih,sizeof(BITMAPINFOHEADER));
m_pBitmapInfo=bitmapInfo;
}
}
else
{
AfxMessageBox("打開的不是位圖文件");
return false;
}
file.Close();
return true;
}
保存位圖的程序
BOOL CDib::SaveImage(CString filename)
{
//如果保存時的文件名爲空,則返回
if(filename=="")
{
AfxMessageBox("文件名不能爲空");
return false;
}
CFile file;
file.Open(filename,CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
//建立一個位圖文件頭變量,併爲此變量賦值
BITMAPFILEHEADER bf;
if(m_nBitCount==8)
{
//如果位圖是8位的,則位圖像素數據的偏移地址就爲位圖前三部分的字節數之和
//即爲:文件頭+信息頭+調色板的大小
bf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256;
}
else if(m_nBitCount==24)
{
//如果位圖是24位的,則位圖像素數據的偏移地址就爲位圖的前兩部分的字節數之和
//即爲:文件頭+信息頭
bf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
}
else
{
AfxMessageBox("暫時只能保存8或24位位圖");
return false;
}
//將位圖文件頭中的保留爲都置零
bf.bfReserved1=0;
bf.bfReserved2=0;
if(m_nBitCount==8)
{
//如果位圖爲8位的,則位圖文件大小就爲位圖的四部分之和
//即爲:文件頭+信息頭+調色板+像素數據
bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256+m_nHeight*m_lLineBytes;
}
else if(m_nBitCount==24)
{
//如果位圖爲24位的,則位圖文件大小就爲位圖的三部分之和
//即爲:文件頭+信息頭+像素數據
bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+m_nHeight*m_lLineBytes;
}
else
{
AfxMessageBox("暫時只能保存8或24位位圖");
return false;
}
//位圖文件的類型爲BM
bf.bfType=((WORD)'M'<<8|'B');
//將位圖文件頭寫入文件
file.Write(&bf,sizeof(BITMAPFILEHEADER));
//建立位圖信息頭,並準備爲其各項賦值
BITMAPINFOHEADER bi;
//將位圖的位數存入信息頭的biBitCount中
bi.biBitCount=m_nBitCount;
//將圖像顯示有重要影響的顏色索引的數目,如果是0,表示都重要
bi.biClrImportant=0;
//說明位圖實際使用的彩色表中的顏色索引數(設爲0的話,則說明使用所有調色板項)
bi.biClrUsed=0;
//目標設備說明位面數,其值總是被設爲1
bi.biPlanes=1;
//說明圖像數據壓縮的類型
bi.biCompression=0L;
//說明圖像的寬度,以像素爲單位
bi.biHeight=m_nHeight;
//說明圖像的寬度,以像素爲單位
bi.biWidth=m_nWidth;
//說明BITMAPINFOHEADER結構所需要的字節數
bi.biSize=sizeof(BITMAPINFOHEADER);
//說明圖像的大小,以字節爲單位。當用BI_RGB格式時,可設置爲0
bi.biSizeImage=m_nHeight*m_lLineBytes;
//說明圖像的水平分辨率,用像素/米來表示
bi.biXPelsPerMeter=0;
//說明圖像的垂直分辨率,用像素/米來表示
bi.biYPelsPerMeter=0;
//將信息頭寫入文件
file.Write(&bi,sizeof(BITMAPINFOHEADER));
if(m_nBitCount==8)
{
//如果是8位位圖,還需要寫入調色板
file.Write(&m_pBitmapInfo->bmiColors,256*sizeof(RGBQUAD));
//寫入像素數據
file.Write(m_lpDibData,m_nHeight*m_lLineBytes);
//關閉文件
file.Close();
}
else if(m_nBitCount==24)
{
//寫入像素數據
file.Write(m_lpDibData,m_nHeight*m_lLineBytes);
//關閉文件
file.Close();
}
else
{
file.Close();
AfxMessageBox("只能寫入8或24位位圖");
return false;
}
return true;
}