讨论:如何将一个视存为位图图像(注意,不是视口,客户区,是整个视) 几个API:BeginPaintGetClientRect(GetWindowRect)CreateCompatibleBitmap -> 获得HBITMAP位图写文件EndPaint 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我创建的是htmlwiew 绘制显示都不是由我管理,我想把整个网页做成位图,但是无论我如何操作得到的总是视口的位图,我怎样才能得到整个视的位图呢,请大家踊跃发表意见,在线等候 GetWindowRect得到整个视的大小,创建屏幕DC,按视的东西抓。 可能是我说的不清楚,说白了 我就是想让程序自动拍照,照下整幅网页 存为.bmp图像,可现在无论我怎么照,都只能照到窗口中正在显示的一部分,各位,我怎样才能照下整个网页呢?帮我出出主意。 写窗口图像到BMP位图文件 WINDOWS的窗口图像从本质上来说,是WINDOWS在内存DC上绘制的一幅图像,我们要将此图像存储起来,首先要获得WINDOWS窗口的区域大小,然后将区域中的图像存在一内存DC中,由于内存DC是与设备相关的位图,所以将它存储起来还要用DDBTODIB函数转换成DIB位图,最后再用WriteDIB函数转储成BMP文件。 BOOL WriteWindowToDIB( LPTSTR szFile, CWnd *pWnd ){ CBitmap bitmap; CWindowDC dc(pWnd); CDC memDC; CRect rect; memDC.CreateCompatibleDC(&dc); pWnd->GetWindowRect(rect); //用窗口区域大小定义一个内存DC ,并将窗口图像暂存其中 bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() ); CBitmap* pOldBitmap = memDC.SelectObject(&bitmap); memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY); // 如果设备支持调色板,创建调色板 CPalette pal; if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE ) { UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256); LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300; pLP->palNumEntries = GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry ); // Create the palette pal.CreatePalette( pLP ); delete[] pLP; } memDC.SelectObject(pOldBitmap); // 转换 bitmap 到 a DIB HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal ); if( hDIB == NULL ) return FALSE; // Write it to file WriteDIB( szFile, hDIB ); // Free the memory allocated by DDBToDIB for the DIB GlobalFree( hDIB ); return TRUE;} 怎么不理解我呢? 以上各位说的还是将窗口存为位图文件,而我想知道的是怎样将整个视存在一幅位图中,例如,我在chtmlview 中到用了 news.sina.com.cn 这一页 我想将全部的新闻标题都存为 位图,而不是窗口中可以看到的部分。 这个问题我现在回答第五遍了,LPTSTR CRemoteC::CopyScreenToBitmap(LPRECT lpRect){HDC hScrDC, hMemDC; // 屏幕和内存设备描述表HBITMAP hBitmap,hOldBitmap; // 位图句柄int nX, nY, nX2, nY2; // 选定区域坐标int nWidth, nHeight; // 位图宽度和高度int xScrn, yScrn; // 屏幕分辨率// 确保选定区域不为空矩形if (IsRectEmpty(lpRect)) return NULL;//为屏幕创建设备描述表hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);//为屏幕设备描述表创建兼容的内存设备描述表hMemDC = CreateCompatibleDC(hScrDC);// 获得选定区域坐标nX = lpRect->left;nY = lpRect->top;nX2 = lpRect->right;nY2 = lpRect->bottom;// 获得屏幕分辨率xScrn = GetDeviceCaps(hScrDC, HORZRES);yScrn = GetDeviceCaps(hScrDC, VERTRES);//确保选定区域是可见的if (nX < 0) nX = 0;if (nY < 0) nY = 0;if (nX2 > xScrn) nX2 = xScrn;if (nY2 > yScrn) nY2 = yScrn;nWidth = nX2 - nX;nHeight = nY2 - nY;// 创建一个与屏幕设备描述表兼容的位图int *temp=new int(m_szResolution.Find("*"));char *pWidth=new char[10];char *pHeight=new char[10];strcpy(pWidth,m_szResolution.Mid(0,*temp));strcpy(pHeight,m_szResolution.Mid(*temp+1));delete temp;int nDestResWidth=atoi(pWidth);int nDestResHeight=atoi(pHeight);delete pWidth;delete pHeight;hBitmap = CreateCompatibleBitmap(hScrDC, nDestResWidth, nDestResHeight);// 把新位图选到内存设备描述表中hOldBitmap=(HBITMAP)::SelectObject(hMemDC, hBitmap);// 把屏幕设备描述表拷贝到内存设备描述表中StretchBlt(hMemDC, 0, 0, nDestResWidth, nDestResHeight,hScrDC, nX, nY,nWidth,nHeight,SRCCOPY);//得到屏幕位图的句柄hBitmap =(HBITMAP) ::SelectObject(hMemDC, hOldBitmap);//清除 DeleteDC(hScrDC);DeleteDC(hMemDC);char tmppath[MAX_PATH];char *tmpname=new char[MAX_PATH];GetTempPath(MAX_PATH,tmppath);GetTempFileName(tmppath,"AnyServer",0,tmpname);//获得一个唯一的临时文件名 SaveBitmapToFile(hBitmap,tmpname);return tmpname;}int CRemoteC::SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName){//我们也可以把屏幕内容以位图格式存到磁盘文件上. //lpFileName 为位图文件名HDC hDC; //设备描述表 int iBits; //当前显示分辨率下每个像素所占字节数WORD wBitCount; //位图中每个像素所占字节数 //定义调色板大小, 位图中像素字节大小,位图文件大小,写入文件字节数DWORD dwPaletteSize=0, dwBmBitsSize, dwDIBSize, dwWritten;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 if (iBits <= 32) wBitCount = 24; //计算调色板大小if (wBitCount <= 8) dwPaletteSize = (1 << wBitCount) * sizeof(RGBQUAD); //设置位图信息头结构 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.biClrUsed = 0; bi.biClrImportant = 0; dwBmBitsSize = ((Bitmap.bmWidth*wBitCount+31)/32)* 4*Bitmap.bmHeight ; hDib = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));//为位图内容分配内存 lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib); *lpbi = bi; hPal=(HPALETTE)::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(lpFileName, 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; }取rect的话只要GetWindowRect就行了 kingzai() 谢谢你不辞劳苦的为大家回答问题,而我想知道的是怎样将整个视存在一幅位图中,例如,我在CHtmlView 中到用了 http://news.sina.com.cn 这一页 我想将全部的新闻标题都存为 位图,而不是窗口中可以看到的部分。 hbs_biscuit: 偶也是来学习的,也是菜鸟,这样说我可无地自容.要想将全部的新闻标题都存为位图 ,如果按我这种方法的话。CopyScreenToBitmap(LPRECT lpRect)的输入参数是要取得矩形区域的大小,而要想将全部的新闻标题都存为 位图,这个可能比较困难,首先要计算各个标题的矩形区域,而且标题的位置大部分都是不固定的,如果取某个特定位置好办,查看当前页面的html文件即可。我的想法是写一个遍历,将位置比较固定的标题存成位图。 kingzai() 唉,就怪我的表达不好,我的意思并不是将特定的html页做成位图(sina.com.cn只是据个例子),由于某些原因我要做一个服务器,他将定期的访问数据库钟的web连接,将得到网页存为位图,我起初想到的是把网页显示出来然后拷屏,但这样做只能拷下显示器上可见的部分。如果我们手动的作这些工作,我们只要先拷一屏,然后拓东滚动条,在继续拷,然后将得到的n 幅图用图像处理软件处理,拼成一幅图即可,但是如果写一个程序模拟这些操作,就显得菜了点,我想找一个跟好的方法。我目前有一个想法-----直接调用 IWebBrowser2接口,这从技术上和代码工作量上都很困难正在考虑别的办法..........如果大家友好的想法,请不吝赐教!!!!也可以在另一张帖子上发表高见http://www.csdn.net/expert/topic/450/450843.shtm 可以这样做:1、先取得ie窗口的IID_IHTMLDOCUMENT2接口 。见http://support.microsoft.com/default.aspx?scid=kb;EN-US;q2492322。取得页面所有元素集合的接口 IHTMLElementCollectionIHTMLElementCollection* pColl; hr = pHTMLDocument2->get_all ( &pColl ); 3。将页面元素存成位图:采取我上面这种方法,不过先要的到页面元素的矩形区域 要是能替换html view的那个OnPaint就好,它应该是根据当前的ClientRect和它自己的DC来画的,我们自己计算画整个页面需要的Rect大小,再创建一个MemDC传进去,让它以为页面上所有的元素都可见,就都画到MemDC上了。 to DoItFreely(Freely):我也是这个想法,可是刚才听高人说Onpaint替了也没用,CHtmlView继承了CFormView 而IWebBrowser只是CFormView上的一个控件被封装了 CSerialPort类 串口号的限制 VC滑动条位置的更新 100分 求 用IAccessible接口访问OutLook Express “新邮件”窗口中的元素 我把我的软件要求写写,大家看看给我提点一下吧,实在没辙了 关于动态连接库的一个初级问题,请高手回答 版面分析:一幅二值图像,如何把其中的文字与图像区域识别出来? ATL 中的接口继承问题 一个关于视频播放的问题???/为什么会出现重影 串口通信的问题 如何解析多重括号,? 100分求拖拉机游戏程序代码,谢谢 写了这样一段代码,结果出现:"0x1021674c"指令引用的"0xcccccccc"内存,该内存不能为"read"
可现在无论我怎么照,都只能照到窗口中正在显示的一部分,各位,我怎样才能照下整个网页呢?帮我出出主意。
WINDOWS的窗口图像从本质上来说,是WINDOWS在内存DC上绘制的一幅图像,
我们要将此图像存储起来,首先要获得WINDOWS窗口的区域大小,然后将区域中的图像
存在一内存DC中,由于内存DC是与设备相关的位图,所以将它存储起来还要用DDBTODIB
函数转换成DIB位图,最后再用WriteDIB函数转储成BMP文件。 BOOL WriteWindowToDIB( LPTSTR szFile, CWnd *pWnd )
{
CBitmap bitmap;
CWindowDC dc(pWnd);
CDC memDC;
CRect rect; memDC.CreateCompatibleDC(&dc); pWnd->GetWindowRect(rect);
//用窗口区域大小定义一个内存DC ,并将窗口图像暂存其中
bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() ); CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY); // 如果设备支持调色板,创建调色板
CPalette pal;
if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300; pLP->palNumEntries =
GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry ); // Create the palette
pal.CreatePalette( pLP ); delete[] pLP;
} memDC.SelectObject(pOldBitmap); // 转换 bitmap 到 a DIB
HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal ); if( hDIB == NULL )
return FALSE; // Write it to file
WriteDIB( szFile, hDIB ); // Free the memory allocated by DDBToDIB for the DIB
GlobalFree( hDIB );
return TRUE;
}
LPTSTR CRemoteC::CopyScreenToBitmap(LPRECT lpRect)
{HDC hScrDC, hMemDC; // 屏幕和内存设备描述表
HBITMAP hBitmap,hOldBitmap; // 位图句柄
int nX, nY, nX2, nY2; // 选定区域坐标
int nWidth, nHeight; // 位图宽度和高度
int xScrn, yScrn; // 屏幕分辨率
// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect)) return NULL;//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);//确保选定区域是可见的if (nX < 0) nX = 0;
if (nY < 0) nY = 0;
if (nX2 > xScrn) nX2 = xScrn;
if (nY2 > yScrn) nY2 = yScrn;
nWidth = nX2 - nX;
nHeight = nY2 - nY;// 创建一个与屏幕设备描述表兼容的位图
int *temp=new int(m_szResolution.Find("*"));
char *pWidth=new char[10];
char *pHeight=new char[10];
strcpy(pWidth,m_szResolution.Mid(0,*temp));
strcpy(pHeight,m_szResolution.Mid(*temp+1));
delete temp;
int nDestResWidth=atoi(pWidth);
int nDestResHeight=atoi(pHeight);
delete pWidth;
delete pHeight;
hBitmap = CreateCompatibleBitmap(hScrDC, nDestResWidth, nDestResHeight);// 把新位图选到内存设备描述表中
hOldBitmap=(HBITMAP)::SelectObject(hMemDC, hBitmap);// 把屏幕设备描述表拷贝到内存设备描述表中
StretchBlt(hMemDC, 0, 0, nDestResWidth, nDestResHeight,hScrDC, nX, nY,nWidth,nHeight,SRCCOPY);
//得到屏幕位图的句柄
hBitmap =(HBITMAP) ::SelectObject(hMemDC, hOldBitmap);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
char tmppath[MAX_PATH];
char *tmpname=new char[MAX_PATH];
GetTempPath(MAX_PATH,tmppath);
GetTempFileName(tmppath,"AnyServer",0,tmpname);//获得一个唯一的临时文件名
SaveBitmapToFile(hBitmap,tmpname);
return tmpname;
}
int CRemoteC::SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName)
{
//我们也可以把屏幕内容以位图格式存到磁盘文件上.
//lpFileName 为位图文件名
HDC hDC; //设备描述表
int iBits; //当前显示分辨率下每个像素所占字节数
WORD wBitCount; //位图中每个像素所占字节数
//定义调色板大小, 位图中像素字节大小,位图文件大小,写入文件字节数
DWORD dwPaletteSize=0,
dwBmBitsSize,
dwDIBSize, dwWritten;
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 if (iBits <= 32)
wBitCount = 24;
//计算调色板大小
if (wBitCount <= 8)
dwPaletteSize = (1 << wBitCount) *
sizeof(RGBQUAD);
//设置位图信息头结构
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.biClrUsed = 0;
bi.biClrImportant = 0; dwBmBitsSize = ((Bitmap.bmWidth*wBitCount+31)/32)* 4*Bitmap.bmHeight ;
hDib = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));//为位图内容分配内存
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
hPal=(HPALETTE)::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(lpFileName, 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;
}
取rect的话只要GetWindowRect就行了
偶也是来学习的,也是菜鸟,这样说我可无地自容.要想将全部的新闻标题都存为位图 ,如果按我这种方法的话。CopyScreenToBitmap(LPRECT lpRect)的输入参数是要取得矩形区域的大小,而要想将全部的新闻标题都存为 位图,这个可能比较困难,首先要计算各个标题的矩形区域,而且标题的位置大部分都是不固定的,如果取某个特定位置好办,查看当前页面的html文件即可。我的想法是写一个遍历,将位置比较固定的标题存成位图。
我目前有一个想法-----直接调用 IWebBrowser2接口,这从技术上和代码工作量上都很困难
正在考虑别的办法..........如果大家友好的想法,请不吝赐教!!!!
也可以在另一张帖子上发表高见
http://www.csdn.net/expert/topic/450/450843.shtm
1、先取得ie窗口的IID_IHTMLDOCUMENT2接口 。见http://support.microsoft.com/default.aspx?scid=kb;EN-US;q249232
2。取得页面所有元素集合的接口 IHTMLElementCollection
IHTMLElementCollection* pColl;
hr = pHTMLDocument2->get_all ( &pColl );
3。将页面元素存成位图:
采取我上面这种方法,不过先要的到页面元素的矩形区域