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;
}