声明:以下函数均不为自己所写,所以仅供观看,不过确实能用,而且没有错误
转换函数是本人原创,里面调用了这里的函数
//return value:
// 0 OK
// 1 failed
BOOL CDib::OpenFile(const CString &szFileName)
{
CFile f;
if (!f.Open(szFileName,CFile::modeRead))
{
#ifdef _DEBUG
AfxMessageBox("Can't open file:/n"+szFileName,MB_OK);
#endif
return 1;
}
//读入位图信息
void *hbi=ReadBitmapHead(&f);
if (!hbi)
return 1;
//读入位图数据
BITMAPINFOHEADER *lpbi=(BITMAPINFOHEADER *)hbi;
int dwsize=lpbi->biSizeImage;
int dwlen=lpbi->biSize+PaletteSize(*lpbi)+lpbi->biSizeImage;
void *h=realloc(hbi,dwlen);
if (!h)
{
free(hbi);
return 1;
}
hbi=h;
lpbi=(BITMAPINFOHEADER *)hbi;
// dwsize=lpbi->biSizeImage;
// dwlen=lpbi->biSize+PaletteSize(*lpbi)+lpbi->biSizeImage;
UINT temp = PaletteSize(*lpbi);
f.Read((void *)((BYTE*)lpbi+lpbi->biSize+temp),dwsize);
hdib=hbi;
hbm=BitmapFromDib((void *)hdib);
if (!hbm)
{
free(hdib);
hdib=NULL;
return 1;
}
strFileName = szFileName;
return 0;
}
HBITMAP CDib::BitmapFromDib (void *dib)
{
LPBITMAPINFOHEADER lpbi;
HDC hdc;
HBITMAP hbm;
if(!hdib)
return(NULL);
lpbi = (LPBITMAPINFOHEADER)hdib;
WORD wPaletteSize;
hdc = GetDC(NULL);
wPaletteSize = PaletteSize(*lpbi);
hbm = CreateDIBitmap(hdc,
(LPBITMAPINFOHEADER)lpbi,
(DWORD)CBM_INIT,
(BYTE*)lpbi + lpbi->biSize + wPaletteSize,
(LPBITMAPINFO)lpbi,
DIB_RGB_COLORS );
if (!hbm) // Couldn't CreateDIBitmap
{
AfxMessageBox("Can't create bitmap,Function BitmapFromDib failed");
return(NULL);
}
ReleaseDC(NULL,hdc);
return(hbm);
}
void *CDib::ReadBitmapHead(CFile *f)
{
//文件头
BITMAPFILEHEADER bf;
f->Read(&bf,sizeof(BITMAPFILEHEADER));
if (!IsDIB(bf.bfType))
{
AfxMessageBox("File type is not Bitmap, Please select Bitmap",MB_OK);
return(NULL);
}
//信息头
BITMAPINFOHEADER bi;
f->Read(&bi,sizeof(BITMAPINFOHEADER));
int size=bi.biSize;
// switch(size)
// {
// case sizeof(BITMAPINFOHEADER):
// break;
// case sizeof(BITMAPV4HEADER):
// break;
// case sizeof(BITMAPCOREHEADER):
// BITMAPCOREHEADER *bc=(BITMAPCOREHEADER *)&bi;
// bi.biSize=40;
// bi.biWidth=bc->bcWidth;
// bi.biHeight=bc->bcHeight;
// bi.biBitCount=bc->bcBitCount;
// bi.biPlanes=bc->bcPlanes;
// bi.biClrUsed=0;
// bi.biClrImportant=0;
// bi.biCompression=0;
// f->Seek(sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),CFile::current);
// break;
// }
//位图数据的字节数,计算图像每行象素所占的字节数目,设置成4的整数倍
bi.biSizeImage=WIDTHBYTES(bi.biWidth*bi.biBitCount)*bi.biHeight;
//颜色数,对于16、24、32位位图,颜色数为0
int nnumcolors=DibNumColors(bi);
if (bi.biClrUsed==0)
bi.biClrUsed=nnumcolors;
//位图信息=信息头的大小+调色板的大小
void *hbi=malloc( size+ PaletteSize(bi) );
if (!hbi)
{
AfxMessageBox("Can't allocate memory",MB_OK);
return(NULL);
}
//信息头
LPBITMAPINFOHEADER lpbi=(BITMAPINFOHEADER *)hbi;
*lpbi=bi;
//调色板或颜色掩码
RGBQUAD *pRgb=(RGBQUAD*)malloc(256*sizeof(RGBQUAD));
pRgb=(RGBQUAD *)((BYTE*)lpbi+sizeof(BITMAPINFOHEADER));
// if (size==sizeof(BITMAPV4HEADER))
// {
// f->Seek(sizeof(BITMAPV4HEADER)-sizeof(BITMAPINFOHEADER),CFile::current);
// pRgb=(RGBQUAD *)((BYTE*)pRgb+sizeof(BITMAPV4HEADER)-sizeof(BITMAPINFOHEADER));
// }
// else
if (bi.biCompression==BI_BITFIELDS && bi.biBitCount>8)
{
f->Read( pRgb,3*sizeof(DWORD));
pRgb=(RGBQUAD *)((BYTE*)pRgb+3*sizeof(DWORD));
}
if (nnumcolors)//读取调色板信息
{
// if (size==sizeof(BITMAPCOREHEADER))
// {
// f->Read((void *)((BYTE*)pRgb),nnumcolors*sizeof(RGBTRIPLE));
// RGBQUAD rgb;
// for(int i=nnumcolors-1;i >= 0;i--)
// {
// rgb.rgbRed=((RGBTRIPLE *)pRgb)[i].rgbtRed;
// rgb.rgbGreen=((RGBTRIPLE *)pRgb)[i].rgbtGreen;
// rgb.rgbBlue=((RGBTRIPLE *)pRgb)[i].rgbtBlue;
// rgb.rgbReserved=(BYTE)0;
// pRgb[i]=rgb;
// }
// }
// else
{
f->Read((void *)((BYTE*)pRgb),nnumcolors*sizeof(RGBQUAD));
}
}
strFileName = f->GetFilePath();
return(hbi);
}
UINT CDib::DibNumColors(void *dib)
{
BITMAPINFOHEADER *lpbi = (BITMAPINFOHEADER *)dib;
switch (lpbi->biBitCount)
{
case 1:
return(2);
case 4:
return(16);
case 8:
return(256);
default:
return(lpbi->biClrUsed);
}
}
UINT CDib::DibNumColors(BITMAPINFOHEADER bi)
{
switch (bi.biBitCount)
{
case 1:
return(2);
case 4:
return(16);
case 8:
return(256);
default:
return(bi.biClrUsed);
}
}
int CDib::BitsPerPixel()
{
return ((BITMAPINFOHEADER*)hdib)->biBitCount;
}
UINT CDib::BitsPerPixel(BITMAPINFOHEADER bi)
{
return bi.biBitCount;
}
UINT CDib::BitsPerPixel(void *dib)
{
BITMAPINFOHEADER *lpbi = (BITMAPINFOHEADER *)dib;
return lpbi->biBitCount;
}
//调色板数据或颜色掩码占用空间大小
//biBitCount=16、32时,
// 当 biCompression成员的值是BI_RGB,它没有调色板。
// 如果biCompression成员的值是BI_BITFIELDS,原来调色板的位置被三个DWORD变量占据,称为红、绿、蓝掩码。
UINT CDib::PaletteSize()
{
if (hdib)
{
BITMAPINFOHEADER *lpbi=(BITMAPINFOHEADER *)hdib;
if (lpbi->biSize==sizeof(BITMAPINFOHEADER)&&
(lpbi->biBitCount>8)&&(lpbi->biCompression==BI_BITFIELDS))
{
return(3*sizeof(DWORD));
}
else
{
return(DibNumColors(*lpbi)*sizeof(RGBQUAD));
}
}
else
{
return(-1);
}
}
//调色板数据或颜色掩码占用空间大小
//biBitCount=16、32时,
// 当 biCompression成员的值是BI_RGB,它没有调色板。
// 如果biCompression成员的值是BI_BITFIELDS,原来调色板的位置被三个DWORD变量占据,称为红、绿、蓝掩码。
UINT CDib::PaletteSize(BITMAPINFOHEADER bi)
{
if (bi.biSize==sizeof(BITMAPINFOHEADER)&&
(bi.biBitCount>8)&&(bi.biCompression==BI_BITFIELDS))
{
return(3*sizeof(DWORD));
}
else
{
return(DibNumColors(bi)*sizeof(RGBQUAD));
}
}
BITMAPINFOHEADER CDib::GetBitmapInfo()
{
BITMAPINFOHEADER bi;
memcpy((void *)&bi,(void *)hdib,sizeof(BITMAPINFOHEADER));
return(bi);
}
BOOL CDib::DrawBitmap(CDC *pDC,int xOffset,int yOffset)
{
BITMAPINFO *lpbf;
BITMAPINFOHEADER *lpbi;
if (hdib)
{
lpbf=(BITMAPINFO *)hdib;
lpbi=(BITMAPINFOHEADER *)hdib;
::SetDIBitsToDevice(pDC->m_hDC,
xOffset,yOffset,
lpbi->biWidth,ABS(int(lpbi->biHeight)),
0,0,
0,ABS(int(lpbi->biHeight)),
(void *)((BYTE*)lpbi+lpbi->biSize+PaletteSize(*lpbi)),
lpbf,
DIB_RGB_COLORS);
// CDC memDc;
// memDc.CreateCompatibleDC(pDC);
// memDc.SelectObject(hbm);
// pDC->BitBlt(0,0,lpbi->biWidth,lpbi->biHeight,&memDc,0,0,SRCCOPY);
}
return(TRUE);
}
UINT CDib::Width()
{
if (hdib)
{
BITMAPINFOHEADER *lpbi=(BITMAPINFOHEADER *)hdib;
return lpbi->biWidth;
}
else
{
return(0);
}
}
int CDib::Height()
{
if (hdib)
{
BITMAPINFOHEADER *lpbi=(BITMAPINFOHEADER *)hdib;
return lpbi->biHeight;
}
else
{
return(0);
}
}
void *CDib::GetBits()
{
if (hdib)
{
return((void *)((BYTE*)hdib+sizeof(BITMAPINFOHEADER)));
}
else
{
return(NULL);
}
}
BOOL CDib::SaveFile(LPCSTR szFileName)
{
CFile f;
if(!f.Open(szFileName,CFile::modeCreate|CFile::shareDenyWrite|CFile::modeWrite))
{
AfxMessageBox("无法打开文件");
return(FALSE);
}
BITMAPFILEHEADER bf;
bf.bfType=0x4d42;
bf.bfSize=sizeof(BITMAPFILEHEADER)+_msize(hdib);
bf.bfReserved1=0;
bf.bfReserved2=0;
bf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+PaletteSize();
f.Write((void *)&bf,sizeof(BITMAPFILEHEADER));
f.Write(hdib,_msize(hdib));
f.Close();
strFileName = szFileName;
return(TRUE);
}
CDib& CDib::operator=(CDib &dib)
{
int size;
FreeDib();
size=_msize(dib.hdib);
hdib=malloc(size);
memcpy(hdib,dib.hdib,size);
hbm=BitmapFromDib(hdib);
return(*this);
}
BOOL CDib::SetBitmapinfoAndBits(BITMAPINFOHEADER bi, void *bits)
{
int size;
void *newdib;
BITMAPINFOHEADER *lpbi;
size=_msize(bits);
newdib=malloc(sizeof(BITMAPINFOHEADER)+size);
if (!newdib)
{
AfxMessageBox("can't allocate memory");
return(FALSE);
}
FreeDib();
hdib=newdib;
lpbi=(BITMAPINFOHEADER *)newdib;
*lpbi=bi;
newdib=(void *)((BYTE*)newdib+sizeof(BITMAPINFOHEADER));
memcpy(newdib,bits,size);
if (!BitmapFromDib(hdib))
{
AfxMessageBox("can't create a new bitmap");
return(FALSE);
}
return(TRUE);
}
void CDib::FreeDib()
{
if (hdib)
{
free(hdib);
hdib = NULL;
}
if (hbm)
DeleteObject(hbm);
}