不错呦!smile@林凯西,确保“准备文件”中的几个文件都有安装,S...您好,看了您这篇帖子觉得很有帮助。但是有个问题想请...我的修改过了怎么还被恶意注册呢 @jjjjiiii 用PJ快9年了,主要是A...PJ3啊,貌似很少有人用PJ了,现在不是WP就是z...@332347365,我当时接入时错误码没有-10...楼主,ChkValue值应为-103是什么意思呢?...大哥 你最近能看到我发的信息,请跟我联系,我有个制...
C#网页截图类WebCapture(增强版)
编辑:dnawo 日期:2009-04-05
上次使用WebBrowser控件的DrawToBitmap方法来保存页面截图,效果不是很好,百度后看了一篇非常棒的文章,效果非常好,下边示例下怎么实现。先定义三个重要的类NativeMethods、UnsafeNativeMethods和Snapshot:
NativeMethods.cs:
UnsafeNativeMethods.cs:
Snapshot.cs:
使用语法如下:
好了,修改下上次的WebCapture类:
WebCapture.cs:
使用示例:
参考文章:
[1].http://www.cnblogs.com/Chinasf/archive/2006/12/25/603294.html
NativeMethods.cs:
复制内容到剪贴板
程序代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
namespace WindowsApplication1
{
/// <summary>
/// 从 .Net 2.0 的 System.Windows.Forms.Dll 库提取
/// 版权所有:微软公司
/// </summary>
internal static class NativeMethods
{
[StructLayout(LayoutKind.Sequential)]
public sealed class tagDVTARGETDEVICE
{
[MarshalAs(UnmanagedType.U4)]
public int tdSize;
[MarshalAs(UnmanagedType.U2)]
public short tdDriverNameOffset;
[MarshalAs(UnmanagedType.U2)]
public short tdDeviceNameOffset;
[MarshalAs(UnmanagedType.U2)]
public short tdPortNameOffset;
[MarshalAs(UnmanagedType.U2)]
public short tdExtDevmodeOffset;
}
[StructLayout(LayoutKind.Sequential)]
public class COMRECT
{
public int left;
public int top;
public int right;
public int bottom;
public COMRECT()
{
}
public COMRECT(Rectangle r)
{
this.left = r.X;
this.top = r.Y;
this.right = r.Right;
this.bottom = r.Bottom;
}
public COMRECT(int left, int top, int right, int bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public static NativeMethods.COMRECT FromXYWH(int x, int y, int width, int height)
{
return new NativeMethods.COMRECT(x, y, x + width, y + height);
}
public override string ToString()
{
return string.Concat(new object[] { "Left = ", this.left, " Top ", this.top, " Right = ", this.right, " Bottom = ", this.bottom });
}
}
[StructLayout(LayoutKind.Sequential)]
public sealed class tagLOGPALETTE
{
[MarshalAs(UnmanagedType.U2)]
public short palVersion;
[MarshalAs(UnmanagedType.U2)]
public short palNumEntries;
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
namespace WindowsApplication1
{
/// <summary>
/// 从 .Net 2.0 的 System.Windows.Forms.Dll 库提取
/// 版权所有:微软公司
/// </summary>
internal static class NativeMethods
{
[StructLayout(LayoutKind.Sequential)]
public sealed class tagDVTARGETDEVICE
{
[MarshalAs(UnmanagedType.U4)]
public int tdSize;
[MarshalAs(UnmanagedType.U2)]
public short tdDriverNameOffset;
[MarshalAs(UnmanagedType.U2)]
public short tdDeviceNameOffset;
[MarshalAs(UnmanagedType.U2)]
public short tdPortNameOffset;
[MarshalAs(UnmanagedType.U2)]
public short tdExtDevmodeOffset;
}
[StructLayout(LayoutKind.Sequential)]
public class COMRECT
{
public int left;
public int top;
public int right;
public int bottom;
public COMRECT()
{
}
public COMRECT(Rectangle r)
{
this.left = r.X;
this.top = r.Y;
this.right = r.Right;
this.bottom = r.Bottom;
}
public COMRECT(int left, int top, int right, int bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public static NativeMethods.COMRECT FromXYWH(int x, int y, int width, int height)
{
return new NativeMethods.COMRECT(x, y, x + width, y + height);
}
public override string ToString()
{
return string.Concat(new object[] { "Left = ", this.left, " Top ", this.top, " Right = ", this.right, " Bottom = ", this.bottom });
}
}
[StructLayout(LayoutKind.Sequential)]
public sealed class tagLOGPALETTE
{
[MarshalAs(UnmanagedType.U2)]
public short palVersion;
[MarshalAs(UnmanagedType.U2)]
public short palNumEntries;
}
}
}
UnsafeNativeMethods.cs:
复制内容到剪贴板
程序代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Security;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace WindowsApplication1
{
/// <summary>
/// 从 .Net 2.0 的 System.Windows.Forms.Dll 库提取
/// 版权所有:微软公司
/// </summary>
[SuppressUnmanagedCodeSecurity]
internal static class UnsafeNativeMethods
{
public static Guid IID_IViewObject = new Guid("{0000010d-0000-0000-C000-000000000046}");
[ComImport, Guid("0000010d-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IViewObject
{
[PreserveSig]
int Draw([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [In] NativeMethods.tagDVTARGETDEVICE ptd, IntPtr hdcTargetDev, IntPtr hdcDraw, [In] NativeMethods.COMRECT lprcBounds, [In] NativeMethods.COMRECT lprcWBounds, IntPtr pfnContinue, [In] int dwContinue);
[PreserveSig]
int GetColorSet([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [In] NativeMethods.tagDVTARGETDEVICE ptd, IntPtr hicTargetDev, [Out] NativeMethods.tagLOGPALETTE ppColorSet);
[PreserveSig]
int Freeze([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [Out] IntPtr pdwFreeze);
[PreserveSig]
int Unfreeze([In, MarshalAs(UnmanagedType.U4)] int dwFreeze);
void SetAdvise([In, MarshalAs(UnmanagedType.U4)] int aspects, [In, MarshalAs(UnmanagedType.U4)] int advf, [In, MarshalAs(UnmanagedType.Interface)] IAdviseSink pAdvSink);
void GetAdvise([In, Out, MarshalAs(UnmanagedType.LPArray)] int[] paspects, [In, Out, MarshalAs(UnmanagedType.LPArray)] int[] advf, [In, Out, MarshalAs(UnmanagedType.LPArray)] IAdviseSink[] pAdvSink);
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Security;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace WindowsApplication1
{
/// <summary>
/// 从 .Net 2.0 的 System.Windows.Forms.Dll 库提取
/// 版权所有:微软公司
/// </summary>
[SuppressUnmanagedCodeSecurity]
internal static class UnsafeNativeMethods
{
public static Guid IID_IViewObject = new Guid("{0000010d-0000-0000-C000-000000000046}");
[ComImport, Guid("0000010d-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IViewObject
{
[PreserveSig]
int Draw([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [In] NativeMethods.tagDVTARGETDEVICE ptd, IntPtr hdcTargetDev, IntPtr hdcDraw, [In] NativeMethods.COMRECT lprcBounds, [In] NativeMethods.COMRECT lprcWBounds, IntPtr pfnContinue, [In] int dwContinue);
[PreserveSig]
int GetColorSet([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [In] NativeMethods.tagDVTARGETDEVICE ptd, IntPtr hicTargetDev, [Out] NativeMethods.tagLOGPALETTE ppColorSet);
[PreserveSig]
int Freeze([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [Out] IntPtr pdwFreeze);
[PreserveSig]
int Unfreeze([In, MarshalAs(UnmanagedType.U4)] int dwFreeze);
void SetAdvise([In, MarshalAs(UnmanagedType.U4)] int aspects, [In, MarshalAs(UnmanagedType.U4)] int advf, [In, MarshalAs(UnmanagedType.Interface)] IAdviseSink pAdvSink);
void GetAdvise([In, Out, MarshalAs(UnmanagedType.LPArray)] int[] paspects, [In, Out, MarshalAs(UnmanagedType.LPArray)] int[] advf, [In, Out, MarshalAs(UnmanagedType.LPArray)] IAdviseSink[] pAdvSink);
}
}
}
Snapshot.cs:
复制内容到剪贴板
程序代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsApplication1
{
/// <summary>
/// ActiveX 组件快照类
/// AcitveX 必须实现 IViewObject 接口
///
/// 作者:随飞
/// http://chinasf.cnblogs.com
/// chinasf@hotmail.com
/// </summary>
public class Snapshot
{
/// <summary>
/// 取快照
/// </summary>
/// <param name="pUnknown">Com 对象</param>
/// <param name="bmpRect">图象大小</param>
/// <returns></returns>
public Bitmap TakeSnapshot(object pUnknown, Rectangle bmpRect)
{
if (pUnknown == null)
return null;
//必须为com对象
if (!Marshal.IsComObject(pUnknown))
return null;
//IViewObject 接口
UnsafeNativeMethods.IViewObject ViewObject = null;
IntPtr pViewObject = IntPtr.Zero;
//内存图
Bitmap pPicture = new Bitmap(bmpRect.Width, bmpRect.Height);
Graphics hDrawDC = Graphics.FromImage(pPicture);
//获取接口
object hret = Marshal.QueryInterface(Marshal.GetIUnknownForObject(pUnknown),
ref UnsafeNativeMethods.IID_IViewObject, out pViewObject);
try
{
ViewObject = Marshal.GetTypedObjectForIUnknown(pViewObject, typeof(UnsafeNativeMethods.IViewObject)) as UnsafeNativeMethods.IViewObject;
//调用Draw方法
ViewObject.Draw((int)DVASPECT.DVASPECT_CONTENT,
-1,
IntPtr.Zero,
null,
IntPtr.Zero,
hDrawDC.GetHdc(),
new NativeMethods.COMRECT(bmpRect),
null,
IntPtr.Zero,
0);
Marshal.Release(pViewObject);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw ex;
}
//释放
hDrawDC.Dispose();
return pPicture;
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsApplication1
{
/// <summary>
/// ActiveX 组件快照类
/// AcitveX 必须实现 IViewObject 接口
///
/// 作者:随飞
/// http://chinasf.cnblogs.com
/// chinasf@hotmail.com
/// </summary>
public class Snapshot
{
/// <summary>
/// 取快照
/// </summary>
/// <param name="pUnknown">Com 对象</param>
/// <param name="bmpRect">图象大小</param>
/// <returns></returns>
public Bitmap TakeSnapshot(object pUnknown, Rectangle bmpRect)
{
if (pUnknown == null)
return null;
//必须为com对象
if (!Marshal.IsComObject(pUnknown))
return null;
//IViewObject 接口
UnsafeNativeMethods.IViewObject ViewObject = null;
IntPtr pViewObject = IntPtr.Zero;
//内存图
Bitmap pPicture = new Bitmap(bmpRect.Width, bmpRect.Height);
Graphics hDrawDC = Graphics.FromImage(pPicture);
//获取接口
object hret = Marshal.QueryInterface(Marshal.GetIUnknownForObject(pUnknown),
ref UnsafeNativeMethods.IID_IViewObject, out pViewObject);
try
{
ViewObject = Marshal.GetTypedObjectForIUnknown(pViewObject, typeof(UnsafeNativeMethods.IViewObject)) as UnsafeNativeMethods.IViewObject;
//调用Draw方法
ViewObject.Draw((int)DVASPECT.DVASPECT_CONTENT,
-1,
IntPtr.Zero,
null,
IntPtr.Zero,
hDrawDC.GetHdc(),
new NativeMethods.COMRECT(bmpRect),
null,
IntPtr.Zero,
0);
Marshal.Release(pViewObject);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw ex;
}
//释放
hDrawDC.Dispose();
return pPicture;
}
}
}
使用语法如下:
复制内容到剪贴板
程序代码

Snapshot snap = new Snapshot();
using (Bitmap bitmap = snap.TakeSnapshot(webBrowser.ActiveXInstance, new Rectangle(0, 0, picWidth, picHeight)))
{
bitmap.Save(savepath, picType);
}
using (Bitmap bitmap = snap.TakeSnapshot(webBrowser.ActiveXInstance, new Rectangle(0, 0, picWidth, picHeight)))
{
bitmap.Save(savepath, picType);
}
好了,修改下上次的WebCapture类:
WebCapture.cs:
复制内容到剪贴板
程序代码

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.IO;
namespace WindowsApplication1
{
public class WebCapture
{
#region 字段、属性
private int width = 0;
private int height = 0;
private string url;
private WebBrowser browser = new WebBrowser();
/// <summary>
/// 属性:图片宽
/// </summary>
public int Width { get { return width; } }
/// <summary>
/// 属性:图片高
/// </summary>
public int Height { get { return height; } }
/// <summary>
/// 属性:Url
/// </summary>
public string Url { get { return url; } }
#endregion
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
public WebCapture()
{
this.url = "http://www.mzwu.com/";
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="url">Url</param>
public WebCapture(string url)
{
this.url = url;
}
#endregion
/// <summary>
/// 保存图片
/// </summary>
/// <param name="destpath">保存路径</param>
/// <returns></returns>
public void Save(string destpath)
{
Save(this.url, destpath, this.width, this.height);
}
/// <summary>
/// 保存图片
/// </summary>
/// <param name="url">Url</param>
/// <param name="destpath">保存路径</param>
/// <returns></returns>
public void Save(string url, string destpath)
{
Save(url, destpath, this.width, this.height);
}
/// <summary>
/// 保存图片
/// </summary>
/// <param name="url">Url</param>
/// <param name="destpath">保存路径</param>
/// <param name="width">图片宽</param>
/// <param name="height">图片高</param>
/// <returns></returns>
/// <remarks>width,height为0时获取完整大小</remarks>
public void Save(string url, string destpath, int width, int height)
{
ImageFormat picType;
//图片格式
switch (Path.GetExtension(destpath).ToLower())
{
case ".gif":
picType = System.Drawing.Imaging.ImageFormat.Gif;
break;
case ".jpg":
case ".jpeg":
picType = System.Drawing.Imaging.ImageFormat.Jpeg;
break;
case ".png":
picType = System.Drawing.Imaging.ImageFormat.Png;
break;
case ".bmp":
picType = System.Drawing.Imaging.ImageFormat.Bmp;
break;
default:
picType = System.Drawing.Imaging.ImageFormat.Jpeg;
break;
}
//抓取图片
InitComobject(url);//初始化窗体
int scrollWidth = this.browser.Document.Body.ScrollRectangle.Width;
int scrollHeight = this.browser.Document.Body.ScrollRectangle.Height;
this.browser.Width = scrollWidth;
this.browser.Height = scrollHeight;
if (width == 0) width = scrollWidth;
if (height == 0) height = scrollHeight;
//核心语句
Snapshot snap = new Snapshot();
using (Bitmap bitmap = snap.TakeSnapshot(this.browser.ActiveXInstance, new Rectangle(0, 0, width, height)))
{
bitmap.Save(destpath, picType);
}
browser.Dispose();
}
/// <summary>
/// 初始化
/// </summary>
/// <param name="url"></param>
protected void InitComobject(string url)
{
this.browser.ScriptErrorsSuppressed = false;
this.browser.ScrollBarsEnabled = false;
this.browser.Navigate(url);
//因为没有窗体,所以必须如此
while (this.browser.ReadyState != WebBrowserReadyState.Complete)
System.Windows.Forms.Application.DoEvents();
this.browser.Stop();
if (this.browser.ActiveXInstance == null)
throw new Exception("实例不能为空");
}
}
}
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.IO;
namespace WindowsApplication1
{
public class WebCapture
{
#region 字段、属性
private int width = 0;
private int height = 0;
private string url;
private WebBrowser browser = new WebBrowser();
/// <summary>
/// 属性:图片宽
/// </summary>
public int Width { get { return width; } }
/// <summary>
/// 属性:图片高
/// </summary>
public int Height { get { return height; } }
/// <summary>
/// 属性:Url
/// </summary>
public string Url { get { return url; } }
#endregion
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
public WebCapture()
{
this.url = "http://www.mzwu.com/";
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="url">Url</param>
public WebCapture(string url)
{
this.url = url;
}
#endregion
/// <summary>
/// 保存图片
/// </summary>
/// <param name="destpath">保存路径</param>
/// <returns></returns>
public void Save(string destpath)
{
Save(this.url, destpath, this.width, this.height);
}
/// <summary>
/// 保存图片
/// </summary>
/// <param name="url">Url</param>
/// <param name="destpath">保存路径</param>
/// <returns></returns>
public void Save(string url, string destpath)
{
Save(url, destpath, this.width, this.height);
}
/// <summary>
/// 保存图片
/// </summary>
/// <param name="url">Url</param>
/// <param name="destpath">保存路径</param>
/// <param name="width">图片宽</param>
/// <param name="height">图片高</param>
/// <returns></returns>
/// <remarks>width,height为0时获取完整大小</remarks>
public void Save(string url, string destpath, int width, int height)
{
ImageFormat picType;
//图片格式
switch (Path.GetExtension(destpath).ToLower())
{
case ".gif":
picType = System.Drawing.Imaging.ImageFormat.Gif;
break;
case ".jpg":
case ".jpeg":
picType = System.Drawing.Imaging.ImageFormat.Jpeg;
break;
case ".png":
picType = System.Drawing.Imaging.ImageFormat.Png;
break;
case ".bmp":
picType = System.Drawing.Imaging.ImageFormat.Bmp;
break;
default:
picType = System.Drawing.Imaging.ImageFormat.Jpeg;
break;
}
//抓取图片
InitComobject(url);//初始化窗体
int scrollWidth = this.browser.Document.Body.ScrollRectangle.Width;
int scrollHeight = this.browser.Document.Body.ScrollRectangle.Height;
this.browser.Width = scrollWidth;
this.browser.Height = scrollHeight;
if (width == 0) width = scrollWidth;
if (height == 0) height = scrollHeight;
//核心语句
Snapshot snap = new Snapshot();
using (Bitmap bitmap = snap.TakeSnapshot(this.browser.ActiveXInstance, new Rectangle(0, 0, width, height)))
{
bitmap.Save(destpath, picType);
}
browser.Dispose();
}
/// <summary>
/// 初始化
/// </summary>
/// <param name="url"></param>
protected void InitComobject(string url)
{
this.browser.ScriptErrorsSuppressed = false;
this.browser.ScrollBarsEnabled = false;
this.browser.Navigate(url);
//因为没有窗体,所以必须如此
while (this.browser.ReadyState != WebBrowserReadyState.Complete)
System.Windows.Forms.Application.DoEvents();
this.browser.Stop();
if (this.browser.ActiveXInstance == null)
throw new Exception("实例不能为空");
}
}
}
使用示例:
复制内容到剪贴板
程序代码

new WebCapture().Save("http://www.163.com/", @"C:\163.jpg");
参考文章:
[1].http://www.cnblogs.com/Chinasf/archive/2006/12/25/603294.html






评论: 0 | 引用: 0 | 查看次数: 6839
发表评论
请登录后再发表评论!