急急急!!关于位图处理的问题 唉,本来对图形编程就不熟,可公司偏偏让我做一个这方面的项目,现在遇到一个问题,就是我现在有一个HDC,但如何才能的把它里面的图像保存为BMP文件呢?各位大哥救救命啊,跪谢了,5555 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 How to save CDC object? Answer:CDC dcmem; dcmem.CreateCompatibleDC(&dc); CBitmap bmp; CRect rc; GetClientRect(&rc); bmp.CreateCompatibleBitmap(&dc,rc.Width(),rc.Height()); dcmem.SelectObject(&bmp); dcmem.BitBlt(0,0,rc.Width(),rc.Height(),&dc,0,0,SRCCOPY); SaveBmp(bmp,"c:\\a.bmp");void SaveBmp(HBITMAP hbmp, LPCTSTR sIconFileName){ if(hbmp==NULL || sIconFileName==NULL) return; //warning: this code snippet is not bullet proof. //do error check by yourself [masterz] PICTDESC picdesc; picdesc.cbSizeofstruct = sizeof(PICTDESC); picdesc.picType = PICTYPE_BITMAP ; picdesc.bmp.hpal = NULL; picdesc.bmp.hbitmap = hbmp; IPicture* pPicture=NULL; OleCreatePictureIndirect(&picdesc, IID_IPicture, TRUE,(VOID**)&pPicture); LPSTREAM pStream; CreateStreamOnHGlobal(NULL,TRUE,&pStream); LONG size; HRESULT hr=pPicture->SaveAsFile(pStream,TRUE,&size); char pathbuf[1024]; strcpy(pathbuf,sIconFileName); CFile iconfile; iconfile.Open(pathbuf, CFile::modeCreate|CFile::modeWrite); LARGE_INTEGER li; li.HighPart =0; li.LowPart =0; ULARGE_INTEGER ulnewpos; pStream->Seek( li,STREAM_SEEK_SET,&ulnewpos); ULONG uReadCount = 1; while(uReadCount>0) { pStream->Read(pathbuf,sizeof(pathbuf),&uReadCount); if(uReadCount>0) iconfile.Write(pathbuf,uReadCount); } pStream->Release(); iconfile.Close();} 最土的办法就是先创建位图对象,然后把DC上的点的RGB值逐个写入该对象 ///这个是桌面DCHDC hSr=GetDC(GetDesktopWindow());HDC hdc=CreateCompatibleDC(hSr);HBITMAP hbmp=CreateCompatibleBitmap(hSr,1024,768);SelectObject(hdc,(HGDIOBJ)hbmp);::StretchBlt(hdc,0,0,1024,768,hSr,0,0,1024,768,SRCCOPY);SaveBmp(hbmp,"Test.bmp");//your save functionDeleteDC(hdc);ReleaseDC(hSr);http://search.csdn.net/Expert/topic/1924/1924477.xml?temp=.5980188 最土的办法就是先创建位图对象,然后把DC上的点的RGB值逐个写入该对象这个方法还是可行的。 占个位子1:写位图文件BOOL SaveBmp(HBITMAP hBitmap, CString FileName){ HDC hDC; //当前分辨率下每象素所占字节数 int iBits; //位图中每象素所占字节数 WORD wBitCount; //定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数 DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0; //位图属性结构 BITMAP Bitmap; //位图文件头结构 BITMAPFILEHEADER bmfHdr; //位图信息头结构 BITMAPINFOHEADER bi; //指向位图信息头结构 LPBITMAPINFOHEADER lpbi; //定义文件,分配内存句柄,调色板句柄 HANDLE fh, hDib, hPal,hOldPal=NULL; //计算位图文件每个像素所占字节数 hDC = CreateDC("DISPLAY", NULL, NULL, NULL); iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES); DeleteDC(hDC); if (iBits <= 1) wBitCount = 1; else if (iBits <= 4) wBitCount = 4; else if (iBits <= 8) wBitCount = 8; else wBitCount = 24; GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = Bitmap.bmWidth; bi.biHeight = Bitmap.bmHeight; bi.biPlanes = 1; bi.biBitCount = wBitCount; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrImportant = 0; bi.biClrUsed = 0; dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight; //为位图内容分配内存 hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER)); lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib); *lpbi = bi; // 处理调色板 hPal = GetStockObject(DEFAULT_PALETTE); if (hPal) { hDC = ::GetDC(NULL); hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE); RealizePalette(hDC); } // 获取该调色板下新的像素值 GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) +dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS); //恢复调色板 if (hOldPal) { ::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE); RealizePalette(hDC); ::ReleaseDC(NULL, hDC); } //创建位图文件 fh = CreateFile(FileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (fh == INVALID_HANDLE_VALUE) return FALSE; // 设置位图文件头 bmfHdr.bfType = 0x4D42; // "BM" dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize; bmfHdr.bfSize = dwDIBSize; bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize; // 写入位图文件头 WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); // 写入位图文件其余内容 WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL); //清除 GlobalUnlock(hDib); GlobalFree(hDib); CloseHandle(fh); return TRUE;}:取出某个DC上面的位图HBITMAP GetSrcBit(HDC hDC,DWORD BitWidth, DWORD BitHeight){ HDC hBufDC; HBITMAP hBitmap, hBitTemp; //创建设备上下文(HDC) hBufDC = CreateCompatibleDC(hDC); //创建HBITMAP hBitmap = CreateCompatibleBitmap(hDC, BitWidth, BitHeight); hBitTemp = (HBITMAP) SelectObject(hBufDC, hBitmap); //得到位图缓冲区 StretchBlt(hBufDC, 0, 0, BitWidth, BitHeight, hDC, 0, 0, BitWidth, BitHeight, SRCCOPY); //得到最终的位图信息 hBitmap = (HBITMAP) SelectObject(hBufDC, hBitTemp); //释放内存 ::DeleteDC(hBufDC); return hBitmap;} 请教关于VC 通过进程ID 获得相关EXE 的窗口句柄的问题。 怎么样优化这段寻找路径的代码? VC 如何获取扫描仪序列号 有相关的类文件没有? 关于webbrower 滚动条问题? 使用sscanf函数给浮点数赋值时出现内存访问冲突 提示是指针错误 请大家帮忙推荐本OLE编程的好书 DAO里怎么实现再查询啊 请问如何在ATL中对注册表进行下列操作 来者有分! 并口通讯的问题 用net start启动服务出现异常,请高人指点 新手提问,登陆编译成功,运行时出现错误,求助!!
Answer:
CDC dcmem;
dcmem.CreateCompatibleDC(&dc);
CBitmap bmp;
CRect rc;
GetClientRect(&rc);
bmp.CreateCompatibleBitmap(&dc,rc.Width(),rc.Height());
dcmem.SelectObject(&bmp);
dcmem.BitBlt(0,0,rc.Width(),rc.Height(),&dc,0,0,SRCCOPY);
SaveBmp(bmp,"c:\\a.bmp");
void SaveBmp(HBITMAP hbmp, LPCTSTR sIconFileName)
{
if(hbmp==NULL || sIconFileName==NULL)
return;
//warning: this code snippet is not bullet proof.
//do error check by yourself [masterz]
PICTDESC picdesc;
picdesc.cbSizeofstruct = sizeof(PICTDESC);
picdesc.picType = PICTYPE_BITMAP ;
picdesc.bmp.hpal = NULL;
picdesc.bmp.hbitmap = hbmp;
IPicture* pPicture=NULL;
OleCreatePictureIndirect(&picdesc, IID_IPicture, TRUE,(VOID**)&pPicture);
LPSTREAM pStream;
CreateStreamOnHGlobal(NULL,TRUE,&pStream);
LONG size;
HRESULT hr=pPicture->SaveAsFile(pStream,TRUE,&size);
char pathbuf[1024];
strcpy(pathbuf,sIconFileName);
CFile iconfile;
iconfile.Open(pathbuf, CFile::modeCreate|CFile::modeWrite);
LARGE_INTEGER li;
li.HighPart =0;
li.LowPart =0;
ULARGE_INTEGER ulnewpos;
pStream->Seek( li,STREAM_SEEK_SET,&ulnewpos);
ULONG uReadCount = 1;
while(uReadCount>0)
{ pStream->Read(pathbuf,sizeof(pathbuf),&uReadCount);
if(uReadCount>0)
iconfile.Write(pathbuf,uReadCount);
}
pStream->Release();
iconfile.Close();
}
HDC hSr=GetDC(GetDesktopWindow());
HDC hdc=CreateCompatibleDC(hSr);
HBITMAP hbmp=CreateCompatibleBitmap(hSr,1024,768);
SelectObject(hdc,(HGDIOBJ)hbmp);
::StretchBlt(hdc,0,0,1024,768,hSr,0,0,1024,768,SRCCOPY);
SaveBmp(hbmp,"Test.bmp");//your save function
DeleteDC(hdc);
ReleaseDC(hSr);http://search.csdn.net/Expert/topic/1924/1924477.xml?temp=.5980188
这个方法还是可行的。
1:写位图文件
BOOL SaveBmp(HBITMAP hBitmap, CString FileName)
{
HDC hDC;
//当前分辨率下每象素所占字节数
int iBits;
//位图中每象素所占字节数
WORD wBitCount;
//定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;
//位图属性结构
BITMAP Bitmap;
//位图文件头结构
BITMAPFILEHEADER bmfHdr;
//位图信息头结构
BITMAPINFOHEADER bi;
//指向位图信息头结构
LPBITMAPINFOHEADER lpbi;
//定义文件,分配内存句柄,调色板句柄
HANDLE fh, hDib, hPal,hOldPal=NULL;
//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1) wBitCount = 1;
else if (iBits <= 4) wBitCount = 4;
else if (iBits <= 8) wBitCount = 8;
else wBitCount = 24;
GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrImportant = 0;
bi.biClrUsed = 0;
dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;
//为位图内容分配内存
hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi; // 处理调色板
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
hDC = ::GetDC(NULL);
hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
} // 获取该调色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
+dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, hDC);
} //创建位图文件
fh = CreateFile(FileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE) return FALSE;
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
// 写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh); return TRUE;
}:取出某个DC上面的位图
HBITMAP GetSrcBit(HDC hDC,DWORD BitWidth, DWORD BitHeight)
{
HDC hBufDC;
HBITMAP hBitmap, hBitTemp; //创建设备上下文(HDC)
hBufDC = CreateCompatibleDC(hDC); //创建HBITMAP
hBitmap = CreateCompatibleBitmap(hDC, BitWidth, BitHeight);
hBitTemp = (HBITMAP) SelectObject(hBufDC, hBitmap);
//得到位图缓冲区
StretchBlt(hBufDC, 0, 0, BitWidth, BitHeight,
hDC, 0, 0, BitWidth, BitHeight, SRCCOPY); //得到最终的位图信息
hBitmap = (HBITMAP) SelectObject(hBufDC, hBitTemp); //释放内存 ::DeleteDC(hBufDC); return hBitmap;
}