#include "DibBMP.h"
#include <fstream>
#define WIDTHBYTES(i) ((i+31)/32*4)
CDibBMP::CDibBMP(void)
{
}
CDibBMP::~CDibBMP(void)
{
}
BOOL CDibBMP::LoadBitmap(char *filename)
{
std::ifstream fileBmp;//(filename);
fileBmp.open(filename,std::ios::binary);
if (!fileBmp)
{
MessageBox(NULL, "无法打开喔", "XinXin's WinMain", MB_OK | MB_ICONINFORMATION);
fileBmp.close();
return false;
}
fileBmp.read ((char*)&bitmap.bitmapfileheader,sizeof(BITMAPFILEHEADER)) ;
if (bitmap.bitmapfileheader.bfType != ((WORD) ('M'<<8)|'B'))// 判断是否是DIB对象
{
fileBmp.close();
MessageBox(NULL, "不是0x4D42-BMP", "XinXin's WinMain", MB_OK | MB_ICONINFORMATION);
return NULL;// 如果不是则返回NULL。
}
numQuad=0;
if (bitmap.bitmapinfoheader.biBitCount<24)
numQuad=1<<bitmap.bitmapinfoheader.biBitCount;
fileBmp.read( (char*)&bitmap.bitmapinfoheader, sizeof(BITMAPINFOHEADER));
Info = (BITMAPINFO*)HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER) + 24*sizeof(RGBQUAD));
memcpy(Info,&bitmap.bitmapinfoheader,sizeof(bitmap.bitmapinfoheader));
quad=(RGBQUAD*)(BYTE*)Info+sizeof(BITMAPINFOHEADER);
fileBmp.read ((char*)quad,sizeof(RGBQUAD)*numQuad);
bitmap.bitmapinfoheader .biSizeImage =bitmap.bitmapfileheader.bfSize -bitmap .bitmapfileheader.bfOffBits;
lpBuf=(BYTE*)HeapAlloc(GetProcessHeap(),0,bitmap.bitmapinfoheader .biSizeImage);
fileBmp.read ((char*)lpBuf,bitmap.bitmapinfoheader .biSizeImage);
// BmpBit = bitmap.bitmapinfoheader.biBitCount;
//
//
// int BmpDataSize = 0;
//
// if(bitmap.bitmapinfoheader.biSizeImage > 0)
// BmpDataSize = bitmap.bitmapinfoheader.biSizeImage;
// else
// BmpDataSize = bitmap.bitmapinfoheader.biWidth * bitmap.bitmapinfoheader.biBitCount * bitmap.bitmapinfoheader.biHeight;
//
//
//
// fileBmp.seekg((BmpDataSize)*(-1), std::ios::end);
// bitmap.Buffer = new UCHAR[BmpDataSize];
// memset(bitmap.Buffer,1,BmpDataSize);
//
//
//int dataline;
//
// if(bitmap.bitmapinfoheader.biHeight >= 0)
// {
// IMAGE_Width = bitmap.bitmapinfoheader.biWidth;
// IMAGE_Height = bitmap.bitmapinfoheader.biHeight;
//
// //biHeight >= 0, 图像数据上下倒置(如图片左上角的像素颜色值在图像数据的左下角),因此翻转图像
// UCHAR *temp;
// temp = new UCHAR[BmpDataSize];
// memcpy(temp, bitmap.Buffer, BmpDataSize);
//
// // Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充
// dataline=(IMAGE_Width * bitmap.bitmapinfoheader.biBitCount+31)/32*4;
// //int del;
// //int dataline = bitmap->bitmapinfoheader.biWidth * bitmap->bitmapinfoheader.biBitCount /8;
// //if( (del = dataline%4) != 0 )dataline += 4 - del;
//
// //翻转
// for(int i = 0; i < IMAGE_Height; i++)
// memcpy(&bitmap.Buffer[(IMAGE_Height-1 -i)*(long)dataline], &temp[i*(long)dataline], dataline);//memcpy单位:字节,扫描线必须为4BYTES倍数
//
// delete []temp;
// }
// else
// {
// IMAGE_Width = bitmap.bitmapinfoheader.biWidth;
// IMAGE_Height = -bitmap.bitmapinfoheader.biHeight;
// }
//
//
//
//
// //BmpDC = CreateCompatibleDC(DrawDeviceHandler);
// // if(bitmap.Buffer != NULL)bitmap.Buffer = NULL;
// // mBMP = CreateDIBSection(dc, (BITMAPINFO *)&bitmap.bitmapinfoheader,
// // DIB_RGB_COLORS, (void **)&bitmap.Buffer, NULL, 0);
// fileBmp.read( (char*)bitmap.Buffer, bitmap.bitmapinfoheader.biSizeImage );
//
//
// ::SetDIBitsToDevice (dc,0,0,0,0,0,0,dataline,dataline,bitmap.Buffer,(BITMAPINFO*)&(bitmap.bitmapinfoheader) ,DIB_RGB_COLORS);
fileBmp.close();//关闭ifstream对像
return TRUE;
}
void CDibBMP::ShowBmp(HDC hdc,int oriXpos, int OriYpos, int width, int height)
{
long bitsAlloc = 32 * 480;
long headerSize = sizeof(BITMAPINFOHEADER); if ((hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, bitsAlloc + headerSize)) == 0)
// return FALSE;
Info = (BITMAPINFO *)::GlobalLock(hGlobal);
//Bits = (void *)((char *)Info + headerSize);
//Info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
//Info->bmiHeader.biWidth = width;
//Info->bmiHeader.biHeight = height;
//Info->bmiHeader.biBitCount = (unsigned short)24;
//Info->bmiHeader.biPlanes = 1;
//Info->bmiHeader.biXPelsPerMeter = 0;
//Info->bmiHeader.biYPelsPerMeter = 0;
//Info->bmiHeader.biClrUsed = 0;
//Info->bmiHeader.biClrImportant = 0;
//Info->bmiHeader.biCompression = BI_RGB;
//Info->bmiHeader.biSizeImage = bitsAlloc;
int n = 119 * ((640 * 480 + 31) / 32)* 4 + (24 + 7) / 8;
SetDIBitsToDevice(hdc, 0, 0,
640, 480,
0, 0, 0, 640,
(char*)n,
Info,
DIB_RGB_COLORS);
//ViewImage.GetBits() = (char *)(640 -480 - 1) * (640 * 480 + 31) / 32) * 4; + (24 + 7) / 8);
//ViewImage.GetInfo(),
//::SetDIBitsToDevice(dc, 0, 0,
// ViewImage.Width(), ViewImage.Height(),
// 0, 0, 0, ViewImage.Height(),
// ViewImage.GetBits(),
// ViewImage.GetInfo(),
// DIB_RGB_COLORS);
}
void CDibBMP::Show(char *filename)
{
BITMAPFILEHEADER m_bmfh;//BMP文件头变量
BITMAPINFOHEADER m_bmih;//BMP文件信息变量
std::ifstream fileBmp;//(filename);
char *m_pImgData=NULL;
/* CFile file;
CFileDialog dlg(TRUE);
if(dlg.DoModal()==IDCANCEL)
return;
file.Open(dlg.GetPathName(),CFile::modeRead);
file.Read(&m_bmfh,sizeof(m_bmfh));
file.Read(&m_bmih,sizeof(m_bmih)); */
fileBmp.read ((char*)&m_bmfh,sizeof(m_bmfh)) ;
fileBmp.read ((char*)&m_bmfh,sizeof(m_bmfh)) ;
m_pImgData=new char[m_bmih.biSizeImage];
fileBmp.seekg(m_bmfh.bfOffBits,0);
fileBmp.read (m_pImgData,m_bmih.biSizeImage);
fileBmp.close ();
// CClientDC dc(this);
//SetDIBitsToDevice(dc.m_hDC,
//0,0,
//m_bmih.biWidth,m_bmih.biHeight,
//0,0,
//0,m_bmih.biHeight,
//m_pImgData,
//(BITMAPINFO*)&m_bmih,
//DIB_RGB_COLORS);
delete m_pImgData;
}
BOOL CDibBMP::Show1(HWND hWnd,char *filename)
{
// HFILE hf;
HANDLE hf;
LPBITMAPINFOHEADER lpImgData;
LPSTR lpPtr;
LPBITMAPINFOHEADER lpTempImgData;
LPSTR lpNewPtr;
LOGPALETTE *pPal;
LPRGBQUAD lpRGB;
HPALETTE hPrevPalette;
HDC hDc;
HLOCAL hPal;
DWORD ImgSize;
DWORD i;
char temp[100];
DWORD bytesread;
//BITMAPFILEHEADER bf,bfNew;
//BITMAPINFOHEADER bi;
std::ifstream fileBmp;//(filename);
fileBmp.open(filename,std::ios::binary);
if (!fileBmp)
{
MessageBox(NULL, "无法打开喔", "XinXin's WinMain", MB_OK | MB_ICONINFORMATION);
fileBmp.close();
return false;
}
fileBmp.read ((char*)&bf,sizeof(BITMAPFILEHEADER)) ;
fileBmp.read( (char*)&bi, sizeof(BITMAPINFOHEADER));
if (bf.bfType != ((WORD) ('M'<<8)|'B'))// 判断是否是DIB对象
{
fileBmp.close();
MessageBox(NULL, "不是0x4D42-BMP", "XinXin's WinMain", MB_OK | MB_ICONINFORMATION);
return NULL;// 如果不是则返回NULL。
}
//hf = file.GetFileTitle(0);
// hf = CreateFile(BmpFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,
// OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
//if((hf=_lopen(BmpFileName,OF_READ))==HFILE_ERROR)
//if( hf == NULL){
// MessageBox(hWnd,"file can not open","Error Message",MB_OK|MB_ICONEXCLAMATION);
// return FALSE;
//}
//ReadFile(hf,&bf,sizeof(BITMAPFILEHEADER),&bytesread,NULL);
//ReadFile(hf,&bi,sizeof(BITMAPINFOHEADER),&bytesread,NULL);
memcpy(&bfNew,&bf,sizeof(BITMAPFILEHEADER));
// _lread(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER));
// _lread(hf,(LPSTR)&bi,sizeof(BITMAPINFOHEADER));
ImgWidth=bi.biWidth;
ImgHeight=bi.biHeight;
LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
ImgSize=(DWORD)LineBytes*bi.biHeight;
switch(bi.biBitCount){
case 1:
NumColors=2;
// SetWindowText(hWnd,"2");
// _sleep(1000);
break;
case 4:
NumColors=16;
// SetWindowText(hWnd,"4");
// _sleep(1000);
break;
case 8:
NumColors=256;
// SetWindowText(hWnd,"8");
// _sleep(1000);
break;
case 24:
NumColors=0;//真彩色不用调色板
// SetWindowText(hWnd,"24");
// _sleep(1000);
break;
default:
MessageBox(hWnd,"Invalid color numbers!","Error Message",MB_OK|MB_ICONEXCLAMATION);
// _lclose(hf);
CloseHandle(hf);
return FALSE;
}
if(bf.bfOffBits!=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)))
{//偏移有误:即颜色数有误
MessageBox(hWnd,"Invalid color numbers!","Error Message" ,MB_OK|
MB_ICONEXCLAMATION);
// _lclose(hf);
CloseHandle(hf);
return FALSE;
}
bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;
if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+
NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
{//分配内存
MessageBox(hWnd,"Error alloc memory!","ErrorMessage",MB_OK|
MB_ICONEXCLAMATION);
// _lclose(hf);
CloseHandle(hf);
return FALSE;
}
if((hTempImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+
NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
{//分配内存
MessageBox(hWnd,"Error alloc memory!","ErrorMessage",MB_OK|
MB_ICONEXCLAMATION);
// _lclose(hf);
if(hf != NULL)
CloseHandle(hf);
return FALSE;
}
lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
lpTempImgData = (LPBITMAPINFOHEADER)GlobalLock(hTempImgData);
fileBmp.seekg(sizeof(BITMAPFILEHEADER), std::ios::beg);
fileBmp.read ((char*)lpImgData,sizeof(BITMAPINFOHEADER) + NumColors*sizeof(RGBQUAD) + ImgSize);
HDC dc;
dc = GetDC(hWnd);
SetDIBitsToDevice(dc,0,0,640,480,0,0,640,480,(void*)4220,(BITMAPINFO*)lpImgData,DIB_RGB_COLORS);
//SetFilePointer(hf,sizeof(BITMAPFILEHEADER),NULL,FILE_BEGIN);
//fileBmp.seekg (
//ReadFile(hf,(char *)lpImgData,sizeof(BITMAPINFOHEADER) + NumColors*sizeof(RGBQUAD) + ImgSize,&bytesread,NULL);
//CloseHandle(hf);
//lpPtr = (char*)lpImgData;
//lpNewPtr = (char*)lpTempImgData;
//memcpy(lpNewPtr,lpPtr,bf.bfSize - sizeof(BITMAPFILEHEADER));
// if(NumColors!=0)//用到了调色板
//{
// hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) + NumColors* sizeof(PALETTEENTRY));
// pPal =(LOGPALETTE *)LocalLock(hPal);
// pPal->palNumEntries =(WORD) NumColors;
// pPal->palVersion = 0x300;
// //移到调色板的开始处
// lpRGB = (LPRGBQUAD)((LPSTR)lpImgData + (DWORD)sizeof(BITMAPINFOHEADER));
// for (i = 0; i < NumColors; i++) {
// pPal->palPalEntry[i].peRed=lpRGB->rgbRed;
// pPal->palPalEntry[i].peGreen=lpRGB->rgbGreen;
// pPal->palPalEntry[i].peBlue=lpRGB->rgbBlue;
// pPal->palPalEntry[i].peFlags=(BYTE)0;
// lpRGB++;
// }
// hPalette=CreatePalette(pPal);//创建逻辑调色板
// LocalUnlock(hPal);
// LocalFree(hPal);
//}
//hDc=GetDC(hWnd);
//if(hPalette){
// hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
// RealizePalette(hDc);
//}
////如果有调色板先将调色板调入内存中
//hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpImgData, (LONG)CBM_INIT,
// (LPSTR)lpImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
// (LPBITMAPINFO)lpImgData, DIB_RGB_COLORS);
////再把原调色板调入内存
//if(hPalette && hPrevPalette){
// SelectPalette(hDc,hPrevPalette,FALSE);
// RealizePalette(hDc);
//}
//ReleaseDC(hWnd,hDc);
GlobalUnlock(hTempImgData);
GlobalUnlock(hImgData);
return TRUE;
}