[C#] 如何截取完整的网页图片

前言

有时候浏览到非常有用的网页时,我们会选择将它加入到收藏夹中,但是网站一旦过期,以后就看不到这个网页了。当然也可以将网页打印成PDF文档保存。最新的Windows 10中的Edge浏览器支持将网页保存至OneNote中,但在OneNote中其实是保存了一张当前页面的完整图片。这篇博客将介绍如何使用C#将完整的页面保存成图片。

实现方式

使用WinForms中的WebBrowser来保存图片,具体DrawToBitmap方法进行保存。新建一个Console程序(添加System.Windows.Forms),

[STAThread]
static void Main(string[] args)
{
    int width = 800;
    int height = 600;using (WebBrowser browser = new WebBrowser())
    {
        browser.Width = width;
        browser.Height = height;
        browser.ScrollBarsEnabled = false;
        browser.ScriptErrorsSuppressed = true;

        browser.DocumentCompleted += OnDocumentCompleted;

        browser.Navigate("http://www.cnblogs.com");

        Application.Run();
    }
}

private static void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    WebBrowser browser = (WebBrowser)sender;

    using (Graphics graphics = browser.CreateGraphics())
    {
        int dWidth = browser.Document.Body.ScrollRectangle.Width;

        int dHeight = browser.Document.Body.ScrollRectangle.Height;

        browser.Height = dHeight;

        browser.Width = dWidth;

        using (Bitmap bitmap = new Bitmap(dWidth, dHeight, graphics))
        {
            Rectangle bounds = new Rectangle(0, 0, dWidth, dHeight);

            browser.DrawToBitmap(bitmap, bounds);

            bitmap.Save("Screenshot1.png", ImageFormat.Png);
        }
    }
    Application.Exit();
}

注意加粗的代码,当页面加载完成后,需要根据网页的大小来调整WebBrowser的大小,否则保存的页面大小就是初始时给WebBrowser设置的大小。

上述代码中,直接将需要截图的页面写在代码中,如果能够直接读取当前IE/FireFox/Chrome打开的页面,直接截图就完美了。

改进

增加获取当前IE/FireFox/Chrome打开的页面,

代码参考自:https://stackoverflow.com/questions/5317642/retrieve-current-url-from-c-sharp-windows-forms-application

添加UIAutomationClient和UIAutomationTypes引用,

public static string GetChromeUrl(Process process)
{
    if (process == null)
        throw new ArgumentNullException("process");

    if (process.MainWindowHandle == IntPtr.Zero)
        return null;

    AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
    if (element == null)
        return null;

    AutomationElement edit = element.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
    return ((ValuePattern)edit.GetCurrentPattern(ValuePattern.Pattern)).Current.Value as string;
}

public static string GetInternetExplorerUrl(Process process)
{
    if (process == null)
        throw new ArgumentNullException("process");

    if (process.MainWindowHandle == IntPtr.Zero)
        return null;

    AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
    if (element == null)
        return null;

    AutomationElement rebar = element.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "ReBarWindow32"));
    if (rebar == null)
        return null;

    AutomationElement edit = rebar.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));

    return ((ValuePattern)edit.GetCurrentPattern(ValuePattern.Pattern)).Current.Value as string;
}

public static string GetFirefoxUrl(Process process)
{
    if (process == null)
        throw new ArgumentNullException("process");

    if (process.MainWindowHandle == IntPtr.Zero)
        return null;

    AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
    if (element == null)
        return null;

    AutomationElement doc = element.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document));
    if (doc == null)
        return null;

    return ((ValuePattern)doc.GetCurrentPattern(ValuePattern.Pattern)).Current.Value as string;
}

根据浏览器进程查找当前Active的页面,

string url = string.Empty;

foreach (Process process in Process.GetProcessesByName("firefox"))
{
    url = GetFirefoxUrl(process);
    if (url != null)
    {
        // Find the target Url
        break;
    }
}

foreach (Process process in Process.GetProcessesByName("iexplore"))
{
    url = GetInternetExplorerUrl(process);
    if (url != null)
    {
        // Find the target Url
        break;
    }
}

foreach (Process process in Process.GetProcessesByName("chrome"))
{
    url = GetChromeUrl(process);
    if (url != null)
    {
        // Find the target Url
        break;
    }
}

此时就不需要手动的修改需要截图的Url地址了,直接一键截图~

感谢您的阅读~ 代码点击这里下载。

posted @ 2017-09-07 18:32  Yang-Fei  阅读(2169)  评论(0编辑  收藏  举报