请教各位高手一个超难问题,关于自动截取IE界面并保存为一张图片的,请进来看看... 我想实现这么一个功能:用IE随便打开某个网站,然后将IE中显示的网站内容保存为一张图片,功能类似于抓屏软件,但是不需要用户干预,有办法能够实现么?请教编程如何实现!给各思路也可以,但希望说的详细些。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你可以用VC来自己编一个带浏览功能的程序,视图类从CHtmlView继承。然后可以把你打开的网站抓下来存为bmp或者jpg文件。原理如下:1、得到整个屏幕的DC:HDC hDisplay = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);2、得到屏幕的宽度和高度:int nScreenWidth = GetDeviceCaps(hDisplay, HORZRES); int nScreenHeight = GetDeviceCaps(hDisplay, VERTRES);3、创建一个内存中的DC: HDC hMemDc = CreateCompatibleDC(hDisplay);4、创建一个内存中的位图: HBITMAP hBmp = CreateCompatibleBitmap(hDisplay, nScreenWidth, nScreenHeight);5、把位图和DC绑定在一起: HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDc, hBmp);6、把整个屏幕的内容复制到内存DC中: BitBlt(hMemDc, 0, 0, nScreenWidth, nScreenHeight, hDisplay, 0, 0, SRCCOPY);7、再次绑定(例子上这么做,不知道为什么) hBmp = (HBITMAP)SelectObject(hMemDc, hOldBmp);8、分配内存(BMP图片文件大小),初始化位图结构体(省略)9、利用GetDIBits函数得到位图的象素信息: GetDIBits(hDisplay, hBmp, 0, nScreenHeight, pBits, (BITMAPINFO *)pInfoHeader, DIB_RGB_COLORS);10、创建文件,保存位图这里是源代码://复制屏幕void CopyScreen(const char *pFilePath){ //首先得到整个屏幕的句柄 HDC hDisplay = CreateDC(_T("DISPLAY"), NULL, NULL, NULL); _ASSERT(NULL!=hDisplay); //得到屏幕的大小 int nScreenWidth = GetDeviceCaps(hDisplay, HORZRES); int nScreenHeight = GetDeviceCaps(hDisplay, VERTRES); //创建内存DC HDC hMemDc = CreateCompatibleDC(hDisplay); _ASSERT(NULL != hMemDc); //创建位图 HBITMAP hBmp = CreateCompatibleBitmap(hDisplay, nScreenWidth, nScreenHeight); _ASSERT(NULL != hBmp); //选择位图 HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDc, hBmp); _ASSERT(NULL != (DWORD)hOldBmp || GDI_ERROR != (DWORD)hOldBmp); //复制图形 BOOL blnReturnValue = BitBlt(hMemDc, 0, 0, nScreenWidth, nScreenHeight, hDisplay, 0, 0, SRCCOPY); _ASSERT(0 != blnReturnValue); //再次选择 hBmp = (HBITMAP)SelectObject(hMemDc, hOldBmp); _ASSERT(NULL != (DWORD)hBmp || GDI_ERROR != (DWORD)hBmp); DeleteDC(hMemDc); hMemDc = NULL; int nBits = GetDeviceCaps(hDisplay, BITSPIXEL); //每个象素的位数 DWORD dwLineBits = 0; //每行字节数 switch (nBits) { case 16: dwLineBits = nScreenWidth*2; break; case 24: dwLineBits = (nScreenWidth+1)*3-((nScreenWidth+1)*3)%4; break; case 32: dwLineBits = nScreenWidth*4; break; default: //其他情况(这里产生资源泄漏,只是例子,所以没管) MessageBox(NULL, _T("不支持该格式!"), _T("不支持!"), MB_OK); break; } //下面分配内存 DWORD dwBitsCount = dwLineBits * nScreenHeight; DWORD dwFileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBitsCount; BYTE * pMem = (BYTE *)GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT, dwFileSize); if (NULL == pMem) { MessageBox(hWnd, _T("分配内存失败!"), _T("错误!"), MB_OK); return; } BITMAPFILEHEADER* pBMPHeader = (BITMAPFILEHEADER*)pMem; BITMAPINFOHEADER* pInfoHeader = (BITMAPINFOHEADER*)((BYTE *)pBMPHeader + sizeof(BITMAPFILEHEADER)); BYTE* pBits = (BYTE*)pInfoHeader + sizeof(BITMAPINFOHEADER); //下面初始化 pBMPHeader->bfType = ('M'<<8) | 'B'; pBMPHeader->bfSize = dwFileSize; pBMPHeader->bfReserved1 = 0; pBMPHeader->bfReserved2 = 0; pBMPHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); pInfoHeader->biSize = sizeof(BITMAPINFOHEADER); pInfoHeader->biWidth = nScreenWidth; pInfoHeader->biHeight = nScreenHeight; pInfoHeader->biPlanes = GetDeviceCaps(hDisplay, PLANES); //调色板数 pInfoHeader->biBitCount = nBits; pInfoHeader->biCompression = BI_RGB; pInfoHeader->biSizeImage = dwBitsCount; pInfoHeader->biXPelsPerMeter = GetDeviceCaps(hDisplay, LOGPIXELSX); pInfoHeader->biYPelsPerMeter = GetDeviceCaps(hDisplay, LOGPIXELSY); pInfoHeader->biClrUsed = 0; pInfoHeader->biClrImportant = 0; //下面得到数据 int nLines = GetDIBits(hDisplay, hBmp, 0, nScreenHeight, pBits, (BITMAPINFO *)pInfoHeader, DIB_RGB_COLORS); if (0 == nLines) { DWORD errno = GetLastError(); MessageBox(hWnd, _T("复制位图数据失败"), _T("错误!"), MB_OK); return; } DeleteDC(hDisplay); hDisplay = NULL; DeleteObject(hBmp); hBmp = NULL; DeleteObject(hOldBmp); hOldBmp = NULL; //下面保存文件 HANDLE hFile = CreateFile(pFilePath, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (NULL == hFile || INVALID_HANDLE_VALUE == hFile) { MessageBox(hWnd, _T("文件已经存在!"), _T("错误!"), MB_OK); return; } //写入 DWORD dwWriteCount = 0; if (!WriteFile(hFile, (void *)pBMPHeader, dwFileSize, &dwWriteCount, NULL)) { MessageBox(NULL, _T("写入文件失败!"), _T("错误"), MB_OK | MB_ICONEXCLAMATION); CloseHandle(hFile); return; } //关闭文件 CloseHandle(hFile); GlobalFree((void *)pBMPHeader);}、、也可以保存为jpg格式的,不过比较蛮烦,不讲了。 http://support.microsoft.com/support/kb/articles/Q249/2/32.asphttp://www.codeproject.com/internet/htmlimagecapture.asp HWND hWnd = NULL;hWndIE = ::FindWindow("Internet Explorer_Server",NULL);CDC dcIE;HDC hdcIE = ::GetDC(hWndIE);dcIE.Attach(hdcIE);HBITMAP hBitmapIE = dcIE.GetCurrentBitmap();然后把hBitmapIE 保存成bmp文件,具体怎么保存看我的blog 我很想知道如何把截下来的图片直接保存为jpg档案,哪位大哥可否给一个实现代码,谢谢! bmp保存成jpgint GetEncoderClsid(const WCHAR* format, CLSID* pClsid){ UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if(size == 0) return -1; // Failure pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if(pImageCodecInfo == NULL) return -1; // Failure GetImageEncoders(num, size, pImageCodecInfo); for(UINT j = 0; j < num; ++j) { if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) { *pClsid = pImageCodecInfo[j].Clsid; free(pImageCodecInfo); return j; // Success } } free(pImageCodecInfo); return -1; // Failure}void BMP2JPG(CString strBMPFile,CString strJPGFile){ CLSID encoderClsid; WCHAR strGuid[39]; if(GetEncoderClsid(L"image/jpeg", &encoderClsid) >= 0) StringFromGUID2(encoderClsid, strGuid, 39); Image image(strBMPFile.AllocSysString()); image.Save(strJPGFile.AllocSysString(),&encoderClsid,NULL);} 我这里有一个调用dll来把bmp保存为jpg的例子。如果你要的话,发一份请求到我油箱:[email protected] CListCtrl的问题 【请教】最近在试验vc2008编程 遇到一些问题请各位老师指导 vista操作系统下opengl 的双缓冲PFD_DOUBLEBUFFER为什么不起作用?100分 请教ado中的PutCollect()函数报错问题 mp3的结构和组成? 工作线程中数据如何传递给界面线程? 丢开Wizard, 自由创建应用程序窗口 如何注册自己创建的文件类型的默认打开文件啊? 如何向别的程序发消息? 在同样条件下,怎样写程序占用内存最少,速度最快? 关于绘图仪 哪位大侠,给一段VC画圆的代码吧,感谢指教!
然后可以把你打开的网站抓下来存为bmp或者jpg文件。
原理如下:
1、得到整个屏幕的DC:HDC hDisplay = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
2、得到屏幕的宽度和高度:int nScreenWidth = GetDeviceCaps(hDisplay, HORZRES);
int nScreenHeight = GetDeviceCaps(hDisplay, VERTRES);
3、创建一个内存中的DC:
HDC hMemDc = CreateCompatibleDC(hDisplay);
4、创建一个内存中的位图:
HBITMAP hBmp = CreateCompatibleBitmap(hDisplay, nScreenWidth, nScreenHeight);
5、把位图和DC绑定在一起:
HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDc, hBmp);
6、把整个屏幕的内容复制到内存DC中:
BitBlt(hMemDc, 0, 0, nScreenWidth, nScreenHeight, hDisplay, 0, 0, SRCCOPY);
7、再次绑定(例子上这么做,不知道为什么)
hBmp = (HBITMAP)SelectObject(hMemDc, hOldBmp);
8、分配内存(BMP图片文件大小),初始化位图结构体(省略)
9、利用GetDIBits函数得到位图的象素信息:
GetDIBits(hDisplay, hBmp, 0, nScreenHeight,
pBits,
(BITMAPINFO *)pInfoHeader,
DIB_RGB_COLORS);
10、创建文件,保存位图这里是源代码:
//复制屏幕
void CopyScreen(const char *pFilePath)
{
//首先得到整个屏幕的句柄
HDC hDisplay = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
_ASSERT(NULL!=hDisplay);
//得到屏幕的大小
int nScreenWidth = GetDeviceCaps(hDisplay, HORZRES);
int nScreenHeight = GetDeviceCaps(hDisplay, VERTRES);
//创建内存DC
HDC hMemDc = CreateCompatibleDC(hDisplay);
_ASSERT(NULL != hMemDc);
//创建位图
HBITMAP hBmp = CreateCompatibleBitmap(hDisplay, nScreenWidth, nScreenHeight);
_ASSERT(NULL != hBmp);
//选择位图
HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDc, hBmp);
_ASSERT(NULL != (DWORD)hOldBmp || GDI_ERROR != (DWORD)hOldBmp);
//复制图形
BOOL blnReturnValue = BitBlt(hMemDc, 0, 0, nScreenWidth, nScreenHeight, hDisplay, 0, 0, SRCCOPY);
_ASSERT(0 != blnReturnValue);
//再次选择
hBmp = (HBITMAP)SelectObject(hMemDc, hOldBmp);
_ASSERT(NULL != (DWORD)hBmp || GDI_ERROR != (DWORD)hBmp);
DeleteDC(hMemDc);
hMemDc = NULL;
int nBits = GetDeviceCaps(hDisplay, BITSPIXEL); //每个象素的位数
DWORD dwLineBits = 0; //每行字节数
switch (nBits)
{
case 16:
dwLineBits = nScreenWidth*2;
break;
case 24:
dwLineBits = (nScreenWidth+1)*3-((nScreenWidth+1)*3)%4;
break;
case 32:
dwLineBits = nScreenWidth*4;
break;
default:
//其他情况(这里产生资源泄漏,只是例子,所以没管)
MessageBox(NULL, _T("不支持该格式!"), _T("不支持!"), MB_OK);
break;
}
//下面分配内存
DWORD dwBitsCount = dwLineBits * nScreenHeight;
DWORD dwFileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBitsCount;
BYTE * pMem = (BYTE *)GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT, dwFileSize);
if (NULL == pMem)
{
MessageBox(hWnd, _T("分配内存失败!"), _T("错误!"), MB_OK);
return;
}
BITMAPFILEHEADER* pBMPHeader = (BITMAPFILEHEADER*)pMem;
BITMAPINFOHEADER* pInfoHeader = (BITMAPINFOHEADER*)((BYTE *)pBMPHeader + sizeof(BITMAPFILEHEADER));
BYTE* pBits = (BYTE*)pInfoHeader + sizeof(BITMAPINFOHEADER);
//下面初始化
pBMPHeader->bfType = ('M'<<8) | 'B';
pBMPHeader->bfSize = dwFileSize;
pBMPHeader->bfReserved1 = 0;
pBMPHeader->bfReserved2 = 0;
pBMPHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
pInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
pInfoHeader->biWidth = nScreenWidth;
pInfoHeader->biHeight = nScreenHeight;
pInfoHeader->biPlanes = GetDeviceCaps(hDisplay, PLANES); //调色板数
pInfoHeader->biBitCount = nBits;
pInfoHeader->biCompression = BI_RGB;
pInfoHeader->biSizeImage = dwBitsCount;
pInfoHeader->biXPelsPerMeter = GetDeviceCaps(hDisplay, LOGPIXELSX);
pInfoHeader->biYPelsPerMeter = GetDeviceCaps(hDisplay, LOGPIXELSY);
pInfoHeader->biClrUsed = 0;
pInfoHeader->biClrImportant = 0;
//下面得到数据
int nLines = GetDIBits(hDisplay, hBmp, 0, nScreenHeight,
pBits,
(BITMAPINFO *)pInfoHeader,
DIB_RGB_COLORS);
if (0 == nLines)
{
DWORD errno = GetLastError();
MessageBox(hWnd, _T("复制位图数据失败"), _T("错误!"), MB_OK);
return;
}
DeleteDC(hDisplay);
hDisplay = NULL;
DeleteObject(hBmp);
hBmp = NULL;
DeleteObject(hOldBmp);
hOldBmp = NULL;
//下面保存文件
HANDLE hFile = CreateFile(pFilePath, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (NULL == hFile || INVALID_HANDLE_VALUE == hFile)
{
MessageBox(hWnd, _T("文件已经存在!"), _T("错误!"), MB_OK);
return;
}
//写入
DWORD dwWriteCount = 0;
if (!WriteFile(hFile, (void *)pBMPHeader, dwFileSize, &dwWriteCount, NULL))
{
MessageBox(NULL, _T("写入文件失败!"), _T("错误"), MB_OK | MB_ICONEXCLAMATION);
CloseHandle(hFile);
return;
}
//关闭文件
CloseHandle(hFile);
GlobalFree((void *)pBMPHeader);
}
、、也可以保存为jpg格式的,不过比较蛮烦,不讲了。
http://www.codeproject.com/internet/htmlimagecapture.asp
hWndIE = ::FindWindow("Internet Explorer_Server",NULL);CDC dcIE;
HDC hdcIE = ::GetDC(hWndIE);
dcIE.Attach(hdcIE);HBITMAP hBitmapIE = dcIE.GetCurrentBitmap();然后把hBitmapIE 保存成bmp文件,具体怎么保存看我的blog
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure GetImageEncoders(num, size, pImageCodecInfo); for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
} free(pImageCodecInfo);
return -1; // Failure
}void BMP2JPG(CString strBMPFile,CString strJPGFile)
{
CLSID encoderClsid;
WCHAR strGuid[39];
if(GetEncoderClsid(L"image/jpeg", &encoderClsid) >= 0)
StringFromGUID2(encoderClsid, strGuid, 39);
Image image(strBMPFile.AllocSysString());
image.Save(strJPGFile.AllocSysString(),&encoderClsid,NULL);}
[email protected]