捕获网页为图像
参考原文(英文) http://www.codeproject.com/cs/media/IECapture.asp 环境:Visual Studio.NET 2003 语言:C# 系统需求:Windows + iexplore 附件:捕获网页为图像程序 捕获效果图:
该程序的目标很明确,就是捕获IE浏览器打开的网页存为图像,附加的需求,我们能自定义图像的保存质量(控制图像的大小)。当然我们还要考虑当有多个浏览器窗口打开的时候,我们是捕获所有窗口的图像。 废话不多说,我们开始说说这个程序如何实现。
第一步: 该程序需要SHDocVw.dll 和 MSHTML.dll的支持,所以在我们的工程中需要添加两个com组件,在添加引用的对话框中选择com的标签页,然后找到Microsoft Internet Controls". 和Microsoft HTML Object Library,添加进来。
第二步:添加必要的名称空间
using
System.Text;
using
System.Runtime.InteropServices;
using
System.Diagnostics;
using
System.IO;
using
System.Drawing.Imaging;
using
SHDocVw;
using
mshtml;
第三步:调用user32.dll的函数
[DllImport(
"
user32.dll
"
, CharSet
=
CharSet.Auto)]
public
static
extern
IntPtr FindWindowEx(IntPtr parent
/**/
/* HWND */
, IntPtr next
/**/
/* HWND */
,
string
sClassName, IntPtr sWindowTitle); [DllImport(
"
user32.dll
"
, ExactSpelling
=
true
, CharSet
=
CharSet.Auto)]
public
static
extern
IntPtr GetWindow(IntPtr hWnd,
int
uCmd); [DllImport(
"
user32.Dll
"
)]
public
static
extern
void
GetClassName(
int
h, StringBuilder s,
int
nMaxCount); [DllImport(
"
user32.dll
"
)]
private
static
extern
bool
PrintWindow(IntPtr hwnd, IntPtr hdcBlt,
uint
nFlags);
public
const
int
GW_CHILD
=
5
;
public
const
int
GW_HWNDNEXT
=
2
;
第四步:找到一个打开的浏览器进程,并分配一个Browser Document给它。
SHDocVw.WebBrowser m_browser
=
null
; SHDocVw.ShellWindows shellWindows
=
new
SHDocVw.ShellWindowsClass();
//
Find first availble browser window.
//
Application can easily be modified to loop through and
//
capture all open windows.
string
filename;
foreach
(SHDocVw.WebBrowser ie
in
shellWindows)
{ filename = Path.GetFileNameWithoutExtension(ie.FullName).ToLower(); if (filename.Equals( " iexplore " )) { m_browser = ie; break ; } }
if
(m_browser
==
null
)
{ MessageBox.Show( " No Browser Open " ); return ; }
//
Assign Browser Document
mshtml.IHTMLDocument2 myDoc
=
(mshtml.IHTMLDocument2)m_browser.Document;
第五步:获取屏幕和网页的高度和宽度
//
Set scrolling on.
myDoc.body.setAttribute(
"
scroll
"
,
"
yes
"
,
0
);
//
Get Browser Window Height
int
heightsize
=
(
int
)myDoc.body.getAttribute(
"
scrollHeight
"
,
0
);
int
widthsize
=
(
int
)myDoc.body.getAttribute(
"
scrollWidth
"
,
0
);
//
Get Screen Height
int
screenHeight
=
(
int
)myDoc.body.getAttribute(
"
clientHeight
"
,
0
);
int
screenWidth
=
(
int
)myDoc.body.getAttribute(
"
clientWidth
"
,
0
);
第六步:捕获算法 这里要说明的是,其实没有什么组件可以让我们直接把网页完全捕获过来,我们还是从基本的一页一页捕捉,然后组合整个图像的方法来完成的。 其基本思想是这样的:首先捕获该网页的第一个片段,然后滚动条滑道下一页,继续捕获下一个片段,然后这个片段组合到一个目标位图中,就像缝合起来。这个过程会循环进行,直到最后一个片段捕获完毕,缝合到目标位图中去。 当然我们还可能遇到这样一种情况,就是网页比屏幕要宽,这是我们的程序仍然是先捕获第一个片段,然后浏览器滚动条水平移动,捕获剩余的部分,然后缝接起来,然后再进行上述的步骤。
http://blog.csdn.net/metababy
http://hexun.com/metababy
//
Get bitmap to hold screen fragment.
Bitmap bm
=
new
Bitmap(screenWidth, screenHeight, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
//
Create a target bitmap to draw into.
Bitmap bm2
=
new
Bitmap(widthsize
+
URLExtraLeft, heightsize
+
URLExtraHeight
-
trimHeight, System.Drawing.Imaging.PixelFormat.Format16bppRgb555); Graphics g2
=
Graphics.FromImage(bm2); Graphics g
=
null
; IntPtr hdc; Image screenfrag
=
null
;
int
brwTop
=
0
;
int
brwLeft
=
0
;
int
myPage
=
0
; IntPtr myIntptr
=
(IntPtr)m_browser.HWND;
//
Get inner browser window.
int
hwndInt
=
myIntptr.ToInt32(); IntPtr hwnd
=
myIntptr; hwnd
=
GetWindow(hwnd, GW_CHILD); StringBuilder sbc
=
new
StringBuilder(
256
);
//
Get Browser "Document" Handle
while
(hwndInt
!=
0
)
{ hwndInt = hwnd.ToInt32(); GetClassName(hwndInt, sbc, 256 ); if (sbc.ToString().IndexOf( " Shell DocObject View " , 0 ) > - 1 ) { hwnd = FindWindowEx(hwnd, IntPtr.Zero, " Internet Explorer_Server " , IntPtr.Zero); break ; } hwnd = GetWindow(hwnd, GW_HWNDNEXT); }
//
Get Screen Height (for bottom up screen drawing)
while
((myPage
*
screenHeight)
<
heightsize)
{ myDoc.body.setAttribute( " scrollTop " , (screenHeight - 5 ) * myPage, 0 ); ++ myPage; }
//
Rollback the page count by one
--
myPage;
int
myPageWidth
=
0
;
while
((myPageWidth
*
screenWidth)
<
widthsize)
{ myDoc.body.setAttribute( " scrollLeft " , (screenWidth - 5 ) * myPageWidth, 0 ); brwLeft = ( int )myDoc.body.getAttribute( " scrollLeft " , 0 ); for ( int i = myPage; i >= 0 ; -- i) { // Shoot visible window g = Graphics.FromImage(bm); hdc = g.GetHdc(); myDoc.body.setAttribute( " scrollTop " , (screenHeight - 5 ) * i, 0 ); brwTop = ( int )myDoc.body.getAttribute( " scrollTop " , 0 ); PrintWindow(hwnd, hdc, 0 ); g.ReleaseHdc(hdc); g.Flush(); screenfrag = Image.FromHbitmap(bm.GetHbitmap()); g2.DrawImage(screenfrag, brwLeft + URLExtraLeft, brwTop + URLExtraHeight); } ++ myPageWidth; }