各位大侠,我用的是wince系统。在执行下面的程序时,一旦点击保存按钮button1,调用Save32BitmapToFile,就会弹出对话框,说out of memory.是不是程序中位图头文件的大小设置的问题?对这个不是很懂,请指教。
void Cwince位图Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
Save32BitmapToFile(hBitmap,TEXT("aa.bmp"));}int Cwince位图Dlg::Save32BitmapToFile(HBITMAP hBitmap, LPCTSTR lpFileName)
{
HWND hWnd = ::FindWindow(NULL,L"wince位图");
if ( IsWindow( hWnd ) )
{
hdc = ::GetDC( hWnd ); // 得到指定主窗口的DC,主窗口改名字,这里也得改
}
HDC hOffDC=CreateCompatibleDC(hdc);
SelectObject(hOffDC,hBitmap);//将兼容窗口句柄存到hBitmap中
BITMAP Bitmap;
GetObject(hBitmap,sizeof(BITMAP),&Bitmap);
HANDLE fh=CreateFile (lpFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if(fh == INVALID_HANDLE_VALUE )
return FALSE; BITMAPFILEHEADER bfh;
memset(&bfh,0,sizeof(bfh));
bfh.bfType=0x4D42/*((WORD) ('M' << 8) | 'B')*/;//是"BM"类型的意思
//bfh.bfSize= sizeof(bfh)+4*Bitmap.bmWidth*Bitmap.bmHeight+sizeof(BITMAPFILEHEADER);
bfh.bfSize= sizeof(bfh)+(Bitmap.bmWidth*Bitmap.bmHeight)/8;
bfh.bfOffBits=sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER);
DWORD dwWritten=0;
WriteFile(fh,&bfh,sizeof(bfh),&dwWritten,NULL);
BITMAPINFOHEADER bih;
memset(&bih,0,sizeof(bih));
bih.biSize=sizeof(bih);
bih.biWidth=Bitmap.bmWidth;
bih.biHeight=Bitmap.bmHeight;
bih.biPlanes=1;
bih.biBitCount=8;
bih.biCompression=BI_BITFIELDS; if( !WriteFile(fh,&bih,sizeof(bih),&dwWritten,NULL))
{
return FALSE;
}
BITMAPINFO bitmapInfo;
memset((void *)&bitmapInfo,0,sizeof(BITMAPINFO));
bitmapInfo.bmiHeader=bih;
bitmapInfo.bmiColors[0].rgbRed=255;
bitmapInfo.bmiColors[0].rgbGreen=255;
bitmapInfo.bmiColors[0].rgbBlue=255; HDC hMemDC=CreateCompatibleDC(hdc);
//BYTE *m_lpBitBmp=new BYTE[4*Bitmap.bmWidth*Bitmap.bmHeight];
BYTE *m_lpBitBmp=new BYTE[Bitmap.bmWidth*Bitmap.bmHeight];
HBITMAP hDibBitmap=CreateDIBSection(hMemDC,&bitmapInfo,DIB_RGB_COLORS,(void **)&m_lpBitBmp,NULL,0);
if(hDibBitmap != 0)
{
::SelectObject(hMemDC,hDibBitmap);
BitBlt(hMemDC,0,0,Bitmap.bmWidth,Bitmap.bmHeight,hOffDC,0,0,SRCCOPY);
//WriteFile(fh,m_lpBitBmp,4*Bitmap.bmWidth*Bitmap.bmHeight,&dwWritten,NULL);
WriteFile(fh,m_lpBitBmp,Bitmap.bmWidth*Bitmap.bmHeight,&dwWritten,NULL);
}
DeleteObject(hDibBitmap);
DeleteDC(hdc);
DeleteDC(hMemDC); CloseHandle(fh); return 0;
}
void Cwince位图Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
Save32BitmapToFile(hBitmap,TEXT("aa.bmp"));}int Cwince位图Dlg::Save32BitmapToFile(HBITMAP hBitmap, LPCTSTR lpFileName)
{
HWND hWnd = ::FindWindow(NULL,L"wince位图");
if ( IsWindow( hWnd ) )
{
hdc = ::GetDC( hWnd ); // 得到指定主窗口的DC,主窗口改名字,这里也得改
}
HDC hOffDC=CreateCompatibleDC(hdc);
SelectObject(hOffDC,hBitmap);//将兼容窗口句柄存到hBitmap中
BITMAP Bitmap;
GetObject(hBitmap,sizeof(BITMAP),&Bitmap);
HANDLE fh=CreateFile (lpFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if(fh == INVALID_HANDLE_VALUE )
return FALSE; BITMAPFILEHEADER bfh;
memset(&bfh,0,sizeof(bfh));
bfh.bfType=0x4D42/*((WORD) ('M' << 8) | 'B')*/;//是"BM"类型的意思
//bfh.bfSize= sizeof(bfh)+4*Bitmap.bmWidth*Bitmap.bmHeight+sizeof(BITMAPFILEHEADER);
bfh.bfSize= sizeof(bfh)+(Bitmap.bmWidth*Bitmap.bmHeight)/8;
bfh.bfOffBits=sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER);
DWORD dwWritten=0;
WriteFile(fh,&bfh,sizeof(bfh),&dwWritten,NULL);
BITMAPINFOHEADER bih;
memset(&bih,0,sizeof(bih));
bih.biSize=sizeof(bih);
bih.biWidth=Bitmap.bmWidth;
bih.biHeight=Bitmap.bmHeight;
bih.biPlanes=1;
bih.biBitCount=8;
bih.biCompression=BI_BITFIELDS; if( !WriteFile(fh,&bih,sizeof(bih),&dwWritten,NULL))
{
return FALSE;
}
BITMAPINFO bitmapInfo;
memset((void *)&bitmapInfo,0,sizeof(BITMAPINFO));
bitmapInfo.bmiHeader=bih;
bitmapInfo.bmiColors[0].rgbRed=255;
bitmapInfo.bmiColors[0].rgbGreen=255;
bitmapInfo.bmiColors[0].rgbBlue=255; HDC hMemDC=CreateCompatibleDC(hdc);
//BYTE *m_lpBitBmp=new BYTE[4*Bitmap.bmWidth*Bitmap.bmHeight];
BYTE *m_lpBitBmp=new BYTE[Bitmap.bmWidth*Bitmap.bmHeight];
HBITMAP hDibBitmap=CreateDIBSection(hMemDC,&bitmapInfo,DIB_RGB_COLORS,(void **)&m_lpBitBmp,NULL,0);
if(hDibBitmap != 0)
{
::SelectObject(hMemDC,hDibBitmap);
BitBlt(hMemDC,0,0,Bitmap.bmWidth,Bitmap.bmHeight,hOffDC,0,0,SRCCOPY);
//WriteFile(fh,m_lpBitBmp,4*Bitmap.bmWidth*Bitmap.bmHeight,&dwWritten,NULL);
WriteFile(fh,m_lpBitBmp,Bitmap.bmWidth*Bitmap.bmHeight,&dwWritten,NULL);
}
DeleteObject(hDibBitmap);
DeleteDC(hdc);
DeleteDC(hMemDC); CloseHandle(fh); return 0;
}
这样不够啊。
bitmapInfo.bmiColors[0].rgbRed=255;
bitmapInfo.bmiColors[0].rgbGreen=255;
bitmapInfo.bmiColors[0].rgbBlue=255;
void OnScreenSave(const char *filename,HDC hScrDC)
{
HDC hMemDC;
int width, height;
//指向象素缓冲
BYTE *lpBitmapBits = NULL;
//创建设备上下文
//hScrDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL); //屏幕大小
width = GetDeviceCaps(hScrDC, HORZRES);
height = GetDeviceCaps(hScrDC, VERTRES); //内存DC
hMemDC = CreateCompatibleDC(hScrDC); //初始化 BITMAPINFO
//为了在WINCE上使用 CreateDIBSection ,每个象素都存储为24位,且无压缩biCompression=0)
BITMAPINFO RGB24BitsBITMAPINFO;
ZeroMemory(&RGB24BitsBITMAPINFO, sizeof(BITMAPINFO));
RGB24BitsBITMAPINFO.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
RGB24BitsBITMAPINFO.bmiHeader.biWidth = width;
RGB24BitsBITMAPINFO.bmiHeader.biHeight = height;
RGB24BitsBITMAPINFO.bmiHeader.biPlanes = 1;
RGB24BitsBITMAPINFO.bmiHeader.biBitCount = 24; //使用 CreateDIBSection 建立一个HBITMAP,以获得 图像数据指针 lpBitmapBits
HBITMAP directBmp = CreateDIBSection(hMemDC, (BITMAPINFO*)&RGB24BitsBITMAPINFO,
DIB_RGB_COLORS, (void **)&lpBitmapBits, NULL, 0);
//SelectObject 将directBmp选入内存DC
HGDIOBJ previousObject = SelectObject(hMemDC, directBmp); //将屏幕DC拷贝到内存DC
BitBlt(hMemDC, 0, 0, width, height, hScrDC, 0, 0, SRCCOPY); //if you only want to get the every pixel color value,
//you can begin here and the following part of this function will be unuseful;
//the following part is in order to write file; //位图文件头
BITMAPFILEHEADER bmBITMAPFILEHEADER;
ZeroMemory(&bmBITMAPFILEHEADER, sizeof(BITMAPFILEHEADER));
bmBITMAPFILEHEADER.bfType = 0x4d42; //bmp
bmBITMAPFILEHEADER.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmBITMAPFILEHEADER.bfSize = bmBITMAPFILEHEADER.bfOffBits + ((width*height)*3); ///3=(24 / 8) //写入文件
FILE *mStream = NULL;
if((mStream = fopen(filename, "wb")))
{
//写文件头
fwrite(&bmBITMAPFILEHEADER, sizeof(BITMAPFILEHEADER), 1, mStream);
//写位图信息
fwrite(&(RGB24BitsBITMAPINFO.bmiHeader), sizeof(BITMAPINFOHEADER), 1, mStream);
//写象素值
fwrite(lpBitmapBits, 3*width*height, 1, mStream);
//关闭文件
fclose(mStream);
} //释放资源
DeleteObject(hMemDC);
DeleteObject(hScrDC);
DeleteObject(directBmp);
DeleteObject(previousObject);
}
谢谢各位,我先试试hhwei1985的方法。
帖子再留两天,希望大家关注~~